register_post_type_args:デフォルトのWordPress投稿(post)の一覧ページを表示する

WordPressのデフォルト投稿であるpostに一覧ページを表示する方法について。

今回のWordPressサイト構築の仕様

  • サイトトップページは一覧形式ではなく、オリジナルコンテンツ
  • 投稿のパーマリンクは/blog/%post_id%/

という場合に、アーカイブ一覧がなくなっていしまうので、カスタム投稿のhas_archiveのように一覧ページを設定したい。

以前は固定ページにblogというスラッグをつけていましたが、
WordPress4.4以降ではfunctions.phpにいけるらしい。

function post_has_archive( $args, $post_type ) {
    if ( 'post' == $post_type ) {
        $args['rewrite'] = true;
        $args['has_archive'] = 'blog'; // ページ名
    } 
    return $args;
}
add_filter( 'register_post_type_args', 'post_has_archive', 10, 2 );

しかし、やってみたところ投稿詳細のパーマリンクに『/blog/%post_id%/』と設定している場合は、『$args[‘has_archive’] = ‘blog’』という指定だとうまくいかない。

調べていたところ海外のこちらの記事でベストな方法が紹介されていました。

functions.phpに以下を追加

『$archive_slug = ‘blog’;』の部分にすきな文字列を定義すれば、ページ送りもきちんと効く一覧ページが出来上がります。

<?php
add_filter( 'register_post_type_args', function( $args, $post_type ) {
    global $wp_rewrite;
    if ( 'post' === $post_type ) {
        $archive_slug = 'blog';
        // Setting 'has_archive' ensures get_post_type_archive_template() returns an archive.php template.
        $args['has_archive'] = $archive_slug;
        // We have to register rewrite rules, because WordPress won't do it for us unless $args['rewrite'] is true.
        $archive_slug = $wp_rewrite->root . $archive_slug;
        add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' );
        $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')';
        add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
        add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
        add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' );
    }
    return $args;
}, 10, 2 );

SNSでもご購読できます。