getEntityRecords()とページネーション。
使える条件は?
エンティティ操作ではメタ情報からアイテムの総数およびページの最大数を取得出来るようになってます。
ただし、設定にsupportsPagination: true
が含まれていることと、per_page
が-1ではないことです。
以下はエンティティの設定情報を片っ端から取得して、supportsPagination: true
の設定を探したものです。
[‘postType’, ‘taxonomy’, ‘root’].map(kind => wp.data.select(‘core’).getEntitiesConfig(kind).map(e => [e.name, e.baseURL, e.supportsPagination] ))
- エンティティ設定についてはこちら
https://kurage-worker.com/2024/gutenberg-core-data-entity-rest-api
supportsPagination
がtrue
の設定情報を見ていきます。
kindがpostType
全般と、root
のmedia(/wp/v2/media)
及びglobalStyles(/wp/v2/global-styles)
が該当するようです。
これらはハードコーディング(/core-data/src/entities.js)されているようです。
どこにロジックが存在する?
一方サーバーサイドでは投稿のWP_REST_Posts_Controller
などいくつかのコントローラで実装してあります。
以下のようにコントローラのget_items()
ヘッダーに情報が設定されます。
$response->header( 'X-WP-Total', (int) $total_posts );
$response->header( 'X-WP-TotalPages', (int) $max_pages );
- コントローラの実装についてはこちら
Gutenbergはどこで取得してるの?
getEntityRecords()
のリゾルバは内部でapiFetch()
を使ってREST APIへアクセスします。
その際ヘッダの「X-WP-Total
」および「X-WP-TotalPages
」から目的の情報を取得しメタ情報に追加します。
メタのプロパティはそれぞれ「totalItems
」及び「totalPages
」ですが、その取得はそれぞれgetEntityRecordsTotalItems()
, getEntityRecordsTotalPages()
から取得します。
getEntityRecordsTotalItems()
取得出来るアイテムの総数を取得します。
クエリと一致している必要があります。
wp.data.select('core').getEntityRecords('postType', 'post', { search: 'x' })
null
wp.data.select('core').getEntityRecords('postType', 'post', { search: 'x' })
(3) [{…}, {…}, {…}]
wp.data.select('core').getEntityRecordsTotalItems('postType', 'post', { search: 'x'})
3
getEntityRecordsTotalPages()
ページの総数を取得します。
例えば1ページに10
件表示する場合(per_page
に指定)、アイテム総数が25
個あれば、
「1-10
, 11-20
, 21-25
」までの3
ページあり、その3
を取得します。
wp.data.select('core').getEntityRecords('postType', 'post', { search: 'x' })
null
wp.data.select('core').getEntityRecords('postType', 'post', { search: 'x' })
(3) [{…}, {…}, {…}]
wp.data.select('core').getEntityRecordsTotalPages('postType', 'post', { search: 'x', per_page: 1 })
3
wp.data.select('core').getEntityRecordsTotalPages('postType', 'post', { search: 'x', per_page: 2 })
2
wp.data.select('core').getEntityRecordsTotalPages('postType', 'post', { search: 'x', per_page: 3 })
1
ただし、クエリにper_page
が無いのNaN
になってしまうので注意します。
これらを使って以下のようなコードが書けます。
wp.data.select('core').getEntityRecords('postType', 'post')
null
wp.data.select('core').getEntityRecords('postType', 'post')
(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
const totalItems = wp.data.select('core').getEntityRecordsTotalItems('postType', 'post')
const totalPages = wp.data.select('core').getEntityRecordsTotalPages('postType', 'post', { per_page: 5 })
const msg = `全部で「${totalItems}」件ありました。1-${totalPages}ページまでを表示します。`;
msg
'全部で「39」件ありました。1-8ページまでを表示します。'
最後に
でも実際はuseEntityRecords()
から使用されているようです。
hooksなのでコンポーネント内で使用します。
import { useEntityRecords } from "@wordpress/core-data"
export default ({kind, name, queries}) =>
{
const { totalItems, totalPages } = useEntityRecords(kind, name, queries);
// NaN対策
if(!queries.per_page)
{
queries['per_page'] = 5;
}
const msg = `全部で「${totalItems}」件ありました。1-${totalPages}ページまでを表示します。`;
return <h1>{msg}</h1>
}
こちらもNaN
にならないように注意して使います。