2026年5月20日
2026年5月20日
WordPressのカスタム投稿タイプのアーカイブページを作る方法
はじめに
カスタム投稿タイプの一覧ページ(アーカイブ)を正しく表示するには、register_post_type の has_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' => '« 前のページ',
'next_text' => '次のページ »',
]); ?>
<?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_type で has_archive: true を設定し、パーマリンクをフラッシュ後、テーマに archive-{post-type}.php を作成します。表示件数・ソート順は pre_get_posts で制御し、the_posts_pagination() でページネーションを追加します。