Shifter Headless + GatsbyJS で WordPress の記事からページを生成する方法

ishigaki

こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。

今回は前回の記事「Shifter Headless で WordPress を Headless CMS として使う」に引き続き、Shifter Headless で生成した WordPress のデータを、 React ベースの静的サイトジェネレーター GatsbyJS で取得し、記事ごとにページが生成できるようにするまでの方法をまとめたいと思います。

Shifter Headless で生成した WordPress の API を GatsbyJS の GraphQL で取得する

Shifter Headless で生成した WordPress のプラグイン管理画面

前回の記事でご紹介した Shifter Headless でのセッティングを終わらせておき、 前もって WordPress の方で WP Gatsby WP GraphQL プラグインを有効化しておきます。

GatsbyJS の API 取得方法について

Gaji-LaboのコーポレートサイトはGatsbyJSで作られています」という記事でもご紹介しましたが、 GatsbyJS は GraphQL というクエリ言語を使用してページやコンテンツの生成に必要なAPIを取得します。

任意のデータソースから GraphQL を使用して API を取得できるようにするには、GatsbyJS にそのデータソース用に用意されたプラグインを導入する必要があります。

例えば、 GatsbyJS の src ディレクトリ以下に置いた markdown ファイルのAPIを取得するためのプラグイン gatsby-transformer-remark や、 Headless CMS の contentful からAPIを取得するプラグイン gatsby-source-contentful など、多種多様なデータソースからAPIの取得を行うために多くのプラグインが用意されています。

今回はデータソースとして Shifter Headless で生成した WordPress を使いたいので、 gatsby-source-wordpress-experimental というプラグインを導入します。

$ npm install --save gatsby-source-wordpress-experimental

2020年7月現在、gatsby-source-wordpress はバージョンアップが進められており、 バージョン3 が gatsby-source-wordpress 、バージョン4 が gatsby-source-wordpress-experimental としてそれぞれ並行して存在しています。

当記事では gatsby-source-wordpress-experimental でのやり方をご紹介しています。いずれ gatsby-source-wordpress-experimentalgatsby-source-wordpress として統合されて使えるようになるようです。

gatsby-config.js に以下の記述を追加することで、 GraphQL を使用して、 Shifter Headless で前もって生成した WordPress サイトからデータを取得することができるようになります。

詳しい設定は gatsby-source-wordpress-experimental のドキュメントも御覧ください。

module.exports = {
  ...
  plugins: [
    ...,
    {
      resolve: `gatsby-source-wordpress-experimental`,
      options: {
        url:
          `[生成したWordPressサイトのURL]/graphql`,
        schema: {
          typePrefix: `Wp`,
        },
        type: {
          Post: {
            limit:
              1000,
          },
        },
      },
    },
  ]
}

取得したデータは、allWpPost という GraphQL クエリを叩いて確認することができます。 (Wp は先程指定したプレフィックスで任意に変更できます)

{
  allWpPost {
    edges {
      node {
        slug
        title
        content
        excerpt
      }
    }
  }
}

GatsbyJS には GraphQL のクエリ実行結果をブラウザ上で確認できるツール GraphiQL が標準で導入されているので、 gatsby develop で開発を行っている際に (ローカルサーバーのアドレス)/_graphql というアドレスで GraphiQL を使ってクエリ実行結果を確認することができます。

例えば、 Shifter Headless で生成した WordPress で1つ目の画像のような投稿を行うと GraphQL では2つ目の画像のように取得できます。

WordPress側で画像のように記事を投稿すると
GatsbyJSのGraphQLで画像中央左のクエリを叩くことで画像右の出力が得られる

取得したAPIを使用してページを生成する

GatsbyJS で取得したAPIを使用してページを生成するには、 gatsby-node.js でAPIを取得し、ページのテンプレートファイルにデータを流し込む必要があります。

まずはテンプレートファイルを用意します。

import React from 'react';
import { graphql } from 'gatsby';

const Blog = (props) => {
  const { data } = props;
  const { wpPost: post } = data;

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

export default Blog;

export const pageQuery = graphql`
  query BlogByID($id: String!) {
    wpPost(id: { eq: $id }) {
      id
      slug
      title
      content
    }
  }
`;

次に、gatsby-node.js で、 WordPress から APIを取得し、ページのテンプレートファイルにデータを流し込んでページを生成します。

const path = require('path');

const createPages = (createPage, posts) => { // 取得した API からテンプレートファイルに流し込んでページを生成する
  posts.forEach(edge => {
    createPage({
      path: `/blog/${String(edge.node.slug)}`, // ページを生成させたいURL
      component: path.resolve(
        `src/templates/blog.jsx`, // テンプレートファイルのパス
      ),
      context: {
        id: edge.node.id, // テンプレートファイルの GraphQL `id: { eq: $id }` に渡すコンテキスト
      },
    });
  });
};

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

  return graphql(`
    {
      allWpPost { // API 取得
        edges {
          node {
            id
            slug
          }
        }
      }
    }
  `).then(result => {
    if (result.errors) {
      result.errors.forEach(e => console.error(e.toString()));
      return Promise.reject(result.errors);
    }

    const posts = result.data.allWpPost.edges;
    createPages(createPage, posts); // ページ生成

    return Promise.resolve();
  });
};

この設定を行った後、 gatsby develop すると、 指定した slug でページが生成されます。

/blog/test/

slug のURL でテンプレートファイルからページが生成された結果

まとめ

今回は前回の記事「Shifter Headless で WordPress を Headless CMS として使う」に引き続き、Shifter Headless で生成した WordPress のデータを、 React ベースの静的サイトジェネレーター GatsbyJS で取得し、記事ごとにページが生成できるようにするまでの方法をまとめました。

Shifter Headless に興味のある方、WordPress + GatsbyJS でサイトを構築したいと考えている方の参考にしていただけたらと思います。

Gaji-Laboでは、JavaScriptフレームワーク経験が豊富なパートナーさんを募集しています

Gaji-Laboでは、開発チームの一員としてプロジェクトに一緒に取り組んでくれる業務委託のパートナーさんを募集しています。

現在は特にJavaScriptフレームワーク実践と業務経験が豊富なWebフロントエンドエンジニアを必要としています。React + TypeScript、Vue.js、Next.js、Nuxt.js など、あなたの得意なフレームワークを教えて下さい!

パートナー契約へのお問い合わせもお仕事へのお問い合わせも、どちらもいつでも大歓迎です。まずはオンラインでのリモート面談からはじめましょう。ぜひお気軽にお問い合わせください!

お問い合わせしてみる!


ishigaki

投稿者 石垣 祥太郎

アシスタントエンジニアとしてHTML/CSS/JavaScriptの実装やRailsの組み込み、スタイルガイドの構築などを担当しています。 業務の中でさまざまな学びを吸収しながら、文書構造やアクセシビリティに目を向けたマークアップの学習やJavaScriptの学習などを行っています。チームに貢献できるエンジニアとなるために日々奮闘中です。