getEntityRecords()とページネーション。

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

supportsPaginationtrueの設定情報を見ていきます。
kindがpostType全般と、rootmedia(/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 );
  • コントローラの実装についてはこちら

https://kurage-worker.com/2024/wordpress-rest-api-controller%e3%82%92%e5%ae%9f%e8%a3%85%e3%81%97%e3%81%a6%e3%81%bf%e3%82%8b%e3%80%82

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にならないように注意して使います。

BlockEditor certificate css DataGrid Docker Gutenberg Hyper-V iframe MUI openssl PHP React ReduxToolkit REST ubuntu WordPress オレオレ認証局 フレームワーク