archive.phpとは、WordPressのテンプレート階層においてカテゴリ・タグ・日付・著者などのアーカイブページを一括で制御するテンプレートファイルです。テーマ開発では、このファイル1つで複数種類の一覧ページをまとめて管理でき、functions.phpと連携することで表示件数の変更やカスタム投稿タイプのアーカイブ有効化なども行えます。
この記事では、archive.phpの基本的な書き方からfunctions.phpとの連携、実践的なカスタマイズ方法までを解説します。WordPressテーマのテンプレートファイル一覧と役割と合わせて読むことで、テンプレート階層の理解が深まります。
archive.phpとは?テンプレート階層での役割
WordPressには「テンプレート階層」という仕組みがあり、表示するページの種類に応じて使用するテンプレートファイルが決まります。archive.phpは、この階層の中でアーカイブ系ページの汎用テンプレートとして機能します。
具体的には、以下のページがarchive.phpの対象です。
- カテゴリーページ(例:
/category/wordpress/) - タグページ(例:
/tag/php/) - 日付アーカイブ(例:
/2026/05/) - 著者ページ(例:
/author/admin/) - カスタム投稿タイプのアーカイブ(例:
/works/) - カスタムタクソノミーのアーカイブ
テンプレートの優先順位(フォールバック)
テンプレート階層では、より具体的なファイルが優先されます。例えばカテゴリーページでは以下の順で探索されます。
| 優先順位 | ファイル名 | 説明 |
|---|---|---|
| 1(最優先) | category-{slug}.php | 特定カテゴリ専用(スラッグ指定) |
| 2 | category-{id}.php | 特定カテゴリ専用(ID指定) |
| 3 | category.php | カテゴリ全般 |
| 4 | archive.php | アーカイブ全般(フォールバック先) |
| 5 | index.php | 最終フォールバック |
つまり、category.phpやtag.phpがなくても、archive.phpさえあればアーカイブ系ページは全て表示できます。逆に、特定の種類だけデザインを変えたい場合はcategory.phpやtag.phpを個別に作成します。
archive.phpの基本的な書き方
最もシンプルなarchive.phpの構成は以下の通りです。WordPressループを使って投稿を一覧表示します。
<?php get_header(); ?>
<main class="site-main">
<header class="archive-header">
<h1><?php the_archive_title(); ?></h1>
<?php the_archive_description( '<div class="archive-description">', '</div>' ); ?>
</header>
<div class="post-list">
<?php if ( have_posts() ) : ?>
<?php while ( have_posts() ) : the_post(); ?>
<article class="post-card">
<?php if ( has_post_thumbnail() ) : ?>
<div class="post-thumbnail">
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail( 'medium' ); ?>
</a>
</div>
<?php endif; ?>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<div class="post-excerpt">
<?php the_excerpt(); ?>
</div>
</article>
<?php endwhile; ?>
<?php else : ?>
<p>記事が見つかりませんでした。</p>
<?php endif; ?>
</div>
<?php the_posts_pagination(); ?>
</main>
<?php get_sidebar(); ?>
<?php get_footer(); ?>主要な関数の解説
| 関数 | 役割 |
|---|---|
the_archive_title() | アーカイブの種類に応じたタイトルを自動出力(例: 「カテゴリー: WordPress」) |
the_archive_description() | カテゴリ・タグの説明文を出力 |
have_posts() / the_post() | WordPressループ(メインクエリの投稿を順に処理) |
the_posts_pagination() | ページネーション(ページ送り)を出力 |
get_template_part() | パーツテンプレートを読み込み(コードの再利用に有効) |
the_archive_title()は自動で「カテゴリー:」「タグ:」といった接頭辞を付けます。この接頭辞を除去するカスタマイズ方法は後述します。
functions.phpでarchive.phpを活用する設定
archive.phpの表示内容はfunctions.phpから柔軟にコントロールできます。ここでは、実務で頻繁に使う設定を紹介します。
アーカイブページの表示件数を変更する(pre_get_posts)
WordPressのデフォルトではアーカイブの表示件数は「設定 → 表示設定」の値(初期値10件)が使われます。pre_get_postsフックを使えば、テンプレートを変更せずに表示件数をコントロールできます。
function custom_archive_posts_per_page( $query ) {
// 管理画面は除外 & メインクエリのみ対象
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// アーカイブページの表示件数を20件に変更
if ( $query->is_archive() ) {
$query->set( 'posts_per_page', 20 );
}
}
add_action( 'pre_get_posts', 'custom_archive_posts_per_page' );注意点: is_admin()とis_main_query()のチェックは必須です。これを省略すると、管理画面やサブクエリまで影響を受けてしまいます。
カスタム投稿タイプのアーカイブを有効化する
カスタム投稿タイプをarchive.phpで一覧表示するには、register_post_type()でhas_archiveをtrueに設定します。
function register_works_post_type() {
register_post_type( 'works', array(
'labels' => array(
'name' => '実績',
'singular_name' => '実績',
),
'public' => true,
'has_archive' => true, // /works/ でアーカイブページが有効になる
'rewrite' => array( 'slug' => 'works' ),
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
'show_in_rest' => true, // ブロックエディタ対応
) );
}
add_action( 'init', 'register_works_post_type' );has_archive => trueを設定すると、/works/というURLでアーカイブページが自動的に生成されます。テンプレートの優先順位はarchive-works.php → archive.php → index.phpです。
登録後にパーマリンクが404になる場合は、「設定 → パーマリンク」で「変更を保存」をクリックしてリライトルールを再生成してください。
the_archive_title()の接頭辞を除去する
デフォルトのthe_archive_title()は「カテゴリー: WordPress」のように接頭辞が付きます。これを除去するにはget_the_archive_titleフィルターを使います。
function remove_archive_title_prefix( $title ) {
if ( is_category() ) {
$title = single_cat_title( '', false );
} elseif ( is_tag() ) {
$title = single_tag_title( '', false );
} elseif ( is_post_type_archive() ) {
$title = post_type_archive_title( '', false );
} elseif ( is_date() ) {
$title = get_the_date( 'Y年n月' );
} elseif ( is_author() ) {
$title = get_the_author();
}
return $title;
}
add_filter( 'get_the_archive_title', 'remove_archive_title_prefix' );archive.phpのカスタマイズ例
基本形をベースに、実務で使えるカスタマイズパターンを紹介します。
条件分岐でアーカイブの種類ごとに表示を変える
1つのarchive.phpで、カテゴリ・タグ・日付など種類ごとに見出しや説明文を出し分けることができます。
<?php
// 見出しと説明文の決定
$heading = '記事一覧';
$desc = '';
if ( is_category() || is_tag() || is_tax() ) {
$term = get_queried_object();
$heading = $term->name;
$desc = term_description( $term->term_id, $term->taxonomy );
} elseif ( is_date() ) {
if ( is_year() ) {
$heading = get_the_date( 'Y年' ) . 'の記事一覧';
} elseif ( is_month() ) {
$heading = get_the_date( 'Y年n月' ) . 'の記事一覧';
} elseif ( is_day() ) {
$heading = get_the_date( 'Y年n月j日' ) . 'の記事一覧';
}
} elseif ( is_author() ) {
$author = get_queried_object();
$heading = $author->display_name . ' の記事一覧';
} elseif ( is_post_type_archive() ) {
$heading = post_type_archive_title( '', false );
}
?>
<h1><?php echo esc_html( $heading ); ?></h1>
<?php if ( ! empty( $desc ) ) : ?>
<div class="archive-description"><?php echo $desc; ?></div>
<?php endif; ?>この方法ならthe_archive_title()のフィルターに頼らず、自分で見出しを完全にコントロールできます。
WP_Queryでカスタムクエリを使う
メインクエリではなくWP_Queryを使うことで、並び順や表示件数をテンプレート側で自由に制御できます。
<?php
$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 20,
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
);
// カテゴリ・タグ・タクソノミーの場合、tax_queryを追加
if ( is_category() || is_tag() || is_tax() ) {
$term = get_queried_object();
$args['tax_query'] = array(
array(
'taxonomy' => $term->taxonomy,
'field' => 'term_id',
'terms' => $term->term_id,
),
);
}
// 日付アーカイブの場合、年・月・日を追加
if ( is_date() ) {
if ( is_year() ) {
$args['year'] = get_query_var( 'year' );
} elseif ( is_month() ) {
$args['year'] = get_query_var( 'year' );
$args['monthnum'] = get_query_var( 'monthnum' );
}
}
$archive_query = new WP_Query( $args );
?>WP_Queryを使う場合の注意点: ループ終了後にwp_reset_postdata()を必ず呼び出してください。これを忘れると、サイドバーやフッターのグローバル$postが狂います。
<?php if ( $archive_query->have_posts() ) : ?>
<?php while ( $archive_query->have_posts() ) : $archive_query->the_post(); ?>
<!-- 記事カード -->
<?php endwhile; ?>
<?php endif; ?>
<?php
// 必ずリセットする
wp_reset_postdata();
?>ページネーションを実装する
メインクエリを使う場合はthe_posts_pagination()で簡単に実装できます。WP_Queryを使う場合はpaginate_links()を使います。
<?php
// メインクエリの場合(簡単)
the_posts_pagination( array(
'prev_text' => '« 前へ',
'next_text' => '次へ »',
'mid_size' => 2,
) );
?><?php
// WP_Queryの場合
$big = 999999999;
echo paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, $paged ),
'total' => $archive_query->max_num_pages,
'prev_text' => '« 前へ',
'next_text' => '次へ »',
'end_size' => 2,
'mid_size' => 2,
) );
?>category.phpやtag.phpとの使い分け(DRY設計)
テンプレート階層を活用した設計パターンは大きく2つあります。
| 設計パターン | メリット | デメリット | 向いているケース |
|---|---|---|---|
| archive.php統一型 | 1ファイルで管理。修正が1箇所で済む | 条件分岐が増えると複雑になる | カテゴリ・タグのデザインが同じ場合 |
| 個別テンプレート分離型 | 種類ごとに独立。見通しが良い | 共通部分の重複が発生する | 種類ごとにレイアウトが大きく異なる場合 |
実務でおすすめなのは「archive.phpに統一し、category.phpやtag.phpからincludeで読み込む」というハイブリッドな方法です。
<?php
// category.php(たった1行)
include get_template_directory() . '/archive.php';
?><?php
// tag.php(同じく1行)
include get_template_directory() . '/archive.php';
?>この方法なら、WordPressのテンプレート階層を活かしつつ(category.phpやtag.phpが存在することで階層のフォールバックが正しく機能する)、実装は1箇所(archive.php)に集約できます。将来カテゴリだけ別デザインにしたくなった場合も、category.phpの中身を書き換えるだけで済みます。
テンプレートパーツで記事カードを共通化する
archive.phpのループ内で直接HTMLを書くと、同じカードデザインをsearch.phpやindex.phpでも使いたいときにコピペが必要になります。get_template_part()でパーツテンプレートとして切り出しましょう。
<!-- template-parts/card-post.php -->
<?php
$link = get_permalink();
$title = get_the_title();
?>
<article class="post-card">
<a href="<?php echo esc_url( $link ); ?>">
<?php if ( has_post_thumbnail() ) : ?>
<div class="post-thumbnail">
<?php the_post_thumbnail( 'medium', array(
'alt' => esc_attr( $title ),
'loading' => 'lazy',
) ); ?>
</div>
<?php endif; ?>
<h2 class="post-title"><?php echo esc_html( $title ); ?></h2>
<div class="post-excerpt"><?php the_excerpt(); ?></div>
</a>
</article>archive.php側では以下のように呼び出します。
<?php while ( have_posts() ) : the_post(); ?>
<?php get_template_part( 'template-parts/card', 'post' ); ?>
<?php endwhile; ?>WordPress 5.5以降ではget_template_part()の第3引数でデータを渡すこともできます。
// データを渡す
get_template_part( 'template-parts/card', 'post', array(
'show_date' => true,
'image_size' => 'large',
) );
// card-post.php 側で受け取る
$show_date = $args['show_date'] ?? false;
$image_size = $args['image_size'] ?? 'medium';よくある質問(FAQ)
Q. archive.phpを作ったのにアーカイブページが表示されないのはなぜ?
パーマリンク設定が「基本」になっている場合、カテゴリやタグのURLが正しく生成されないことがあります。「設定 → パーマリンク」で「投稿名」などを選択し、「変更を保存」をクリックしてリライトルールを更新してください。
Q. archive.phpとhome.phpの違いは?
home.phpはブログ投稿一覧(フロントページまたは投稿ページ)専用のテンプレートです。archive.phpはカテゴリ・タグ・日付・著者のアーカイブ用で、ブログのトップページには使われません。「設定 → 表示設定」で投稿ページを指定した場合はhome.phpが優先されます。
Q. archive.phpとindex.phpの違いは?
index.phpはWordPressテーマで唯一必須のテンプレートファイルで、他の全テンプレートの最終フォールバック先です。archive.phpが存在しない場合、アーカイブページはindex.phpで表示されます。index.phpよりarchive.phpの方がアーカイブ用に最適化した表示を行えるため、テーマ開発では基本的にarchive.phpを作成します。
Q. pre_get_postsとWP_Queryはどちらを使うべき?
メインクエリの条件を変更するだけならpre_get_postsが推奨されます。クエリが1回で済むためパフォーマンスが良く、the_posts_pagination()もそのまま使えます。メインクエリとは別の条件で投稿を取得したい場合や、複数のループが必要な場合はWP_Queryを使います。
Q. functions.phpに書く内容はテーマファイルとプラグインのどちらに入れるべき?
表示に関する設定(pre_get_postsでの件数変更、archive_titleの接頭辞除去など)はテーマのfunctions.phpが適切です。一方、カスタム投稿タイプやタクソノミーの登録はテーマを変更しても維持したい機能なので、プラグインとして独立させるのが理想です。
まとめ
archive.phpは、WordPressテーマ開発においてアーカイブ系ページを一元管理するための重要なテンプレートファイルです。
- テンプレート階層を理解する — archive.phpはカテゴリ・タグ・日付・著者ページのフォールバック先
- functions.phpと連携する — pre_get_postsで表示件数を変更、has_archiveでカスタム投稿タイプのアーカイブを有効化
- 条件分岐で出し分ける — is_category()やis_date()を活用して1ファイルで複数種類のアーカイブに対応
- DRY設計を心がける — category.phpからarchive.phpをincludeするハイブリッド型がおすすめ
- テンプレートパーツで共通化 — get_template_part()で記事カードを使い回す
テンプレート階層の全体像や他のテンプレートファイルについては、WordPressテーマのテンプレート一覧と役割ガイドも参考にしてください。
テンプレートファイルの使い方をさらに深掘りしたい方は、single.phpの使い方とカスタマイズやheader.phpとfooter.phpの作り方、WordPressループの仕組みも合わせてご覧ください。
