WordPress

【WordPress】archive.phpだけで実装!カテゴリー絞り込み機能付きお知らせ一覧の作り方

WordPress でサイトを制作していると、「お知らせ」や「ブログ」などの一覧ページを実装する機会は非常に多いですよね。

さらに、「カテゴリーごとにお知らせを絞り込んで表示したい」という要望もよくあります。

HTML/CSS、JavaScript の学習を終えた方だと、「タブの切り替えは JavaScript を使うのかな?」と考えるかもしれません。もちろんそれも一つの方法ですが、WordPress ならではの PHP を使った実装なら、もっとスマートで効率的に実装できます。

この記事では、WordPress 初心者の方に向けて、archive.phpというテンプレートファイル1つだけで、カテゴリー絞り込み機能ページネーションを備えたお知らせ一覧を実装する方法を、コードを交えながら分かりやすく解説します。

home.phpcategory.php の2つのファイルを組み合わせる方法もありますが、archive.php 1つにまとめることで、コードの管理がしやすくなるというメリットがあります。
それでは、さっそく実装していきましょう。

1. 固定ページで「お知らせ一覧」ページを作成

まず、WordPress の管理画面から、お知らせ一覧を表示するための「器」となる固定ページを作成します。

  • 1.  管理画面 > 固定ページ > 新規追加 をクリック
  • 2.  タイトルに「お知らせ」や「NEWS」など、分かりやすい名前を入力
  • 3.  パーマリンク(URLスラッグ)を `news` や `archive` など、任意の名前に設定
  • 4.  コンテンツ部分は空のままでOKです。「公開」ボタンをクリックします。

2. テンプレートファイル archive.php の作成

次に、作成した固定ページに適用するための、オリジナルのテンプレートファイルを作成します。

お使いのテーマフォルダ直下に archive.php という名前で新規ファイルを作成し、以下のコードを記述してください。

<?php
/*
Template Name: お知らせ一覧
*/
?>
<?php get_header(); ?>

<!-- ここに HTML と PHP を記述していきます -->

<?php get_footer(); ?>

ファイルの冒頭に /* Template Name: お知らせ一覧 */ と記述することで、WordPress はこのファイルを「お知らせ一覧」という名前のテンプレートとして認識してくれます。

このファイルを保存したら、先ほど作成した固定ページの編集画面に戻り、右側の「ページ属性」>「テンプレート」から、今作成した「お知らせ一覧」を選択して更新してください。

これで、https://あなたのサイトURL/news/ にアクセスすると、archive.php の内容が表示されるようになりました。

3. カテゴリー絞り込みタブの実装 (PHP)

ここが今回の肝となる部分です。JavaScript を使わずに、PHP で動的なカテゴリータブを生成します。

なぜ JavaScript ではなく PHP なのか?

  •   **SEOに有利:** PHPでサーバーサイドでHTMLを生成するため、クローラーが各カテゴリーのページを正しく認識できます。
  •   **表示パフォーマンス:** ページアクセス時に完成したHTMLが返されるため、クライアントサイドでの処理が不要になり、表示が高速です。
  •   **WordPressとの親和性:** WordPressが提供する便利な関数(`get_categories`など)を最大限に活用できます。

archive.phpget_header() の下に、以下のコードを追加します。

<section class="p-archive" aria-label="お知らせ一覧ページ">
  <div class="p-archive__container">
    <div class="p-archive__header">
      <h1 class="p-archive__heading heading">お知らせ一覧</h1>
    </div>

    <!-- カテゴリータブナビゲーション -->
    <nav class="p-archive__tabs" role="tablist" aria-label="カテゴリーフィルター">
      <?php
      // 「すべて」タブ
      // 現在がカテゴリーページでなければ'--active'クラスを付与
      $all_tab_class = !is_category() ? 'p-archive__tab p-archive__tab--active' : 'p-archive__tab';
      echo '<a href="' . home_url("/news/") . '" class="' . $all_tab_class . '">すべて</a>';

      // カテゴリータブを動的に生成
      $categories = get_categories();
      foreach ($categories as $category) {
        // 現在表示しているページのカテゴリーと一致するかどうかを判定
        $is_current_category = is_category($category->term_id);
        $tab_class = $is_current_category ? 'p-archive__tab p-archive__tab--active' : 'p-archive__tab';
        
        echo '<a href="' . get_category_link($category->term_id) . '" class="' . $tab_class . '">' . esc_html($category->name) . '</a>';
      }
      ?>
    </nav>

コード解説

  •   !is_category(): WordPressの条件分岐タグで、「現在カテゴリーアーカイブページではない」場合に `true` を返します。これを利用して、「すべて」タブ(=お知らせ一覧のトップページ)にいるかどうかを判定しています。
  •   home_url("/news/"): お知らせ一覧ページのURLを返します。
  •   get_categories(): 投稿カテゴリーの情報を配列として取得します。
  •   foreach ($categories as $category): 取得したカテゴリーの数だけループ処理を行います。
  •   is_category($category->term_id): 現在表示しているページが、ループ中のカテゴリーのアーカイブページかどうかを判定します。
  •   get_category_link($category->term_id): 指定したIDのカテゴリーアーカイブページへのURLを返します。
  •   esc_html($category->name): カテゴリー名を出力します。`esc_html()`で安全に出力(エスケープ)するのが定石です。

これにより、カテゴリーが増減しても自動的にタブが生成され、現在表示しているカテゴリーのタブに p-archive__tab--active クラスが付与されるようになります。

4. 投稿一覧の表示 (WP_Query)

次に、選択されたカテゴリーに応じて投稿を表示するループ処理を記述します。WP_Query を使うことで、メインのクエリを汚さずに、安全に独自の投稿ループを作成できます。

先ほどの <nav> タグの後に、以下のコードを追加します。

    <!-- 投稿コンテンツ -->
    <div class="p-archive__content">
      <div class="p-archive__list">
        <?php
        // 現在のページ番号を取得
        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        
        // 表示するカテゴリーIDを条件分岐で設定
        $cat_id = is_category() ? get_query_var('cat') : 0;

        $args = array(
          'post_type' => 'post', // 投稿タイプ
          'paged' => $paged, // 表示するページ
          'posts_per_page' => 10, // 1ページあたりの投稿数
          'cat' => $cat_id, // カテゴリーID
        );
        $archive_query = new WP_Query($args);
        ?>

        <?php if ($archive_query->have_posts()) : ?>
          <?php while ($archive_query->have_posts()) : $archive_query->the_post(); ?>
            <article class="p-archive__post">
              <a href="<?php the_permalink(); ?>" class="p-archive__post-link">
                <!-- アイキャッチ画像 -->
                <figure class="p-archive__post-figure">
                  <?php if (has_post_thumbnail()) : ?>
                    <img src="<?php echo get_the_post_thumbnail_url(); ?>" alt="<?php the_title_attribute(); ?>">
                  <?php else : ?>
                    <img src="<?php echo get_template_directory_uri(); ?>/images/no-image.png" alt="画像なし">
                  <?php endif; ?>
                </figure>

                <!-- テキストコンテンツ -->
                <div class="p-archive__post-body">
                  <div class="p-archive__post-meta">
                    <time class="p-archive__post-date" datetime="<?php the_time('Y-m-d'); ?>">
                      <?php the_time('Y.m.d'); ?>
                    </time>
                    <?php
                    $cats = get_the_category();
                    foreach ($cats as $cat) {
                      echo '<span class="p-archive__post-category">' . esc_html($cat->name) . '</span>';
                    }
                    ?>
                  </div>
                  <h2 class="p-archive__post-title"><?php the_title(); ?></h2>
                </div>
              </a>
            </article>
          <?php endwhile; ?>
        <?php else : ?>
          <p class="p-archive__no-posts">投稿がありません。</p>
        <?php endif; ?>
        <?php wp_reset_postdata(); // クエリをリセット ?>
      </div>

コード解説

  •   $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;: ページネーションで何ページ目にいるかを取得します。
  •   $cat_id = is_category() ? get_query_var('cat') : 0;: ここがポイントです。もしカテゴリーアーカイブページなら、そのカテゴリーのID (get_query_var('cat')) を、そうでなければ 0 (すべてのカテゴリー) を $cat_id に代入します。
  •   $args: WP_Query に渡すパラメータの配列です。
  •   'cat' => $cat_id: この指定により、表示する投稿をカテゴリーで絞り込みます。
  •   new WP_Query($args): 上記のパラメータを使って、新しくデータベースに投稿情報を問い合わせます。
  •   if ($archive_query->have_posts()): 取得した投稿があるかチェックします。
  •   while ($archive_query->have_posts()) : $archive_query->the_post();: 投稿がある限りループします。
  •   the_permalink(), the_title() など: ループ内でおなじみのテンプレートタグを使い、投稿の情報を出力します。
  •   wp_reset_postdata(): WP_Query を使った後は、この関数で必ず投稿情報をリセットしましょう。

5. ページネーションの実装

最後に、投稿数が増えたときのためのページネーションを実装します。
先ほどの </div> の後に、以下のコードを追加します。

      <!-- ページネーション -->
      <nav class="p-archive__pagination" aria-label="ページネーション">
        <?php
        $big = 999999999;
        $paginate_links = 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, // WP_Queryオブジェクトの総ページ数を利用
          'prev_text' => '<',
          'next_text' => '>',
          'type' => 'array'
        ));

        if ($paginate_links) {
          echo '<ul class="p-archive__pagination-list">';
          foreach ($paginate_links as $link) {
            echo '<li class="p-archive__pagination-item">' . $link . '</li>';
          }
          echo '</ul>';
        }
        ?>
      </nav>
    </div><!-- /.p-archive__content -->
  </div><!-- /.p-archive__container -->
</section><!-- /.p-archive -->

<?php get_footer(); ?>

コード解説

  •   paginate_links(): WordPress に標準で備わっている、ページネーションのリンク群を生成してくれる便利な関数です。
  •   'total' => $archive_query->max_num_pages: WP_Queryオブジェクトが持つ総ページ数を total パラメータに渡すことで、正しいページ数のリンクが生成されます。
  •   'type' => 'array': リンクを配列として受け取り、foreach でループさせることで、<ul><li> タグで囲むなど、HTML構造を自由にカスタマイズできます。

まとめ

今回は、archive.php という1つのテンプレートファイルだけで、カテゴリー絞り込み機能とページネーションを備えたお知らせ一覧を実装する方法を解説しました。

ポイントは以下の通りです。

  •   **URLで状態を管理:** タブの切り替えは、カテゴリーアーカイブページのURLにアクセスさせることで実現する。
  •   **PHPで動的に出し分け:** is_category() などの条件分岐タグを使い、表示されているページに応じてPHPが動的にコンテンツを出し分ける。
  •   **WP_Queryの活用:** メインクエリとは別にサブクエリを発行し、柔軟な投稿取得を行う。

JavaScript でタブを切り替える UI を作ることに慣れていると、少し不思議な感覚かもしれませんが、この「URLとPHPで状態を管理する」考え方は、WordPress のテンプレート階層を理解する上で非常に重要です。

ぜひこの機会にマスターして、様々な実装に応用してみてください。

✉️ あなたのリクエスト教えてください!

「この記事わかりやすかった!」
「他にもこんな記事書いてほしい!」
そんな声を、ぜひXのDMで教えてください!😊📩

できるだけリクエストにお応えして、今後の記事作成に活かしていきます

▶️ X@TumaLOVE0127もフォローしてもらえるとめちゃくちゃ嬉しいです!

hisa

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA