Shifter Headless 上の WordPress で Advanced Custom Fields を使用し、GatsbyJS でデータを取得する

ishigaki

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

今回は「Shifter Headless + GatsbyJS で WordPress の記事からページを生成する方法」の記事に引き続いて、 Shifter Headless 上の WordPress で Advanced Custom Fields を使用し、React 向け静的サイトジェネレーターの GatsbyJS でデータを取得する方法についてまとめたいと思います。

Advanced Custom Fields とは

Advanced Custom Fields (ACF) とは、 WordPress 上で簡単に、投稿画面にカスタムフィールドを実装できるプラグインです。

WordPress の中身を触ることなく、管理画面だけでカスタムフィールドを追加できるのが大きな特徴です。

公式ドキュメントの使用できるフィールド一覧(一部)

追加できるフィールドの種類も、テキストフィールドやラジオボタン、真偽値のトグルボタンや画像などを始めとした、多くのフィールドに対応しています。また、フィールドのグルーピング機能なども備えています。

この記事では ACF についての詳しい説明は割愛しますので、詳しくはこちらの公式ドキュメントをご覧ください。

Shifter Headless で Advanced Custom Fields を使う

今回は以前の記事「Shifter Headless で WordPress を Headless CMS として使う」から引き続き、 WordPress をサーバーレスの Headless CMS として提供するサービスであるShifter Headlessを使用します。

Shifter Headless で構築した WordPress には ACF がデフォルトでインストールされており、また GraphQL で ACF のAPIを取得できるようなプラグイン群も既にセットアップされているため、すぐに使い始めることができます。

ただし注意点として、Shifter Headless では新たにプラグインをインストールすることができないため、 PRO 版の機能を使用することはできません。

Shifter Headless 上の WordPress で Advanced Custom Fields を作成する

Shifter Headless + GatsbyJS で WordPress の記事からページを生成する方法」の記事でセットアップしたWordPress環境を前提にご紹介します。

Shifter Headless で構築した WordPress のプラグイン一覧(一部)

まずは WordPress の REST API を GatsbyJS 側で取得できるようにするために、WP Gatsby WP GraphQL を有効化します。

次に Advanced Custom Fields WPGraphQL for Advanced Custom Fields を有効化し、 ACF を使えるようにする前準備を行います。

フィールドグループの作成

サイドバーから カスタムフィールド > 新規追加 に移動し、フィールドグループを作成します。

作成したフィールドグループのフィールド一覧

今回は「テキスト」「画像」「投稿オブジェクト」「リンク」そして子に「テキスト」フィールドを持つ「グループ」を持つフィールドグループを例として作成しました。

フィールドグループとはその名の通りカスタムフィールドのグループで、作成したグループを投稿種別やカテゴリなどで出し分けすることができます。

ここで注意点なのですが、デフォルトでは ACF のカスタムフィールドは GraphQL では取得できないようになっており、フィールドグループの Show in GraphQL をオンにしないと取得することができません。

フィールドグループの設定の下部から Show in GraphQL を有効にして取得できるようにさせる

オンにすると、GraphQL Field Name で設定した名前で取得できるようになります。

投稿画面に表示されたカスタムフィールドのキャプチャ

作成したカスタムフィールドは、投稿画面で画像のように表示されます。

いくつかのフィールドについて説明すると、「画像」フィールドではブロックエディタと同様に、画像のアップロードとメディアライブラリからの選択を行うことができます。

「投稿オブジェクト」は他の投稿を参照します。

GatsbyJS 側でデータを取得する

GatsbyJS 側では前回の記事でご紹介した gatsby-source-wordpress-experimental をあらかじめ導入しておきます。ACF を使う上で追加の設定は必要ありません。

WordPress 側で投稿できると、それぞれのフィールドのデータは GraphiQL で下記のように取得できます。

テキスト

query MyQuery {
  post(id: "[投稿id]") {
    acfExample {
      text
    }
  }
}
{
  "data": {
    "post": {
      "acfExample": {
        "text": "テキストサンプル"
      }
    }
  }
}

画像

query MyQuery {
  post(id: "[投稿id]") {
    acfExample {
      image { // 主要なフィールドを抜粋
        altText // alt
        caption // キャプション
        description // 概要
        fileSize
        mediaType
        mimeType
        slug
        sizes
        sourceUrl
        srcSet // サイズごとの src のURL
        title
      }
    }
  }
}
{
  "data": {
    "post": {
      "acfExample": {
        "image": { // 主要なフィールドを抜粋
          "altText": "ACFの公式サイトのスクリーンショット",
          "caption": "<p>キャプション</p>\n",
          "description": "<p>概要</p>\n",
          "fileSize": 636116,
          "mediaType": "image",
          "mimeType": "image/png",
          "slug": "acf_screenshot",
          "sizes": "(max-width: 300px) 100vw, 300px",
          "sourceUrl": "[CDNのURL]/uploads/2020/08/acf_screenshot.png",
          "srcSet": "[CDNのURL]/uploads/2020/08/acf_screenshot-300x140.png 300w, [CDNのURL]/uploads/2020/08/acf_screenshot-1024x478.png 1024w, [CDNのURL]/uploads/2020/08/acf_screenshot-768x358.png 768w, [CDNのURL]/uploads/2020/08/acf_screenshot-1536x717.png 1536w, [CDNのURL]/uploads/2020/08/acf_screenshot-2048x956.png 2048w",
          "title": "acf_screenshot"
        }
      }
    }
  }
}

投稿オブジェクト

query MyQuery {
  post(id: "[投稿id]") {
    acfExample {
      postObject {
        ... on Post { // 主要なフィールドを抜粋
          content
          excerpt // 抜粋
          link // 絶対URL
          slug
          status
          title
          uri // ルートURL
        }
      }
    }
  }
}
{
  "data": {
    "post": {
      "acfExample": {
        "postObject": { // 主要なフィールドを抜粋
          "content": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n",
          "excerpt": "<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!</p>\n",
          "link": "[ShifterのURL]/1/",
          "slug": "hello-world",
          "status": "publish",
          "title": "Hello world!",
          "uri": "/1/"
        }
      }
    }
  }
}

リンク

query MyQuery {
  post(id: "[投稿id]") {
    acfExample {
      link {
        target // target 属性の値
        title
        url
      }
    }
  }
}
{
  "data": {
    "post": {
      "acfExample": {
        "link": {
          "target": "",
          "title": "Advanced Custom Fields",
          "url": "https://www.advancedcustomfields.com/"
        }
      }
    }
  }
}

グループ

query MyQuery {
  post(id: "[投稿") {
    acfExample {
      group { // オブジェクトのように参照できる
        fieldGroupName
        subText
        subText2
      }
    }
  }
}
{
  "data": {
    "post": {
      "acfExample": {
        "group": {
          "fieldGroupName": "group",
          "subText": "サブテキスト",
          "subText2": "サブテキスト2"
        }
      }
    }
  }
}

この GraphQL クエリを使用して、 GatsbyJS 上のページにデータを流し込むことが出来ます。

まとめ

今回は Shifter Headless 上の WordPress で Advanced Custom Fields を使用し、GatsbyJS でデータを取得する方法についてまとめました。

今回ご紹介したフィールドは一部であり、 ACF についてまだ触りきれていない部分もあるのでまた触ってみて学びたいと思っています。

感想として、 Headless CMS として WordPress を使う上で Advanced Custom Fields を使用することでかなり他の Headless CMS と近い感覚でフィールドのセットアップを行うことができるように感じました。

WordPress を Headless CMS として使いたい方はもちろん、 Headless CMS をどれを使うか検討している方も Shifter Headless で構築した WordPress を候補の一つに入れてみてはいかがでしょうか。

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

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

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

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

お問い合わせしてみる!


ishigaki

投稿者 石垣 祥太郎

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