以前、こちらの投稿でカテゴリー毎に記事一覧を出力する方法を書きましたが、同じようにカスタム投稿の記事をターム(カテゴリー)毎に出力する方法の備忘録になります。
仕様
- 検証バージョン:WordPress 4.8.5
- ターム毎に指定した記事数分を表示
- タームは親子階層なし
実現したい表示イメージは以下の通りです。
ターム毎に記事が表示され、タームに記事が無い場合はコメントを表示します。
コード
function.php にカスタム投稿・タクソノミーを定義
function.phpの編集に慣れていない方は、function.phpの最終行の下に追加してください。
function.php
add_action( 'init', 'create_post_type' );
function create_post_type() {
register_post_type( 'trip', // カスタム投稿のスラッグ
array(
'labels' => array(
'name' => __( '旅ログ' ), // 投稿タイプ名
'singular_name' => __( '旅ログ' ) // 投稿タイプ名
),
'public' => true,
'has_archive' => true,
'menu_position' =>5,
'supports' => array('title','editor')
)
);
// カテゴリタクソノミー(カテゴリー分け)を使えるように設定する
register_taxonomy(
'pref', // タクソノミー(カテゴリー)のスラッグ
'trip', // 適用するカスタム投稿のスラッグ
array(
'hierarchical' => true, // trueだと親子関係が使用可能。falseで使用不可
'label' => '都道府県', // タクソノミー名(カテゴリー名)
'singular_label' => '都道府県', // タクソノミー名(カテゴリー名)
'public' => true,
'show_ui' => true
)
);
}
カスタム投稿一覧を表示するコード
カスタム投稿一覧を表示するページのテンプレートファイルに以下のコードを記入してください。
今回はindex.phpに記入しています。
index.php
<?php
$taxonomies = 'pref'; // タクソノミー(カテゴリー)スラッグを指定
$args = array(
'hide_empty' => false, // 空のタームを出力しない場合はtrue
);
$terms = get_terms( $taxonomies , $args );
// ターム(カテゴリー)別に記事を出力する
foreach ($terms as $term) :
$args = array(
'post_type' => 'trip',
'taxonomy' => $taxonomies,
'term' => $term->slug,
'posts_per_page'=> 5 // 最新5記事。数を指定しない場合は-1を指定
);
$trip_posts = get_posts( $args );
if ( $trip_posts ) {
// 記事がある場合
// ターム名(カテゴリー名)
echo '<h1>'.$term->name.'</h1>';
foreach ( $trip_posts as $post ) :
setup_postdata( $post ); ?>
<section>
<h2><?php the_title(); // 記事の見出し ?></h2>
<div><?php the_content(); // 記事の内容 ?></div>
</section>
<?php
endforeach;
} else {
// 記事がない場合
// ターム名(カテゴリー名)
echo '<h1>'.$term->name.'</h1>';
echo '<p>ここにはまだ旅行していません。</p>';
}
endforeach;
wp_reset_postdata();
?>
結果
HTML
<h1>京都</h1>
<section>
<h2>京都旅行記その2</h2>
<div>
<p>京都旅行記その2の内容</p>
</div>
</section>
<section>
<h2>京都旅行記その1</h2>
<div>
<p>京都旅行記その1の内容</p>
</div>
</section>
<h1>沖縄</h1>
<p>ここにはまだ旅行していません。</p>
<h1>北海道</h1>
<section>
<h2>北海道旅行記その1</h2>
<div>
<p>北海道旅行記その1の内容</p>
</div>
</section>
今回はforeach
を使っていますが、もっと簡単な方法もあるのでしょうか…。
ちなみに、プラグインなどでタームの順序を変えればそれに準じて並べ替えられます。
参考になれば嬉しいです。