カテゴリやカスタムタクソノミーの一覧(絞りこみメニュー・タグクラウド)を出すのがget_terms()です。返ってくるのはタームオブジェクトの配列なので、foreachで回して出します。
<?php
$terms = get_terms([
'taxonomy' => 'season',
'hide_empty' => true,
]);
?>
<?php if ($terms && !is_wp_error($terms)) : ?>
<ul class="term-list">
<?php foreach ($terms as $term) : ?>
<li>
<a href="<?php echo esc_url(get_term_link($term)); ?>">
<?php echo esc_html($term->name); ?>(<?php echo esc_html($term->count); ?>)
</a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>タームオブジェクトから取れるもの
foreachの中の$termから、よく使うのはこの5つです。
| 書き方 | 中身 |
|---|---|
$term->name | 表示名(「冬」など) |
$term->slug | スラッグ(winter) |
$term->term_id | ID(数値) |
$term->count | そのタームの投稿数 |
$term->description | 説明文 |
URLはget_term_link($term)で作ります。自分で/season/winter/のような文字列を組み立てないのがコツです——パーマリンク設定やタクソノミーのrewriteが変わっても壊れません。
引数の早見表
| 引数 | 意味 | 例 |
|---|---|---|
taxonomy | 対象のタクソノミー | 'category' / 'post_tag' / 'season' |
hide_empty | 投稿0件のタームを隠すか | true(既定)/ false |
orderby | 並べ替えの基準 | 'name'(既定)/ 'count' / 'term_id' / 'include' |
order | 昇順・降順 | 'ASC' / 'DESC' |
number | 取得件数 | 10 |
parent | 直下の子だけ取る | 0(トップ階層のみ) |
child_of | ある親の子孫すべて | 5 |
include / exclude | ID指定で含める・除く | [3, 7] |
fields | 返す形を変える | 'ids' / 'names' / 'id=>name' |
今見ているタームに印を付ける
絞りこみメニューでは「今どれを見ているか」が分かると使いやすくなります。
<?php
$terms = get_terms(['taxonomy' => 'season', 'hide_empty' => false]);
$current = get_queried_object(); // タクソノミーアーカイブなら今のターム
?>
<ul class="filter">
<?php foreach ($terms as $term) : ?>
<?php $is_current = (!empty($current->term_id) && $current->term_id === $term->term_id); ?>
<li class="<?php echo $is_current ? 'is-current' : ''; ?>">
<a href="<?php echo esc_url(get_term_link($term)); ?>"><?php echo esc_html($term->name); ?></a>
</li>
<?php endforeach; ?>
</ul>カテゴリの場合はis_category($term->term_id)という条件分岐タグでも判定できます。
親子のあるタクソノミー
カテゴリのように階層があるタクソノミーでは、親だけ取ってから子を取ると入れ子のリストが作れます。
<?php $parents = get_terms(['taxonomy' => 'category', 'parent' => 0]); ?>
<ul>
<?php foreach ($parents as $parent) : ?>
<li>
<a href="<?php echo esc_url(get_term_link($parent)); ?>"><?php echo esc_html($parent->name); ?></a>
<?php $children = get_terms(['taxonomy' => 'category', 'parent' => $parent->term_id]); ?>
<?php if ($children) : ?>
<ul>
<?php foreach ($children as $child) : ?>
<li><a href="<?php echo esc_url(get_term_link($child)); ?>"><?php echo esc_html($child->name); ?></a></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>get_termsと似た関数の使い分け
名前が似ていて混乱しやすいので、役割で覚えます。
| 関数 | 何を返すか | 使う場面 |
|---|---|---|
get_terms() | サイト全体のターム一覧 | 絞りこみメニュー・タグクラウド |
get_the_terms($id, $tax) | その投稿に付いているターム(オブジェクト配列) | 記事のカテゴリ表示 |
wp_get_post_terms($id, $tax, $args) | 同じくその投稿のターム(fields指定が使える) | 関連記事の条件づくり |
wp_list_categories() | HTMLのリストを自動生成 | 手軽にサイドバーへ出す |
the_category() | その投稿のカテゴリのリンクHTML | 記事の見出し下に1行で |
「一覧を作りたい=get_terms、この記事のタグを出したい=get_the_terms」——ここを取り違えると、全カテゴリが記事に並ぶ、という見た目のバグになります。
その投稿のタームを出す(get_the_terms)
<?php $terms = get_the_terms(get_the_ID(), 'season'); ?>
<?php if ($terms && !is_wp_error($terms)) : ?>
<ul class="tags">
<?php foreach ($terms as $term) : ?>
<li><a href="<?php echo esc_url(get_term_link($term)); ?>"><?php echo esc_html($term->name); ?></a></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>HTMLを自分で組まなくてよい場面では、the_terms()の1行で済みます。
<?php the_terms(get_the_ID(), 'season', '季節:', '、'); ?>HTMLごとおまかせにする(wp_list_categories)
サイドバーに手早く出すだけなら、HTML生成までやってくれる関数が楽です。
<?php
wp_list_categories([
'taxonomy' => 'season',
'title_li' => '', // 「カテゴリー」という見出しliを消す
'show_count' => true, // 件数を出す
'hide_empty' => false,
]);
?>マークアップを自分で決めたいならget_terms()、手早さ優先ならwp_list_categories()という住み分けです。
まとめ
- ターム一覧は
get_terms()。返ってくるのはオブジェクトの配列なのでforeachで回す - URLは
get_term_link($term)で作る。自分でURL文字列を組み立てない hide_emptyの既定はtrue——投稿0件のタームが出ないのは正常な動きget_terms=サイト全体、get_the_terms=その投稿。手軽さ優先ならwp_list_categories()
一覧が出せるようになると、絞りこみメニューやタグクラウドのような「回遊できる導線」を自分で設計できるようになります。