2026年5月20日

2026年5月20日

WordPressのカスタム投稿タイプのアーカイブページを作る方法

はじめに

カスタム投稿タイプの一覧ページ(アーカイブ)を正しく表示するには、register_post_typehas_archive オプションを有効にし、テーマに archive-{post-type}.php テンプレートを作成する必要があります。

症状・原因

  • カスタム投稿タイプのアーカイブURLが404になる
  • アーカイブページに間違ったテンプレートが使われている
  • 表示件数やソート順を変更したい
  • ページネーションが機能しない

解決手順

ステップ1:has_archiveを有効にする

// functions.php
function mytheme_register_news_post_type(): void {
    register_post_type('news', [
        'labels' => [
            'name'               => 'ニュース',
            'singular_name'      => 'ニュース',
            'add_new_item'       => 'ニュースを追加',
            'edit_item'          => 'ニュースを編集',
            'all_items'          => 'ニュース一覧',
            'view_item'          => 'ニュースを表示',
            'search_items'       => 'ニュースを検索',
        ],
        'public'      => true,
        'has_archive' => true,             // アーカイブURLを有効化
        'rewrite'     => [
            'slug' => 'news',              // /news/ でアーカイブ
            'with_front' => false,
        ],
        'supports'    => ['title', 'editor', 'thumbnail', 'excerpt'],
        'show_in_rest' => true,            // ブロックエディター対応
        'menu_icon'   => 'dashicons-megaphone',
    ]);
}
add_action('init', 'mytheme_register_news_post_type');

has_archive を変更したら、設定→パーマリンク設定で「変更を保存」を一度クリックしてパーマリンクをフラッシュします。

ステップ2:アーカイブテンプレートを作成する

// archive-news.php
get_header();
?>
<main id="main" class="site-main">
    <header class="page-header">
        <h1 class="page-title"><?php post_type_archive_title(); ?></h1>
        <?php
        $description = get_the_archive_description();
        if ($description) {
            echo '<div class="archive-description">' . wp_kses_post($description) . '</div>';
        }
        ?>
    </header>

    <?php if (have_posts()) : ?>
        <div class="news-grid">
            <?php while (have_posts()) : the_post(); ?>
                <?php get_template_part('template-parts/card', 'news'); ?>
            <?php endwhile; ?>
        </div>

        <?php the_posts_pagination([
            'prev_text' => '&laquo; 前のページ',
            'next_text' => '次のページ &raquo;',
        ]); ?>

    <?php else : ?>
        <p>ニュースはまだありません。</p>
    <?php endif; ?>
</main>
<?php
get_sidebar();
get_footer();

ステップ3:表示件数とソート順をカスタマイズする

// functions.php
function mytheme_news_archive_query(WP_Query $query): void {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    if ($query->is_post_type_archive('news')) {
        $query->set('posts_per_page', 12);
        $query->set('orderby', 'date');
        $query->set('order', 'DESC');

        // 特定のカテゴリを除外(カスタムタクソノミーがある場合)
        // $query->set('tax_query', [...]);
    }
}
add_action('pre_get_posts', 'mytheme_news_archive_query');

ステップ4:アーカイブページタイトルをカスタマイズする

// functions.php
function mytheme_archive_title(string $title): string {
    if (is_post_type_archive()) {
        $post_type_obj = get_queried_object();
        return $post_type_obj->labels->name ?? $title;
    }
    return $title;
}
add_filter('get_the_archive_title', 'mytheme_archive_title');

// アーカイブページにディスクリプションを追加
function mytheme_news_archive_description(): void {
    if (is_post_type_archive('news')) {
        echo '<p class="archive-intro">最新のニュースをお届けします。</p>';
    }
}
add_action('wp', 'mytheme_news_archive_description');

ステップ5:テンプレート階層を理解する

WordPressのテンプレート読み込み優先順(カスタム投稿タイプ「news」の場合):

1. archive-news.php ← 最優先

2. archive.php

3. index.php

// archive.php でまとめて処理する場合
get_header();
$post_type = get_post_type();
?>
<main>
    <?php if (is_post_type_archive('news')) : ?>
        <h1>ニュース一覧</h1>
    <?php elseif (is_post_type_archive('event')) : ?>
        <h1>イベント一覧</h1>
    <?php else : ?>
        <h1><?php the_archive_title(); ?></h1>
    <?php endif; ?>

    <?php while (have_posts()) : the_post(); ?>
        <?php get_template_part('template-parts/card', $post_type); ?>
    <?php endwhile; ?>

    <?php the_posts_pagination(); ?>
</main>
<?php get_footer();

注意事項

  • has_archive を後から true に変更した場合は、必ずパーマリンク設定を再保存してリライトルールを更新してください
  • アーカイブページのSEOには post_type_archive_title()get_the_archive_description() を使い、メタタグにも反映させてください
  • カスタム投稿タイプに publicly_queryable => false が設定されているとアーカイブは表示されません

まとめ

register_post_typehas_archive: true を設定し、パーマリンクをフラッシュ後、テーマに archive-{post-type}.php を作成します。表示件数・ソート順は pre_get_posts で制御し、the_posts_pagination() でページネーションを追加します。

お気軽にご相談ください

お見積りへ お問い合わせへ