メインクエリ

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

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

<?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ページあたりの投稿数は、管理画面 設定 > 表示設定 の「1ページに表示する最大投稿数」に依存する。

<?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( array(
        '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カテゴリの記事を表示する。 ※ 投稿数(posts_per_page)を明示しない場合は管理画面の設定の影響を受ける点が、後述するget_posts()(明示しない場合のデフォルトは5件)と異なる。

<?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;

    $query = new WP_Query( array(
        'posts_per_page' => 10,
        'paged'          => $paged,
        'tax_query'      => array(
            array(
                '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();

    the_posts_pagination( array(
        '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>',
    ) );
?>

※ 元のコードは$pagedの算出をthe_posts_pagination()呼び出しの後(クエリ生成より後)に書いていたが、$queryのpaged引数で使用する変数なので、クエリ生成より前に移動した。

引数なしで作成した場合は投稿を全く持たない。

$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( array(
        '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( array(
        '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>',
    ) );
?>

※ 元のコードは`category_name` => 'example'のように配列のキーがバッククォートで囲まれており、PHPの構文として不正だったため、通常のクォート'category_name'に修正した。

サブクエリ参考

  • 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(「カスタムクエリを使用した例」がそのまま使用できる)
  • 参考: https://yuki.world/wp-main-sub-query-pagination/