WPで投稿一覧の表示方法(カテゴリ別表示もあり)

2024.08.17

WordPress案件では必ず使う機能。この記事では投稿一覧表示のコードをメモしていきます。

私は投稿一覧は下記のような条件で実装しています。
・カスタム投稿タイプ(プラグイン 「CPT UI」で設定)
・テンプレートファイルは「archive.php」、「taxnomy.php」を使用
・ページネーションプラグイン「wp-pageNavi」を使用

私は投稿一覧はカスタム投稿タイプから実装しています。その理由はデフォルト投稿とカスタム投稿ではカテゴリーの呼び出しなどで使うWP関数が異なるためです。異なる関数を使うのも覚えるのも大変なため投稿機能を使う際はカスタム投稿で統一しています。
今回もカスタム投稿タイプを使った説明となります。

一覧を表示するWPテンプレートファイルはarchive.php、カテゴリー分けの投稿一覧テンプレートは「taxonomy.php」を使用します。投稿一覧ごとにデザインが異なる場合は「archive-news.php」「archive-blog.php」などそれぞれカスタム投稿タイプを別で作り使い分けています。これは投稿一覧のテンプレートを使った方が投稿タイプスラッグなどのデータ取得が簡単なためです。また「archive.php」「taxnomy.php」となってる方がファイルの用途がわかりやすいですしね。

投稿一覧表示(archive.php)

下記サンプルのコードではカスタム投稿タイプ「news」を9件表示するループ文です。変数$argsで呼び出す条件を配列で格納し、WP_Queryを呼び出す条件に使っています。これが投稿一覧を表示する際の私が使っているコードです。

<ul class="lt">
<?php
   $args = array(
   'post_type' => array('news'),
   'posts_per_page' => 9,
   'paged' => $paged,
   );
   $the_query_news =  new WP_Query($args);
?>
<?php if ( $the_query_news->have_posts() ) : ?>
 <?php while ($the_query_news->have_posts()) : $the_query_news->the_post(); ?>
  <li <?php the_ID(); ?>>
   <a href="<?php the_permalink(); ?>">
     <h3><?php the_title(); ?></h3>
     <div class="date"><?php the_time('Y.m.d'); ?></div>
     <?php if (has_post_thumbnail()) : ?>
      <?php the_post_thumbnail('full'); ?>
     <?php else : ?>
      <img src="<?php bloginfo('template_url'); ?>/assets/images/common/sample.jpg" alt="" />
     <?php endif ; ?>
     <?php if ($terms = get_the_terms($post->ID, 'cat_news')) : ?>
      <div class="catArea">
       <?php foreach( $terms as $term ) : ?>
        <div class="cat"><span><?php echo esc_html($term->name); ?></span></div>
       <?php endforeach; ?>
      </div>
     <?php endif ; ?>
   </a>
  </li>
 <?php endwhile; ?>
<?php endif; wp_reset_postdata(); ?>
<?php if( function_exists( 'wp_pagenavi' )) { wp_pagenavi();} ?>
</ul>

リストタグ内には、記事タイトルやサムネイル画像や日付など主に使うと思われるWP関数を記載しています。

aタグでは記事ページのパーマリンクを呼び出しです。画像はWp管理画面で設定した画像を表示。画像の指定がなければデフォルトの画像を表示します。その他は管理画面で設定した「投稿タイトル」や「日付」を表示しています。

投稿記事のカテゴリー表示

カテゴリの表示はプラグインCPT UIを使い管理画面「タクソノミーの追加と編集」で設定したものを表示します。

「CPT UI」の画面

管理画面で記事にカテゴリーが設定されていれば、foreachで全て表示するコードになっています。

     <?php if ($terms = get_the_terms($post->ID, 'cat_news')) : ?>
      <div class="catArea">
       <?php foreach( $terms as $term ) : ?>
        <div class="cat"><span><?php echo esc_html($term->name); ?></span></div>
       <?php endforeach; ?>
      </div>
     <?php endif ; ?>

ページネーション

コードの最後ではプラグインWp-PageNaviを呼び出すコードです。

<?php endif; wp_reset_postdata(); ?>
<?php if( function_exists( 'wp_pagenavi' )) { wp_pagenavi();} ?>

投稿一覧表示-カテゴリ別(taxnomy.php)

次はtaxnomy.phpはカテゴリ(ターム)ごとに表示するためのテンプレートです。
コードの内容はarchive.phpとほぼ同じですが、異なる部分があります。まずはコードから。

<ul class="lt">
<?php
   $term_object = get_queried_object(); // 現在クエリされているオブジェクトを取得
   $term_slug   = $term_object->slug; // タームスラッグ
   $args = array(
   'post_type' => array('news'),
   'taxonomy' => 'cat_news',
   'term' => $term_slug,
   'posts_per_page' => 9,
   'paged' => $paged,
   );
   $the_query_news =  new WP_Query($args);
?>
<?php if ( $the_query_news->have_posts() ) : ?>
 <?php while ($the_query_news->have_posts()) : $the_query_news->the_post(); ?>
  <li <?php the_ID(); ?>>
   <a href="<?php the_permalink(); ?>">
     <h3><?php the_title(); ?></h3>
     <div class="date"><?php the_time('Y.m.d'); ?></div>
     <?php if (has_post_thumbnail()) : ?>
      <?php the_post_thumbnail('full'); ?>
     <?php else : ?>
      <img src="<?php bloginfo('template_url'); ?>/assets/images/common/sample.jpg" alt="" />
     <?php endif ; ?>
     <?php if ($terms = get_the_terms($post->ID, 'cat_news')) : ?>
      <div class="catArea">
       <?php foreach( $terms as $term ) : ?>
        <div class="cat"><span><?php echo esc_html($term->name); ?></span></div>
       <?php endforeach; ?>
      </div>
     <?php endif ; ?>
   </a>
  </li>
 <?php endwhile; ?>
<?php endif; wp_reset_postdata(); ?>
<?php if( function_exists( 'wp_pagenavi' ))
  { wp_pagenavi( array('query'=>$the_query_news ) );} //← array('query'=>$the_query_news ) この記述がないとpagenaviが一つ目以上が表示されない
?>
</ul>

リストタグの中はarchive.phpと同じです。異なるのは最初の記事を呼び出し指定とpageNaviの記述です。

pageNaviの記述

まずはpageNaviから。

<?php if( function_exists( 'wp_pagenavi' ))
  { wp_pagenavi( array('query'=>$the_query_news ) );} //← array('query'=>$the_query_news ) この記述がないとpagenaviが一つ目以上が表示されない
?>

ここがarchive.phpと異なります。wp_pagenavi()の関数の引数で「array(‘query’=>$the_query_news )」とクエリを具体的に指定しています。これは明示的にどのクエリを使うか指定しないと1ページ目以降の表示がうまく行かないために使っています。

記事の呼び出しについて

さて、それではtaxnomy.phpのコアに関わる部分。

<?php
   $term_object = get_queried_object(); // 現在クエリされているオブジェクトを取得
   $term_slug   = $term_object->slug; // タームスラッグ
   $args = array(
   'post_type' => array('news'),
   'taxonomy' => 'cat_news',
   'term' => $term_slug,
   'posts_per_page' => 9,
   'paged' => $paged,
   );
   $the_query_news =  new WP_Query($args);
?>
//以下略

説明が簡単な部分から。
まず「’taxonomy’ => ‘cat_news’,」の部分です。
こちらはarchive.phpでの説明と同じく、CPT UIの管理画面「タクソノミーの追加と編集」で設定したスラッグ(cat_news)を指定しています。taxnomy.phpはターム(カテゴリー)を絞って記事を表示するテンプレートです。そのため、CPT UIで作成したタクソノミースラッグを指定する必要があります。

次に「’term’ => $term_slug,」
少し説明がややこしいですが、これは具体的に表示するタームを絞るために必要な記述です。
例えばタームの構成が「ブログ(スラッグ:blog)、ワーク(スラッグ:work)」だとします。ブラウザのURL欄で「https://test.com/cat_news/blog」のように入力された際は、blogタームの記事を絞り込んで表示する必要があります。
$term_slugという変数で動的に表示を変えるためです。get_queried_object()で現在のページ(現在のURL)のターム情報を取得。そこからタームスラッグを取得し、表示する記事を絞っているわけです。「https://test.com/cat_news/blog」というURLの時は「blog」タームの記事を絞り込んで表示します。

一つのテンプレートを複数のカスタム投稿タイプで対応させる方法

以上がarchive.phpとtaxnpomy.phpでの基本の表示です。

ただ、現状のコードでは使いにくい場合があります。それは様々なカスタム投稿タイプを表示する時に対応ができないことです。

今までの参考例ではpost_typeの指定が「news」と指定して記述されていますが、これでは実績一覧の「work」というページを作る際は別途「archive-work.php」というファイルを作らなければいけません。

<?php
   $args = array(
   'post_type' => array('news'),//カスタム投稿『news』しか表示することができない。
   'posts_per_page' => 9,
   'paged' => $paged,
   );
   $the_query_news =  new WP_Query($args);
?>

デザインが異なるのであれば別ファイル作成でいいですが、同じデザインなのに別途archiveテンプレートを作成するのはコード管理で手間が生じてしまいます。

そこで、ここからは様々なカスタム投稿タイプに対応できるarchive.phpとtaxnomy.phpを紹介します。異なるカスタム投稿タイプを同じデザインで表示したい場合に有効と思っています。

この備忘録サイトの一覧ページもこの方法を使っています。

抑えておくべきWordPressの知識

ご存知の方もいると思いますが、WordPressはブラウザが受け取るURL欄によって様々処理を各WPテンプレートに分けて処理をしています。今回の一覧機能で言えば、
「https://ドメイン名/カスタム投稿スラッグ/」というURLであればarchive.phpのテンプレートが、
「https://ドメイン名/タクソノミースラッグ/タームスラッグ/」であればtaxnomy.phpテンプレートが動きます。
細かな仕様は「Wordpress テンプレート階層」などで検索してください。

重要なのはブラウザURL欄にてカスタム投稿スラッグやタームスラッグをリクエストすると、archive.phpとtaxnomy.phpの2つのテンプレートが呼び出されることです。この機能を利用してリクエスト(URL)に合わせてページタイトルや取得するカスタム投稿タイプを変えることができます。

リストタグ内を共通パーツ化

今まではリストタグ内はarchive.phpとtaxnomy.php個別にhtmlを記述していましたが、これを共通のパーツとして使えるようにします。

このパーツは「template-parts」というフォルダを作成し、その中にpost_list.phpという共通で使うファイルを作成します。下記が共通化したリストタグのコードです。

<?php
// 親要素の引数を取得。引数が設定されてない場合は空の配列
$args = isset($args) ? $args : array();

// 引数を確認
if (isset($args['variable'])) {
 $taxonomy_slug = $args['variable'];
 // 変数の値を使用する
}
?>


<li <?php the_ID(); ?>>
 <a href="<?php the_permalink(); ?>">
  <h3><?php the_title(); ?></h3>
  <div class="date"><?php the_time('Y.m.d'); ?></div>
  <?php if (has_post_thumbnail()) : ?>
   <?php the_post_thumbnail('full'); ?>
  <?php else : ?>
   <img src="<?php bloginfo('template_url'); ?>/assets/images/common/sample.jpg" alt="" />
  <?php endif ; ?>
  <?php if ($terms = get_the_terms($post->ID, $taxonomy_slug)) : ?>
   <div class="catArea">
    <?php foreach( $terms as $term ) : ?>
     <div class="cat"><span><?php echo esc_html($term->name); ?></span></div>
    <?php endforeach; ?>
   </div>
  <?php endif ; ?>
 </a>
</li>

コード冒頭では親要素となるarchive.phpやtaxnomy.phpから変数argsを受け取る処理です。この変数は各投稿のカテゴリー(ターム)を呼びたすのに利用します。

//タクソノミースラッグを使ってカテゴリーを表示。
  <?php if ($terms = get_the_terms($post->ID, $taxonomy_slug)) : ?>
   <div class="catArea">
    <?php foreach( $terms as $term ) : ?>
     <div class="cat"><span><?php echo esc_html($term->name); ?></span></div>
    <?php endforeach; ?>
   </div>
  <?php endif ; ?>

以上がarchive.phpとtaxnomy.phpで使う共通リストタグについて説明しました。次に記事一覧テンプレートのコードを紹介します。まずはarchive.phpです。

archive.phpのコード

<?php
 $post_type = get_post_type(); // 現在の投稿タイプを取得
 $taxonomy_slug = get_taxonomy_slug($post_type);// タクソノミースラッグを取得
 $pageTitle = get_post_type_object($post_type)->label;//カスタム投稿のページタイトルを取得する
?>

<main>
 <div class="pageTitle">
  <h1><span><?php echo $pageTitle; ?></span></h1>
 </div>
  <ul>
   <?php
    $args = array(
    'post_type' => $post_type,
    'posts_per_page' => 8,
    'paged' => $paged,
    );
    $the_query =  new WP_Query($args);
   ?>
    <?php if ( $the_query->have_posts() ) : ?>
     <?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
      <?php get_template_part('template-parts/post_list',null,
       array(
        'variable' => $taxonomy_slug,
        )
       );
      ?>
     <?php endwhile; ?>
    <?php endif; wp_reset_postdata(); ?>
    <?php if( function_exists( 'wp_pagenavi' )) { wp_pagenavi();} ?>
  </ul>
</main>

まずはコードの冒頭部分。WP関数を使って3つ変数に格納していますね。この変数はarchive.phpとtaxnomy.phpどちらのテンプレートでも使っています。

<?php
 $post_type = get_post_type(); // 現在の投稿タイプを取得
 $taxonomy_slug = get_taxonomy_slug($post_type);// タクソノミースラッグを取得
 $pageTitle = get_post_type_object($post_type)->label;//カスタム投稿のページタイトルを取得する
?>

コアになっている部分は「$post_type = get_post_type();」です。この関数によりブラウザからリクエストされたURLをもとに現在の投稿タイプをを取得し、タクソノミーなど様々な投稿タイプに関わる情報取得ができます。

   <?php
    $args = array(
    'post_type' => $post_type,//動的に投稿タイプを変更し記事データを取得できる
    'posts_per_page' => 8,
    'paged' => $paged,
    );
    $the_query =  new WP_Query($args);
   ?>

冒頭のget_taxonomy_slug()ではタクソノミースラッグを取得しています。これは前述した「post_list」パーツに変数を渡し、各記事のターム表示も動的に変えるために使用します。

<?php get_template_part('template-parts/post_list',null,
 array(
   'variable' => $taxonomy_slug,
  )
 );
?>

同じく冒頭の「get_post_type_object($post_type)->label」はCPT UIで設定したラベル名を取得しています。これは何に使っているかというとページのタイトルです。ここも動的に変える必要があるため、ラベル名を取得してカスタム投稿タイプごとに変えています。

 <div class="pageTitle">
  <h1><span><?php echo $pageTitle; ?></span></h1>
 </div>

taxnomy.phpのコード

次にtaxnomy.phpの内容です。

<?php
 $post_type = get_post_type(); // 現在の投稿タイプを取得
 $taxonomy_slug = get_taxonomy_slug($post_type);// タクソノミースラッグを取得
 $pageTitle = get_post_type_object($post_type)->label;//カスタム投稿のページタイトルを取得する
?>


<main>
 <div class="pageTitle">
  <h1><span><?php echo $pageTitle; ?></span></h1>
 </div>
  <ul>
   <?php
      $term_object = get_queried_object(); // 現在クエリされているオブジェクトを取得
      $term_slug   = $term_object->slug; // タームスラッグ
      $args = array(
       'post_type' => $post_type,
       'taxonomy' => $taxonomy_slug,
       'term' => $term_slug,
       'posts_per_page' => 8,
       'paged' => $paged,
      );
    $the_query =  new WP_Query($args);
   ?>
    <?php if ( $the_query->have_posts() ) : ?>
     <?php while ($the_query->have_posts()) : $the_query->the_post(); ?>
      <?php get_template_part('template-parts/post_list',null,
       array(
        'variable' => $taxonomy_slug,
        )
       );
      ?>
     <?php endwhile; ?>
    <?php endif; wp_reset_postdata(); ?>
    <?php if( function_exists( 'wp_pagenavi' ))
       { wp_pagenavi( array('query'=>$the_query ) );} //← array('query'=>$the_query ) この記述がないとpagenaviが一つ目以上が表示されない
    ?>
    <?php wp_reset_postdata(); ?>
  </ul>
</main>

冒頭の変数部分は同じです。$argsの中も$taxonomy_slug変数を使って動的になっています。その他はこれまで説明した内容になります。

まとめ

以上です。ここまでのコードを使えばarchive.phpとtaxnomy.phpを様々なカスタム投稿タイプで表示することができます。

再度、注意ですがこれが使えるのは全ての一覧ページの表示が同じデザインの場合です。デザインが異なるとhtml構成も変わってきますので使えません。

totop Page Top