在本教程中,我将向您展示如何使用React, Gatsby JSCosmic JS创建一个简单但快速的博客。 让我们开始吧。

TL; DR

先决条件

在开始之前,您将需要安装Node JS,npm和Gastby CLI。 确保已经安装了它们。

什么是盖茨比?

Gatsby是React的快速网站框架。 它允许开发人员在几分钟内构建基于React的网站。 无论您是要开发博客还是商业网站,盖茨比都是一个不错的选择。

因为它基于React,所以永远不会重新加载网站页面,而且它还会生成静态页面,从而使生成的网站超快。

博客开发

我们必须设置环境才能开始在博客上工作。

安装盖茨比

首先,安装Gatsby CLI:

npm install -- global gatsby-cli

搭建Gatsby模板

gatsby new gatsby-blog-cosmicjs

输入项目的文件夹:

cd gatsby-blog-cosmicjs

启动服务器:

gatsby develop

此时,您应该已经可以访问位于以下地址的Gatsby JS博客网站: http:// localhost:8000

安装Cosmic JS源插件

在静态博客中,您的数据可以从不同的来源使用:Markdown文件,HTML文件,外部API(WordPress,Cosmic JS等)。

因此,盖茨比实现了独立的层:数据层。 由GraphQL提供支持。 非常令人兴奋的东西!

要将此数据层与不同的数据提供程序连接,您需要集成源插件。 幸运的是,有许多源插件可以满足大多数需求。

在我们的例子中,我们使用Cosmic JS 。 显然,我们需要为Cosmic JS集成Source Plugin。 好消息:Cosmic JS已实现了其源代码插件

让我们安装:

npm install --save gatsby-source-cosmicjs

我们还需要安装其他一些插件。 让我们也这样做

npm install --save gatsby-plugin-offline gatsby-source-filesystem

这些插件需要一些配置。 因此,将gatsby-config.js的内容替换为:

路径: gatsby-config.js

module .exports = {
  plugins : [
    `gatsby-plugin-offline` ,
    `gatsby-plugin-react-helmet` ,
    {
      resolve : `gatsby-source-filesystem` ,
      options : {
        path : ` ${__dirname} /src/pages` ,
        name : 'pages' ,
      },
    },
    {
      resolve : 'gatsby-source-cosmicjs' ,
      options : {
        bucketSlug : 'gatsby-blog-cosmic-js' , // Bucket Slug
        objectTypes: [ 'posts' , 'settings' ], // List of the Object Types you want to be able to request from Gatsby.
        apiAccess: {
          read_key : '' ,
        }
      }
    },
  ],
}

然后,重新启动服务器,让Gatsby考虑这些更新。

帖子列表和设置

首先,我们要在首页上显示帖子列表。 这样做,将以下内容添加到现有的主页文件中:

路径: src/pages/index.js

import React from 'react'
import Link from 'gatsby-link'
import get from 'lodash/get'
import Helmet from 'react-helmet'

import Bio from '../components/Bio'
import { rhythm } from '../utils/typography'

class BlogIndex extends React . Component {
  render() {
    const siteTitle = get( this , 'props.data.cosmicjsSettings.metadata.site_title' )
    const posts = get( this , 'props.data.allCosmicjsPosts.edges' )
    const author = get( this , 'props.data.cosmicjsSettings.metadata' )

    return (
      <div>
        <Helmet title={siteTitle} />
        <Bio settings={author}/>
        {posts.map(({ node }) => {
          const title = get(node, 'title' ) || node.slug
          return (
            <div key={node.slug}>
              <h3
                style={{
                  marginBottom: rhythm( 1 / 4 ),
                }}
              >
                <Link style={{ boxShadow: 'none' }} to ={`posts/${node.slug}`}>
                  {title}
                </Link>
              </h3>
              <small>{node.created}</small>
              <p dangerouslySetInnerHTML={{ __html: node.metadata.description }} />
            </div>
          )
        })}
      </div>
    )
  }
}

export default BlogIndex

export const pageQuery = graphql`
  query IndexQuery {
    allCosmicjsPosts(sort: { fields: [created], order: DESC }, limit: 1000 ) {
      edges {
        node {
          metadata{
            description
          }
          slug
          title
          created(formatString: "DD MMMM, YYYY" )
        }
      }
    }
    cosmicjsSettings(slug: {eq: "general" }){
      metadata{
        site_title
        author_name
        author_bio
        author_avatar {
          imgix_url
        }
      }
    }
  }
`

说明:

index.js的末尾 文件,我们导出了pageQuery。 这些是GraphQl查询,用于获取有关设置和帖子列表的重要信息。

然后,我们通过{ data }破坏对象作为参数IndexPage和环在其allCosmicjsPostscosmicjsSettings对象以显示数据。

单岗位布局

到目前为止,我们已经将Cosmic JS源插件与Gatsby集成在一起,它看起来像一个Blog。 现在,我们将在博客文章的详细信息页面上工作。

让我们创建模板:

路径: src/templates/blog-post.js

import React from 'react'
import Helmet from 'react-helmet'
import Link from 'gatsby-link'
import get from 'lodash/get'

import Bio from '../components/Bio'
import { rhythm, scale } from '../utils/typography'
import { relative } from 'path' ;

class BlogPostTemplate extends React . Component {
  render() {
    const post = this .props.data.cosmicjsPosts
    const siteTitle = get( this .props, 'data.cosmicjsSettings.metadata.site_title' )
    const author = get( this , 'props.data.cosmicjsSettings.metadata' )
    const { previous, next } = this .props.pathContext

    return (
      <div>
        <style>{`
          .post-content {
            text-align: justify;
          }
          .post-hero {
            width: calc( 100 % + ${rhythm( 8 )});
            margin-left: ${rhythm(- 4 )};
            height: ${rhythm( 18 )};
          }
          @media (max-width: ${rhythm( 32 )}) {
            .post-hero {
              width: calc( 100 % + ${rhythm(( 3 / 4 ) * 2 )});
              margin-left: ${rhythm(- 3 / 4 )};
              height: ${rhythm( 13 )};
            }
          }
        `}
        </style>
        <Helmet title={`${post.title} | ${siteTitle}`} />
        <div
          style={{
            marginTop: rhythm( 1.4 ),
          }}
        >
          <Link
            to = "/" >
            ← Back to Posts
          </Link>
        </div>
        <h1
          style={{
            marginTop: rhythm( 1 ),
          }}
        >
          {post.title}
        </h1>
        <p
          style={{
            ...scale(- 1 / 5 ),
            display: 'block' ,
            marginBottom: rhythm( 0.6 ),
            marginTop: rhythm(- 0.6 ),
          }}
        >
          {post.created}
        </p>
        <div
          className= "post-hero"
          style={{
            backgroundColor: "#007ACC" ,
            backgroundImage: `url( "${post.metadata.hero.imgix_url}?w=2000" )`,
            backgroundSize: 'cover' ,
            backgroundPosition: 'center' ,
            marginBottom: rhythm( 0.6 ),
            position: 'relative' ,
          }}
        ></div>
        <div className= "post-content" dangerouslySetInnerHTML={{ __html: post.content }} />
        <hr
          style={{
            marginBottom: rhythm( 1 ),
          }}
        />
        <Bio settings={author} />

        <ul
          style={{
            display: 'flex' ,
            flexWrap: 'wrap' ,
            justifyContent: 'space-between' ,
            listStyle: 'none' ,
            padding: 0 ,
          }}
        >
          {previous && (
            <li>
              <Link to ={previous.slug} rel= "prev" >
                ← {previous.title}
              </Link>
            </li>
          )}

          {next && (
            <li>
              <Link to ={next.slug} rel= "next" >
                {next.title} →
              </Link>
            </li>
          )}
        </ul>
      </div>
    )
  }
}

export default BlogPostTemplate

export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    cosmicjsPosts(slug: { eq: $slug }) {
      id
      content
      title
      created(formatString: "MMMM DD, YYYY" )
      metadata{
        hero{
          imgix_url
        }
      }
    }
    cosmicjsSettings(slug: {eq: "general" }){
      metadata{
        site_title
        author_name
        author_bio
        author_avatar {
          imgix_url
        }
      }
    }
  }
`

看起来不错,但是在这一点上,Gatsby不知道何时应显示此模板。 每个帖子都需要一个特定的URL。 因此,由于createPage函数,我们将向Gatsby告知我们需要的新URL。

路径: gatsby-node.js

const _ = require ( 'lodash' )
const Promise = require ( 'bluebird' )
const path = require ( 'path' )

exports.createPages = ( { graphql, boundActionCreators } ) => {
  const { createPage } = boundActionCreators
  const indexPage = path.resolve( './src/pages/index.js' )
  createPage({
    path : `posts` ,
    component : indexPage,
  })

  return new Promise ( ( resolve, reject ) => {
    const blogPost = path.resolve( './src/templates/blog-post.js' )
    resolve(
      graphql(
        `
          {
            allCosmicjsPosts(sort: { fields: [created], order: DESC }, limit: 1000) {
              edges {
                node {
                  slug,
                  title
                }
              }
            }
          }
        `
      ).then( result => {
        if (result.errors) {
          console .log(result.errors)
          reject(result.errors)
        }

        // Create blog posts pages.
        const posts = result.data.allCosmicjsPosts.edges;

        _.each(posts, (post, index) => {
          const next = index === posts.length - 1 ? null : posts[index + 1 ].node;
          const previous = index === 0 ? null : posts[index - 1 ].node;

          createPage({
            path : `posts/ ${post.node.slug} ` ,
            component : blogPost,
            context : {
              slug : post.node.slug,
              previous,
              next,
            },
          })
        })
      })
    )
  })
}

重新启动Gatsby服务器。

从现在开始,您应该可以通过单击主页上显示的URL来访问详细信息页面。

额外的东西!

除此之外,我们还实现了src/components/Bio.js来显示作者信息,并实现src/layouts/index.js来为博客创建通用布局。

源代码可在GitHub上获得 。 要实时查看它,请克隆存储库并运行( cd gatsby-blog-cosmicjs && npm i && npm run develop )。

最后,重新启动服务器并访问网站。 看起来很棒!

Gatsby生成的静态网站可以轻松地在存储提供商上发布 :Netlify,S3 / Cloudfront,GitHub页面,GitLab页面,Heroku等。

注意:我们的演示已部署在Netlify上。

结论

恭喜! 您已经成功建立了一个超级快速且易于维护的博客! 随意继续该项目,以发现Gatsby和Cosmic JS的优势。

From: https://hackernoon.com/build-a-gatsby-blog-using-the-cosmic-js-source-plugin-d3772776ddb7

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐