Craft 3 の Element API でページ送りを有効にしたまま1ページの表示件数を変更する

Craft 3 の Element API でページ送りを有効にしたまま1ページの表示件数を変更する方法をご紹介します。

Craft CMS Logo

Element API を定義する config/element-api.php に下記のようなエンドポイントの設定があったとします。

return [
  'endpoints' => [
    'news.json' => function() {
      return [
        'elementType' => Entry::class,
        'criteria' => [
          'section' => 'news',
        ],
        'transformer' => function(Entry $entry) {
          return [
            'title' => $entry->title,
            'url' => $entry->url,
            'jsonUrl' => UrlHelper::url("news/{$entry->id}.json"),
            'summary' => $entry->summary,
          ];
        },
      ];
    },
  ]
];

Craft CMS のお作法を考えて、 criterialimit を追加してみます。

return [
  'endpoints' => [
    'news.json' => function() {
      return [
        'elementType' => Entry::class,
        'criteria' => [
          'section' => 'news',
          'limit' => 2, // 追加
        ],
        'transformer' => function(Entry $entry) {
          return [
            'title' => $entry->title,
            'url' => $entry->url,
            'jsonUrl' => UrlHelper::url("news/{$entry->id}.json"),
            'summary' => $entry->summary,
          ];
        },
      ];
    },
  ]
];

残念ながら、これだと最初と同じレスポンスが返ってきます。このように criteria につけた limit を有効にするには、下記のようにして paginate を無効にする必要があります。

return [
  'endpoints' => [
    'news.json' => function() {
      return [
        'elementType' => Entry::class,
        'criteria' => [
          'section' => 'news',
          'limit' => 2,
        ],
        'paginate' => false, // 追加
        'transformer' => function(Entry $entry) {
          return [
            'title' => $entry->title,
            'url' => $entry->url,
            'jsonUrl' => UrlHelper::url("news/{$entry->id}.json"),
            'summary' => $entry->summary,
          ];
        },
      ];
    },
  ]
];

このようにすれば指定の2件だけ返ってきますが、ページ送りの情報が返ってきません。

ではどうすれば良いかというと、下記のようにして elementsPerPage を追加すれば OK です。

return [
  'endpoints' => [
    'news.json' => function() {
      return [
        'elementType' => Entry::class,
        'criteria' => [
          'section' => 'news',
        ],
        'elementsPerPage' => 2, // 追加
        'transformer' => function(Entry $entry) {
          return [
            'title' => $entry->title,
            'url' => $entry->url,
            'jsonUrl' => UrlHelper::url("news/{$entry->id}.json"),
            'summary' => $entry->summary,
          ];
        },
      ];
    },
  ]
];

ついでに URL に付けた limit パラメータの値で動的に制御する場合は下記のようにすれば OK です。

return [
  'endpoints' => [
    'news.json' => function() {
      $request = Craft::$app->getRequest(); // 追加
      $limit = (int)$request->getParam('limit') ?: null; // 追加
      return [
        'elementType' => Entry::class,
        'criteria' => [
          'section' => 'news',
        ],
        'elementsPerPage' => $limit, // 変更
        'transformer' => function(Entry $entry) {
          return [
            'title' => $entry->title,
            'url' => $entry->url,
            'jsonUrl' => UrlHelper::url("news/{$entry->id}.json"),
            'summary' => $entry->summary,
          ];
        },
      ];
    },
  ]
];
Published 2020-07-28
Updated 2020-08-09