【WordPress】複数の投稿タイプの投稿をまとめてひとつの一覧にする

通常投稿とカスタム投稿、複数の投稿タイプが存在するとき、通常のアーカイブページは投稿タイプごとに分かれますが、今回は、すべての投稿タイプの投稿をまとめて一つの一覧ページとして表示する方法です。

表示例

空の固定ページを用意

複合の一覧ページは、通常のアーカイブページと違ってURLが自動生成されないため、まずはページを表示させるために空の固定ページを用意します。

中身は何も記述しません。

ページ専用テンプレートに一覧表示のコードを書く

以下のコードを、先ほど作成した固定ページの専用テンプレート「page-[pageslug].php」に記述します

<?php
    $wp_query = new WP_Query();
    $my_posts = array(
        'post_type' => array('demo', 'post'),//表示したい投稿タイプ
        'posts_per_page'=> '10',
//1ページ当たりの表示件数
        'paged' => $paged,
//ページャーを動作させるための記述
    );
    $wp_query->query( $my_posts );
    if( $wp_query->have_posts() ): while( $wp_query->have_posts() ) : $wp_query->the_post();
    $obj = get_post_type_object( $post->post_type ); //投稿タイプ情報を取得
?>
<div class="list">
    <div class="list-item">
        <h2>
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </h2>
        <p class="date"><?php the_time('Y.m.d') ?></p>
        <p class="type">
            <span class="type_<?php echo $post->post_type; ?>"><?php echo $obj->labels->name;//投稿タイプ情報から投稿タイプ名を表示?></span>:
            <?php 
            the_taxonomies(array(
                'template' => '%2$l'//タクソノミー名は表示しない,
                'term_template' => '<span class="tag">%2$s</span>',))//リンクは表示しない;
            ?>
        </p>
    </div>
</div>
    
<?php endwhile; endif; wp_reset_postdata(); ?>
<?php wp_pagination();//ページネーション ?>

カテゴリー表示は the_taxonomies();を使うことで、記事に設定されたすべてのタクソノミーのタームを表示してくれる(各カスタム投稿タイプごとにどのカスタムタクソノミーを使っているかをいちいち確認する必要が無い)ですが、リンクの有無や区切り文字の設定などの設定が複雑なので、解説記事を確認しながら表示を調整するとよいでしょう

また上記コードのwp_pagination();はそのままだと動かないので、functions.phpに下記ように登録しておく必要があります。

// ページネーション表示
function wp_pagination()
{
    global $wp_query;
    $big = 999999999;
    echo paginate_links(array(
        'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
        'format' => '?paged=%#%',
        'current' => max(1, get_query_var('paged')),
        'prev_text' => '<span>≪</span>',
        'next_text' => '<span>≫</span>',
        'total' => $wp_query->max_num_pages
    ));
}
add_action('init', 'wp_pagination');

おまけ:the_taxonomies()では出力調整が難しすぎるときは

the_taxonomies()と違い、タクソノミー名をひとつひとつ指定する必要はありますが、「投稿タイプが○○なら××タクソノミーのタームをとってくる」という指定をすることでget_the_termsなどでターム名をとってくることができます。

各投稿タイプごとに使っているタクソノミーが1種類であれば、この方法でも簡単に表示させられます。

<?php
    if($post->post_type == "post"){
        $terms = get_the_terms($post->ID, 'category');
    }elseif($post->post_type == "demo"){
        $terms = get_the_terms($post->ID, 'demo_cat');
    }
    if (empty($terms)) {
        echo '';
    } else {
        foreach ($terms as $term) {
            echo "<span>" . $term->name . "</span>";
        }
    }
?>