Next.jsとWordPressを使って、サイト構築を行なっています。
プラグインの「WPGraphQL」を使って、データ取得を行なっている中で投稿ページにページネーションを作る際に手こずったので、実装方法をまとめておきます。
ページネーションの実装にはいくつかのアプローチがあります。この記事では、カスタムフィールドを追加することで効率的なページネーションを実現する方法について解説します。
全件取得によるページネーション
最もシンプルなページネーションのアプローチは、全ての投稿やページを一度に取得し、クライアントサイドでこれをページ分割する方法です。このアプローチのメリットは、実装の簡単さにあります。しかし、データ量が多い場合にはパフォーマンスの問題を引き起こす可能性があります。
記事全件を取得してくる必要があるので流石にこれは…と思いました。
なので別のアプローチを取ることを考えました。
カスタムフィールドを使用した効率的なページネーション
より効率的なページネーションを実現するには、WPGraphQLでカスタムフィールドを追加し、次の投稿や前の投稿を直接クエリできるようにする方法があります。これにより、必要なデータのみを正確に取得し、パフォーマンスを向上させることができます。
実装ステップ
WordPressのfunctions.php
ファイルに、カスタムフィールドを追加するコードを追加します。
下記のコードを追加することで1件の投稿を取得するクエリに対して「次の記事」「前の記事」を取得するフィールドを追加することができます。
add_action('graphql_register_types', function () {
register_graphql_field('Post', 'nextPost', [
'type' => 'Post',
'description' => '次の投稿を取得します。',
'resolve' => function($root, $args, $context, $info) {
$next_post = get_adjacent_post(false, '', false);
if ($next_post) {
return \WPGraphQL\Data\DataSource::resolve_post_object($next_post->ID, $context);
}
return null;
}
]);
register_graphql_field('Post', 'previousPost', [
'type' => 'Post',
'description' => '前の投稿を取得します。',
'resolve' => function($root, $args, $context, $info) {
$prev_post = get_adjacent_post(false, '', true);
if ($prev_post) {
return \WPGraphQL\Data\DataSource::resolve_post_object($prev_post->ID, $context);
}
return null;
}
]);
});
コードの解説
add_action('graphql_register_types', function () {...});
:- この行は、
graphql_register_types
アクションフックを使用しています。これにより、WPGraphQLのスキーマがロードされる際にカスタムフィールドを登録する関数が実行されるように設定されます。
- この行は、
register_graphql_field('Post', 'nextPost', [...]);
:- ここで
Post
タイプにnextPost
という名前のカスタムフィールドを追加しています。このフィールドのタイプはPost
であり、これにより、次の投稿のデータが返されることを意味します。
- ここで
resolve
関数:resolve
関数は、クエリがこのフィールドを要求した際に実際に実行される関数です。この関数の目的は、次の投稿または前の投稿のデータを取得し、それを返すことです。get_adjacent_post(false, '', false)
とget_adjacent_post(false, '', true)
を使用して、それぞれ次の投稿と前の投稿を取得しています。第一引数のfalse
はカテゴリーを無視することを示し、第二引数の空文字列''
は任意のカテゴリーを指定しないことを意味し、第三引数がfalse
の場合は次の投稿を、true
の場合は前の投稿を取得します。
return \WPGraphQL\Data\DataSource::resolve_post_object($next_post->ID, $context);
:- ここで取得した投稿オブジェクトを、WPGraphQLが理解できる形式のデータに変換しています。これにより、次の投稿または前の投稿のデータをGraphQLクエリのレスポンスとして適切に返すことができます。
そして、追加したカスタムフィールドを利用するGraphQLクエリを作成します。nextPost
とpreviousPost
の部分が今回追加したものになります。
query{
post(id: "記事のslugが入ります", idType: SLUG) {
databaseId
date
modified
nextPost {
title
slug
uri
}
previousPost {
title
slug
uri
}
content(format: RENDERED)
title(format: RENDERED)
featuredImage {
node {
altText
sourceUrl
mediaDetails {
height
width
}
}
}
tags {
nodes {
databaseId
name
}
}
categories {
nodes {
databaseId
name
}
}
}
}
まとめ
フィールドを追加することができることを学びました。
パフォーマンスも考慮した実装を気をつけたいですね。