0

%

Knowledge

【WordPressヘッドレス化】GraphQLでAll In One SEOの情報を取得できるようにする

コーディング

こんにちは!アルテガエンジニアのHarukichiです。

最近、弊社のコーポレートサイトをWordPressヘッドレス化 x Astroでリニューアルしました。
その時に右往左往したことをシリーズに分けてアウトプットしていこうと思います。

今回は、All in one SEOプラグインに入れていた大量のdescriptionデータをGraphQLで取得したお話です。

経緯

実現したかったこと
All in one SEOプラグインで設定したオリジナルのmeta descriptionデータをWPGraphQLで取得したい。

弊社では、大事な記事にオリジナルのdescriptionを設定しています。↓こんな感じ

数百記事分のデータが入っているAll in one SEOのmeta description等のデータをヘッドレス化でも使いたい・・・!
しかし、WPGraphQLではデフォルトで取得することができませんでした。
※WP REST APIでも一緒なはず。

インテグレーションが用意されているYoast SEOにデータを移すことも考えましたが、
弊社員がみんな使い慣れていたAll in one SEOプラグインのままmetaデータを取得できないか試行錯誤してみました。

functions.phpにコードを追加

データベースとして使用しているWordPressのfunctions.phpに追記します。
今回は、標準の投稿(post)とカスタム投稿(case)に設定。
「_aioseop_description」というキーが使えるようだったので、GraphQLに新しいtypeとして追加してみました。
//functions.php


/*
 * All in one SEOをGraphQLに追加
 */
add_action('graphql_register_types', function() {
  // 標準投稿(Post)にAll in One SEOのディスクリプションを追加
  register_graphql_field('Post', 'aioseopDescription', [
    'type'        => 'String',
    'description' => __('All in One SEOのディスクリプション', ''),
    'resolve' => function($post) {
      $value = get_post_meta($post->ID, '_aioseo_description', true);
      return $value;
    },
  ]);

  // カスタム投稿タイプ"case"にAll in One SEOのディスクリプションを追加
  register_graphql_field('Case', 'aioseopDescription', [
    'type'        => 'String',
    'description' => __('All in One SEOのディスクリプション(Case)', ''),
    'resolve' => function($post) {
      $value = get_post_meta($post->ID, '_aioseo_description', true);
      return $value;
    },
  ]);
});

実際にWPGraphQLでmeta descriptionを取得してみる

WPGraphQLのIDEを使って確認してみました。

meta descriptionが格納されている、data.post.aioseoDescripionを取得できていることが確認できました。

※カスタム投稿も同様に取得することができます。

All in one SEOにmetaデータがあれば使用する設定

記事にmeta descriptionが設定されていない場合もあります。
その場合は、記事から抜粋したテキストをmeta descriptionとして設定するようにしてみました。

// blog/[slug].astro(記事詳細ページ)


---
import { postsPromise } from '../../data/posts'; //ここでGraphQLから詳細ページのあれこれをfetch

// postsPromiseからslugに合致する投稿を探す
const { slug } = Astro.params;
const allPosts = await postsPromise;
const post = allPosts.find((post) => post.slug === slug);

// description
const plainExcerpt = post.excerpt?.replace(/<[^>]*>/g, '') || ''; //プレーンテキスト抜粋(HTMLタグ除去)
const description = post.aioseopDescription || plainExcerpt; // descriptionの出し分け
---
<layout metadescription="{description}"> //Layoutコンポーネントにdescription情報を渡す
</layout>


この部分で、All in one SEOのデータがあれば設定、なければ抜粋を設定するようにしています。


const description = post.aioseopDescription || plainExcerpt;

これで、管理画面からDescriptionの柔軟な対応ができるようになりました🎉

参考にさせていただいた記事

All in one SEOのデータをWP REST APIで取得できるようにしている方がいらっしゃって、参考にさせていただきました!
ありがとうございます。

https://qiita.com/hardreggaecafe/items/4b3a0b351e708b15c5aa

まとめ

すでに数百の手書きmeta descriptionデータがあったので、
なるべく今までの使い勝手を変えずに かつ 柔軟な設定ができるように工夫できたと思います。
ただし、プラグイン公式の方法ではないのでお使いになる場合は自己責任でお願いいたします🙇‍♀️

したっけね!