#
ドキュメント

Document

自分のための備忘録です。

メインクエリとサブクエリ

メインクエリ

WordPress は、リクエストに応じたメインクエリを作成します。
WordPress は、have_posts()the_post() などのメインクエリで取得した投稿を処理する関数を提供しています。

※ 1. 下記サンプルコードは、アーカイブなどでよく使われるページネーションを表示する the_posts_pagination() のコードも合わせて掲載しています。
※ 2. 1 ページあたりの投稿数は管理画面 Settings > Reading Settings > Blog pages show at most に依存します。

<?php
    if ( have_posts() ) {
        echo '<ul>';
        while ( have_posts() ) {
            the_post();
            echo sprintf("<li><a href='%s'>%s</a></li>", get_the_permalink(), get_the_title());
        }
        echo '</ul>';
    }
     
    the_posts_pagination(
        array(
            'prev_text'          => __( 'Previous page', 'example' ),
            'next_text'          => __( 'Next page', 'example' ),
            'before_page_number' => '<span class="meta-nav screen-reader-text">' .
                                    __( 'Page', 'example' ) . ' </span>',
        )
    );
?>

$wp_query

グローバル変数 $wp_query はメインクエリを格納しており、リクエストから生成されるクエリで取得した投稿を保持しています。
下記コードは前述したコードとほぼ同じ働きをします。

※ 1. 下記サンプルコードは、アーカイブなどでよく使われるページネーションを表示する the_posts_pagination() のコードも合わせて掲載しています。
※ 2. 1 ページあたりの投稿数は管理画面 Settings > Reading Settings > Blog pages show at most に依存します。

<?php
    global $wp_query;

    if ( $wp_query->have_posts() ) {
        echo '<ul>';
        while ( $wp_query->have_posts() ) {
            $wp_query->the_post();
            echo sprintf("<li><a href='%s'>%s</a></li>", get_the_permalink(), get_the_title());
        }
        echo '</ul>';
    }

    the_posts_pagination([
    'prev_text'          => __( 'Previous page', 'example-domain' ),
    'next_text'          => __( 'Next page', 'example-domain' ),
    'before_page_number' => '<span class="meta-nav screen-reader-text">' .
        __( 'Page', 'example-domain' ) . ' </span>',
    ]);
?>

WP_Query

メインクエリとは異なる条件に一致する投稿を表示したいときなどに使われます。
メインクエリに影響を与えることなく新しいクエリを作成します。

下記サンプルは example カテゴリの記事を表示します。
※ 投稿数は管理画面の影響を受ける点が、後述する get_posts() と異なります。

<?php
    // メインクエリ
    if ( have_posts() ) {
        echo '<ul>';
        while ( have_posts() ) {
            the_post();
            echo sprintf("<li><a href='%s'>%s</a></li>", get_the_permalink(), get_the_title());
        }
        echo '</ul>';
    }
    
    // サブクエリ
    $query = new WP_Query([
        'posts_per_page' => 10,
        'paged' => $paged,
        'tax_query' => [ 
            [
                'taxonomy' => 'category',
                'field'    => 'slug',
                'terms'    => 'example',
            ],
        ],

    ]);

    if ( $query->have_posts() ) {
        echo '<ul>';
        while ( $query->have_posts() ) {
            $query->the_post();
            echo sprintf("<li><a href='%s'>%s</a></li>", get_the_permalink(), get_the_title());
        }
        echo '</ul>';
    }
    wp_reset_postdata();

    $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
    the_posts_pagination([
        'prev_text'          => __( 'Previous page', 'example-domain' ),
        'next_text'          => __( 'Next page', 'example-domain' ),
        'before_page_number' => '<span class="meta-nav screen-reader-text">' .
            __( 'Page', 'example-domain' ) . ' </span>',
    ]);
?>

引数なしで作成した場合は投稿を全く持ちません。

$query = new WP_Query();
$query->have_posts(); // false

get_posts()

上記の new WP_Query とほぼ同じように動作します。

get_posts() は引数で指定したクエリ条件に一致する投稿を取得します。
メインクエリとは異なる条件に一致する投稿を表示したいときなどに使われます。
メインクエリに影響を与えることなくあらたにクエリを作成します。

下記サンプルは example カテゴリの記事を表示します。

<?php
    // メインクエリ
    if ( have_posts() ) {
        echo '<ul>';
        while ( have_posts() ) {
            the_post();
            echo sprintf("<li><a href='%s'>%s</a></li>", get_the_permalink(), get_the_title());
        }
        echo '</ul>';
    }
    
    // サブクエリ
    $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
    $posts = get_posts([
        'posts_per_page' => 10,
        'paged' => $paged,
        `category_name` => 'example'
    ]);        

    foreach ($posts as $post) {
        setup_postdata($post);
        echo sprintf("<li><a href='%s'>%s</a></li>", get_the_permalink(), get_the_title());
    }
    wp_reset_postdata();
    
    the_posts_pagination([
        'prev_text'          => __( 'Previous page', 'example-domain' ),
        'next_text'          => __( 'Next page', 'example-domain' ),
        'before_page_number' => '<span class="meta-nav screen-reader-text">' .
                                __( 'Page', 'example-domain' ) . ' </span>',
    ]);
?>

サブクエリ

https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/paginate_links#.E7.94.A8.E4.BE.8B
↑のカスタムクエリを使用した例がそのまま使用できる。

ref. https://yuki.world/wp-main-sub-query-pagination/