【WordPress】タブ切り替えでカテゴリ別の新着記事を表示する方法|HTML・CSS・PHP・JavaScript

【WordPress】タブ切り替えを利用したカテゴリ別新着記事の表示方法 WordPress

カテゴリごとの新着記事をタブで切り替えて表示すると、訪問者は興味のあるカテゴリの最新記事をすぐに見つけられ、回遊性が上がります。この記事では、HTML・CSS・PHP・JavaScriptを組み合わせてタブ切り替えのカテゴリ別新着記事を実装する方法を、つまずきやすい注意点とともに解説します。

実装の流れ

  • HTML:タブのボタンとコンテンツの枠を作る
  • CSS:タブの見た目を整える
  • PHP:カテゴリごとの新着記事を取得して表示する
  • JavaScript:クリックでタブを切り替える
スポンサーリンク

1. タブのHTMLを作る

タブのボタンと、各カテゴリのコンテンツを入れる枠を用意します。最初のタブを初期表示するため、1つ目のボタンに active クラス、1つ目のコンテンツに style="display:block;" を付けておきます。

HTML:タブの構造(1つ目を初期表示)
<div class="tab">
  <button class="tablinks active" onclick="changeTab(event, 'category1')">カテゴリ1</button>
  <button class="tablinks" onclick="changeTab(event, 'category2')">カテゴリ2</button>
  <!-- 必要に応じてタブを追加 -->
</div>

<div id="category1" class="tabcontent" style="display:block;">
  <!-- ここに記事が入る -->
</div>

<div id="category2" class="tabcontent">
  <!-- ここに記事が入る -->
</div>

2. CSSでタブを整える

タブの見た目を整えます。非アクティブなコンテンツは display:none で隠します。

CSS:タブのスタイル
/* タブ全体 */
.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

/* タブのボタン */
.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
}

/* ホバー時 */
.tab button:hover { background-color: #ddd; }

/* アクティブなタブ */
.tab button.active { background-color: #ccc; }

/* タブのコンテンツ(初期は非表示) */
.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}

3. PHPでカテゴリ別の新着記事を取得する

カテゴリIDを渡すと、そのカテゴリの新着記事を表示する関数を作ります。functions.php に追加してください。

global $post を忘れない
foreach でループする際は、関数の先頭で global $post; を宣言します。これが無いと foreach ($posts as $post)ローカル変数になり、the_title()the_permalink() が読むグローバルの $post が更新されず、記事のタイトルやリンクが正しく表示されません。ループ後は wp_reset_postdata() で元に戻します。ループの仕組みはメインループで記事を表示する方法も参考になります。
functions.php:カテゴリ別の新着記事を表示する関数
<?php
function get_latest_posts_by_category($category_id, $num_posts = 5) {
  global $post; // テンプレートタグを正しく動かすために必須

  $latest_posts = get_posts(array(
    'numberposts' => $num_posts,
    'category'    => $category_id,
    'orderby'     => 'date',
    'order'       => 'DESC',
  ));

  if ($latest_posts) {
    foreach ($latest_posts as $post) {
      setup_postdata($post); ?>
      <div class="post-summary">
        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
        <p><?php the_excerpt(); ?></p>
      </div>
    <?php }
    wp_reset_postdata(); // グローバル $post を元に戻す
  } else {
    echo '<p>記事がありません。</p>';
  }
}
?>

作った関数を、各カテゴリの tabcontent の中で呼び出します(数字は対象のカテゴリID)。

各タブの中で関数を呼び出す
<div id="category1" class="tabcontent" style="display:block;">
  <?php get_latest_posts_by_category(1); ?>
</div>

<div id="category2" class="tabcontent">
  <?php get_latest_posts_by_category(2); ?>
</div>

4. JavaScriptでタブを切り替える

ボタンがクリックされたら、対象のコンテンツだけを表示する changeTab 関数を用意します。

JavaScript:タブ切り替え
function changeTab(evt, categoryName) {
  // すべてのコンテンツを隠す
  var tabcontent = document.getElementsByClassName("tabcontent");
  for (var i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }

  // すべてのボタンから active を外す
  var tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }

  // 選ばれたタブを表示し、ボタンに active を付ける
  document.getElementById(categoryName).style.display = "block";
  evt.currentTarget.className += " active";
}
クリック時に毎回読み込みたい場合(Ajax)
上記はページ表示時に全カテゴリの記事を読み込んでおき、表示を切り替える方式です。タブを開いたときにその都度サーバーから記事を取得したい場合は、Ajaxを使います。実装はAjaxを使ってカテゴリーごとの記事一覧をリアルタイムで切り替える方法で詳しく解説しています。取得条件を細かくしたい場合はWP_Queryで複雑な条件検索を実装する方法も参考になります。

よくある質問(FAQ)

Qタブ切り替えはjQueryなしでもできますか?
Aできます。この記事のように素のJavaScriptで実装できますし、ラジオボタンや <details> 要素を使えばCSSとHTMLだけでも作れます。既存プロジェクトでjQueryを使っているなら show() / hide() でも手軽です。
Qタブを開いたときに記事を読み込む(Ajax)には?
Aadmin-ajax.phpREST API を使います。タブのクリックで fetch("/wp-json/wp/v2/posts?categories=5") のようにカテゴリIDを渡し、返ってきたデータでコンテンツを差し替えます。具体的な実装はAjaxでカテゴリー別記事を切り替える方法を参照してください。
Q非表示タブのコンテンツはSEO的に大丈夫ですか?
A初期HTMLに含まれていれば、display:none のタブの内容もGoogleは認識します。ただしAjaxで後から読み込むコンテンツは初期HTMLに無いためインデックスされにくくなります。重要な記事は最初から表示しておくか、初期HTMLに含める実装にしましょう。

まとめ

  • HTML:タブのボタンとコンテンツ枠(1つ目を activedisplay:block
  • CSS.tabcontentdisplay:none で隠す
  • PHPglobal $post; を宣言してから get_postssetup_postdatawp_reset_postdata
  • JavaScript:クリックで対象タブだけ表示
  • 都度読み込み:必要ならAjax化(初期表示分はSEOに配慮)

global $post; の宣言と最初のタブの初期表示の2点を押さえれば、正しく動くタブ切り替えが作れます。