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

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

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

# Wordpressプラグインの追加

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

```bash
$ yarn add gatsby-source-wordpress
```

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

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

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

```jsx: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を元に動的にページを生成しています。

```js: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.js`の`createpage()`で受け取った変数（ページID）を使って問い合わせを行っている点です。
これでページごとの情報を取得して表示しています。

```js: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を書くときに便利なプラグイン](https://qiita.com/ryo2132/items/b9bad0e1be756337482e)