WordPressクエリループで出力する記事の条件を変更する

WordPressのクエリループブロックは投稿タイプを複数選択できない、カスタムフィールドで絞り込めないなどの制約があります。ここでは、クエリループブロックの絞り込み条件を変更して、記事が出力される条件をカスタマイズしていきます。

通常クエリループブロックの条件

カスタム投稿タイプ「sample」を作成し、クエリループブロックで一覧を表示すると、次のようなクエリが渡ってきます。

add_filter('query_loop_block_query_vars', function ($query) {
    echo '<pre>';
    var_export($query);
    echo '</pre>';

});

結果は、カスタム投稿タイプ「sample」と「post」が渡ってきました。

array (
  'post_type' => 'sample',
  'order' => 'DESC',
  'orderby' => 'date',
  'post__not_in' => 
  array (
  ),
  'tax_query' => 
  array (
  ),
  'offset' => 0,
  'posts_per_page' => 10,
  'author__in' => 
  array (
  ),
)
array (
  'post_type' => 'post',
  'order' => 'DESC',
  'orderby' => 'date',
  'post__not_in' => 
  array (
  ),
  'tax_query' => 
  array (
  ),
  'offset' => 0,
  'posts_per_page' => 4,
  'author__in' => 
  array (
  ),
)

「post」は除外しておきます。

add_filter('query_loop_block_query_vars', function ($query) {
    if ('sample' !== $query['post_type']) {
        return $query;
    }

    echo '<pre>';
    var_export($query);
    echo '</pre>';

});

クエリ条件から投稿が除外されました。

array (
  'post_type' => 'sample',
  'order' => 'DESC',
  'orderby' => 'date',
  'post__not_in' => 
  array (
  ),
  'tax_query' => 
  array (
  ),
  'offset' => 0,
  'posts_per_page' => 10,
  'author__in' => 
  array (
  ),
)

ここで出力結果の詳細を見てみます。

パラメータ説明
post_typesample取得する投稿タイプ。通常投稿なら post、固定ページなら page、カスタム投稿ならそのスラッグを指定。
orderDESC並び順。DESC は降順(新しい順・大きい順)、ASC は昇順(古い順・小さい順)。
orderbydate何を基準に並べるか。date は投稿日順。
post__not_inarray()除外する投稿ID。array(1,2,3) のように指定するとその投稿は表示されない。
tax_queryarray()カテゴリーやタグ、カスタムタクソノミーで絞り込む条件。
offset0先頭から何件スキップするか。10 なら最初の10件を飛ばして取得。
posts_per_page10取得件数。-1 で全件取得。
author__inarray()指定した投稿者の投稿のみ取得。array(1,5) のように指定する。

orderbyの詳細はこちら。

orderby説明
date投稿日順
titleタイトル順
menu_order表示順(固定ページなど)
randランダム
comment_countコメント数順
meta_valueカスタムフィールド値順(文字列)
meta_value_numカスタムフィールド値順(数値)
modified更新日順
ID投稿ID順
author投稿者順

クエリループブロックをカスタムフィールドの値で並べる

各記事のカスタムフィールド「sample_number」に任意の数値を入力し、次のようにカスタマイズする。

add_filter('query_loop_block_query_vars', function ($query) {

    if ('sample' !== $query['post_type']) {
        return $query;
    }

    $query['meta_key'] = 'sample_number';
    $query['orderby'] = 'meta_value_num';
    $query['order'] = 'ASC';

    return $query;
});

クエリ条件が変更になり、投稿の表示順もカスタムフィールドの値の昇順になる。

array (
  'post_type' => 'sample',
  'order' => 'ASC', // 変更
  'orderby' => 'meta_value_num', // 変更
  'post__not_in' => 
  array (
  ),
  'tax_query' => 
  array (
  ),
  'offset' => 0,
  'posts_per_page' => 10,
  'author__in' => 
  array (
  ),
  'meta_key' => 'sample_number', // 変更
)

複数の投稿タイプをふくめる

クエリループブロックに「post」とカスタム投稿タイプ「sample」を出力する。

add_filter('query_loop_block_query_vars', function ($query) {
    if ('sample' !== $query['post_type']) {
        return $query;
    }

    $query['post_type'] = array(
        'post',
        'sample'
    );
    $query['order'] = 'ASC';

    return $query;
});

結果は「post_type」が配列型になり、「post」とカスタム投稿タイプ「sample」が格納され、複数の投稿タイプの記事が表示される。

array (
  'post_type' => 
  array (
    0 => 'post',
    1 => 'sample',
  ),
  'order' => 'ASC',
  'orderby' => 'date',
  'post__not_in' => 
  array (
  ),
  'tax_query' => 
  array (
  ),
  'offset' => 0,
  'posts_per_page' => 10,
  'author__in' => 
  array (
  ),
)

query_loop_block_query_vars フック

return apply_filters( 'query_loop_block_query_vars', $query, $block, $page );
項目意味
$queryWP_Query に渡される引数の配列
$block現在処理中のクエリループブロックのオブジェクト
$page現在のページ番号(1ページ目なら1、2ページ目なら2)

クラス名に基づいてクエリを変更する

投稿テンプレートブロックにターゲットとして目印になるCSSクラス「sample-target」を付与した場合のみ、クエリを変更する。

add_filter('query_loop_block_query_vars', function ($query, $block, $page) {

    if ('sample' !== $query['post_type']) {
        return $query;
    }

    $block = $block->parsed_block;

    if (
        isset($block['attrs']['className'])
        && false !== strpos($block['attrs']['className'], 'sample-target')
    ) {
        $query['order'] = 'ASC';
    }

    return $query;
}, 10, 3);

投稿テンプレートに「sample-target」クラスを持つクエリループの並び順が昇順に変更になる。

array (
  'post_type' => 'sample',
  'order' => 'ASC',
  'orderby' => 'date',
  'post__not_in' => 
  array (
  ),
  'tax_query' => 
  array (
  ),
  'offset' => 0,
  'posts_per_page' => 6,
  'author__in' => 
  array (
  ),
)

処理について確認する。まず、ここでは、WP_Block オブジェクトを連想配列へ変換している。

$block = $block->parsed_block;

// 結果
array(
    'blockName' => 'core/post-template',
    'attrs' => array(
        'className' => 'sample-target',
    ),
    'innerBlocks' => array(
        array(
            'blockName' => 'core/post-title',
            'attrs' => array(
                'isLink' => true,
            ),
            'innerBlocks' => array(),
            'innerHTML' => '',
            'innerContent' => array(),
        ),
    ),
    'innerHTML' => '',
    'innerContent' => array(),
)

その結果、$blockに$block[‘attrs’]でアクセスできるようになり、$block[‘attrs’][‘className’]でクラス名を確認している。

クエリループブロックの出力条件変更はquery_loop_block_query_varsフック

コアのクエリループブロックはカスタマイズできる設定が少ないが、query_loop_block_query_varsフックを使用すると柔軟にクエリを変更できる。