LoginSignup
6
6

More than 3 years have passed since last update.

Gatsby.jsでWordPressと連携。記事一覧、詳細を表示するまで

Posted at

WorpdressからGatsby.jsに移行するにあったって、wordpressの記事情報の取得・表示までの連携をメモします。

以下内容はCLIにてgatsby newで作成したプロジェクトを基本にしています。

Wordpressプラグインの追加

wrodpressとの連携はgatsby-source-wordpressにて行うのでパッケージをダウンロードします。

$ yarn add gatsby-source-wordpress

そしてgatsby-config.jsにプラグインの設定を追記します

gatsby-config.js
plugins: [
...
  {
      resolve: 'gatsby-source-wordpress',
      options: {
        baseUrl: 'makoto-acu.com',
        protocol: 'https',
        hostingWPCOM: false, // wordpress.comにホスティングしている場合はtrue
        useACF: false, // Advanced Custom Fieldsを使っている場合はtrue
        includedRoutes: [
          "**/categories",
          "**/posts",
          "**/pages",
          "**/media",
          "**/tags",
          "**/taxonomies",
          "**/users",
        ],
      }
  }
]

一覧ページの表示

一覧ページの表示は、とても簡単です。
pages/index.jsを以下のように修正しました。
ポイントはquery部分で、こちらにてビルド時にGraphQLでWordpressのデータを取得しています。

pages/index.js
const IndexPage = ({data}) => (
    <Layout>
      <SEO title="Home"/>
      <h1>Hello Gatsby</h1>
      <h1>Posts</h1>
      {data.allWordpressPost.edges.map(({node}) => (
          <div key={node.slug}>
            <Link to={node.slug} css={{textDecoration: `none`}}>
              <h3>{node.title}</h3>
            </Link>
            <div dangerouslySetInnerHTML={{__html: node.excerpt}}/>
          </div>
      ))}
    </Layout>
)

export default IndexPage

export const query = graphql`
    query {
        allWordpressPost(sort: { fields: [date] }) {
            edges {
                node {
                    title
                    excerpt
                    slug
                }
            }
        }
    }
`

詳細ページの表示

詳細ページの表示は少し複雑で、APIから取得したデータを元にページを動的に生成します。
まず、gatsby-node.jsに以下を記述します。
こちらのcreatePage()関数にてAPIの取得結果から後述するtemplateを元に動的にページを生成しています。

gatsby-node.js
const path = require('path')
const slash = require('slash')

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions

  const result = await graphql(`
    {
      allWordpressPost {
        edges {
          node {
            id
            title
            status
          }
        }
      }
    }
  `)

  if (result.errors) {
    throw new Error(result.errors)
  }
  const { allWordpressPost } = result.data

  const postTemplate = path.resolve('./src/templates/post.js') // テンプレートのパス
  allWordpressPost.edges.forEach(edge => {
    createPage({
      path: `/${edge.node.title}/`, // ページを紐付けるURL
      component: slash(postTemplate),  // もととなるページテンプレートを指定
      context: {
        id: edge.node.id, // templateにわたす変数
      },
    })
  })
}

続いて、生成ページの基礎となるtemplateを作成します。
templatesディレクトリを切りpost.jsを以下内容で新たに追加します。
ポイントはGraphQL部分でgatsby-node.jscreatepage()で受け取った変数(ページID)を使って問い合わせを行っている点です。
これでページごとの情報を取得して表示しています。

templates/post.js
import React, { Component } from "react"
import { graphql } from "gatsby"
import PropTypes from "prop-types"
import Layout from "../components/layout"

class PostTemplate extends Component {
  render() {
    const post = this.props.data.wordpressPost

    return (
        <Layout>
          <h1 dangerouslySetInnerHTML={{ __html: post.title }} />
          <div dangerouslySetInnerHTML={{ __html: post.content }} />
        </Layout>
    )
  }
}

PostTemplate.propTypes = {
  data: PropTypes.object.isRequired,
  edges: PropTypes.array,
}

export default PostTemplate

export const pageQuery = graphql`
    query($id: String!) {
        wordpressPost(id: { eq: $id }) {
            title
            content
        }
    }
`

終わりに

以上、Gatsby.jsでWordPressと連携。記事を一覧、詳細を表示するまででした。
このように簡単にwordpressのリソースを利用できるので、wordpressからの移行にgatsby.jsはとてもオススメだと思います。
色々開発進める中でのTipsを別途纏めていきたいと思います。

おまけ

拙著ですがIntelliJでGraphQL扱うなら、このPluginがオススメです。
エンドポイントからschema.jsを自動生成してくれて、流れるようにQuery書けます。
intelliJでgraphQLを書くときに便利なプラグイン

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6