カスタム投稿で他の投稿を取り込みつつページャーもうまく動く環境作り

業務でWordPressを構築していると様々なニーズがあります、タイトルの様な変化球もよくある要望の1つです。

今回、備忘録として記事に残していますが憶測がやや含まれますので、もし記事中に間違いがあるようでしたらコメントやTwitterでお知らせください。

要件

2つのカスタム投稿はそれぞれ分かれており、一覧ページを持っている状態とします。
info/newsは全てに共通するニュースとしたいので、newsにも表示したいというというケースを仮定しています。

domain.com/news
domain.com/info/news

固定ページとカスタム投稿の命名が被ってしまうため、カスタム投稿名を変更しrewriteすることでバッティングを防ぐ方法で設定していきます。

カスタム投稿の登録

まずはそれぞれカスタム投稿の登録を行っていきます、post_typeは下記の様に定義します。
(必要分だけ追加していくことも勿論可能です。)

カスタム投稿A:news_post
カスタム投稿B:info_post

functions.phpに下記追加してください。

add_action( 'init', function() {
    // カスタム投稿 news_post 定義
    register_post_type('news_post', [
        'labels' => 'ニュース',
        'public' => true,
        'has_archive' => false,
        'supports' => array('title', 'editor', 'author'),
        'rewrite' => array('slug' => 'news', 'with_front' => true),
    ]);

    // カスタム投稿 info_post 定義
    register_post_type('info_post', [
        'labels' => 'ニュース|共通',
        'public' => true,
        'has_archive' => false,
        'supports' => array('title', 'editor', 'author'),
        'rewrite' => array('slug' => 'info/news', 'with_front' => true),
    ]);
}

上記で重要なのは、’has_archive’ => false としている点で、カスタム投稿としてのアーカイブは作らない様にしてください。

作成した2つのカスタム投稿には記事が無い状態だと思いますので、数件ダミーで作成しておいてください。(1つではなく複数無いとページネーションの挙動チェック出来ないので注意。)

カスタム投稿一覧を表示させるためにページを作る

後半で詳しく解説を行いますが、まずは今回の投稿を表示させるためのテンプレートを作成して、固定ページでそのテンプレートを元に表示させる様にします。

固定ページ用のテンプレートの作成

それぞれ下記の様にテンプレートを作成しましょう。

<?php
    /**
     * Template Name: ニュース 固定ページテンプレート
     */

    wp_head();
    get_header('');

    $paged = get_query_var('paged') ? get_query_var('paged') : 1;
    $wp_query = new WP_Query();
    $my_posts = array(
        'post_type' => array('info_post', 'news_post'),
        'posts_per_page' => '10',
        'paged' => $paged,
    );
    $wp_query->query($my_posts);
    if ($wp_query->have_posts()):
?>
<ul>
    <?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
    <li>
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
    </li>
    <?php endwhile;?>
</ul>
<?php 
    $linkElm = get_previous_posts_link('← 新しい投稿へ');
    if ($linkElm) {
        $linkElm = str_replace('<a', '<a class="is-next"', $linkElm);
        echo $linkElm;
    }
    $linkElm = get_next_posts_link('古い投稿へ →');
    if ($linkElm) {
        $linkElm = str_replace('<a', '<a class="is-prev"', $linkElm);
        echo $linkElm;
    }
    echo "</div>";
    endif;
    wp_reset_postdata();
?>

<?php
    get_footer();
    wp_footer();
<?php
    /**
     * Template Name: ニュース|共通 固定ページテンプレート
     */

    wp_head();
    get_header('');

    $paged = get_query_var('paged') ? get_query_var('paged') : 1;
    $wp_query = new WP_Query();
    $my_posts = array(
        'post_type' 'info_post',
        'posts_per_page' => '10',
        'paged' => $paged,
    );
    $wp_query->query($my_posts);
    if ($wp_query->have_posts()):
?>
<ul>
    <?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
    <li>
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
    </li>
    <?php endwhile;?>
</ul>
<?php 
    $linkElm = get_previous_posts_link('← 新しい投稿へ');
    if ($linkElm) {
        $linkElm = str_replace('<a', '<a class="is-next"', $linkElm);
        echo $linkElm;
    }
    $linkElm = get_next_posts_link('古い投稿へ →');
    if ($linkElm) {
        $linkElm = str_replace('<a', '<a class="is-prev"', $linkElm);
        echo $linkElm;
    }
    echo "</div>";
    endif;
    wp_reset_postdata();
?>

<?php
    get_footer();
    wp_footer();

テンプレートなので名前はお好みで大丈夫です。
仮にstatic-news-post.phpとstatic-info-post.phpと付けてthemes内に格納しておきます。

固定ページを作成し、テンプレートを適用する

次にWordPress管理画面から固定ページを作ります。
タイトルをテンプレートの様に付けても良いですし、自由に設定してください。
重要なのは、固定ページ作成画面中のテンプレートから先ほど作成したテンプレート名を指定することです。
また、合わせてパーマリンクの設定も変更してください。

右側ペインのテンプレート項目から作成したテンプレートを指定します。

上記の作業を繰り返し、2ページ分を作成してください。

info/news を作るにはまずinfoと命名したURLスラッグ固定ページを作成し、新しく追加する固定ページ内のページ属性の親ページから最初に作成したページを親ページ指定する事で親子関係を持ったページを作ることが出来ます。

確認してみる

上記の流れ通りに作成すると正しく2ページ目以降も表示されている事と思いますので、それぞれのページを確認し正しく表示出来ているかを確認してください。
(上記では個別投稿ページ用テンプレートは作成していないので、リンク先はindex.phpかsingle.phpで表示されます。)

なぜカスタム投稿アーカイブでは駄目なのか?🤔

納得できる理由が見当たらなかったのですが、恐らくカスタム投稿アーカイブはそもそも対象のカスタム投稿に対する一覧ですので、他の投稿タイプを持ってきても対象となるページ分のページネーションが機能しないものと思われます。(news_postのアーカイブはあくまでもnews_postであり、配列で指定したとしてもそれ以上にはならないため表示は出来るがページネーションは生成出来ない)

固定ページは特別な投稿タイプを持っているわけでは無いために、解説した複合的な投稿タイプを用いても正しく記事数を取得し、ページネーションを生成出来るのではないかと納得することにしました。

そもそも、クライアント希望やSEO的観点から狙ったURLにしたいという理由は分かるのですが、中途半端な知識を持ったディレクターが定義してしまうと無理矢理解決するしかないという場面が多い印象です。

WordPressはオブジェクト・ID、スラッグでいい感じにルーティングされていますが、正しく理解を深めることやドキュメントが少ない印象です。
もし他に良い方法あれば是非教えて欲しいと思っています🥺

タイトルとURLをコピーしました