べんりワザ・WordPressのテンプレートと投稿の取得

get_termsでカテゴリ・タームの一覧を出す

カテゴリやカスタムタクソノミーの一覧を出すget_termsの書き方。引数の早見表、リンクと件数の出し方、今見ているタームに印を付ける方法、get_the_termsとの違いをまとめました。

カテゴリやカスタムタクソノミーの一覧(絞りこみメニュー・タグクラウド)を出すのが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_idID(数値)
$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 / excludeID指定で含める・除く[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()という住み分けです。

べんりワザtax_queryでカテゴリ・タクソノミーで絞りこむ一覧を絞りこむ側(tax_query)の書き方はこちら

まとめ

  1. ターム一覧はget_terms()。返ってくるのはオブジェクトの配列なのでforeachで回す
  2. URLはget_term_link($term)で作る。自分でURL文字列を組み立てない
  3. hide_emptyの既定はtrue——投稿0件のタームが出ないのは正常な動き
  4. get_terms=サイト全体、get_the_terms=その投稿。手軽さ優先ならwp_list_categories()

一覧が出せるようになると、絞りこみメニューやタグクラウドのような「回遊できる導線」を自分で設計できるようになります。

よくある質問

作ったばかりのタームが一覧に出てきません
get_termsのhide_emptyは既定でtrueのため、投稿が0件のタームは除外されます。'hide_empty' => falseを指定すると空のタームも出ます。
get_termsとget_the_termsの違いは何ですか?
get_termsは「サイト全体のターム一覧」(絞りこみメニューなどに使う)、get_the_termsは「その投稿に付いているターム」(記事のカテゴリ表示に使う)です。似た名前ですが用途が逆です。
タームのリンク先URLはどう作りますか?
get_term_link($term)を使います。パーマリンク設定に応じたアーカイブページのURLが返ります。get_term_linkはWP_Errorを返すことがあるので、is_wp_error()で確認してから使うと安全です。
件数が多い順に並べたいです
'orderby' => 'count' と 'order' => 'DESC' を指定します。名前順なら'orderby' => 'name'(既定)です。