サイドバーなどでカテゴリやタグ一覧などを表示させたい時に、カテゴリ・タグ・タクソノミーで登録済みのターム情報を全て取得する方法をまとめていこうと思います。

主に以下のような方法があります。

  • get_categories(), get_tags(), get_terms()といったget_〇〇s関数を使用する
  • WP_Term_Queryを使用する
  • wp_list_categories()を使用する (カテゴリのみ)

では、それぞれの違いや特徴を整理していきます。

目次

はじめに - WP_Termオブジェクトについて

タームの情報を取得する場合、「WP_Termオブジェクト」というオブジェクトでターム情報を取得する方法がよくあります。

今回も、get_〇〇s関数WP_Term_QueryではWP_Termオブジェクトを扱うことになります。

なので、先にWP_Termオブジェクトというものにどんな情報が保存されているのかを確認しておきましょう。

カテゴリー・タグ・タクソノミーの各タームで共通するパラメータ

object(WP_Term) {
  ["term_id"]           => int()    //タームID
  ["name"]              => string() //ターム名
  ["slug"]              => string() //"タームスラッグ
  ["term_group"]        => int()    //タームグループID
  ["term_taxonomy_id"]  => int()    //タームタクソノミーID
  ["taxonomy"]          => string() //タクソノミー
  ["description"]       => string() //ターム説明
  ["parent"]            => int()    //親
  ["count"]             => int()    //投稿数
  ["filter"]            => string() //フィルタ
}

上記が基本的なターム情報の一覧になります。

これらに加え、カテゴリーに関するタームにのみ、以下の情報が追加されます。

カテゴリーにのみ存在するパラメータ

object(WP_Term) {
  /* ... */
  ["cat_ID"]                =>int()     //カテゴリID = ["term_ID"]
  ["category_count"]        =>int()     //投稿数 = ["count"]
  ["category_description"]  =>string()  //カテゴリ説明 = ["description"]
  ["cat_name"]              =>string()  //カテゴリ名 = ["name"]
  ["category_nicename"]     =>string()  //カテゴリスラッグ = ["slug"]
  ["category_parent"]       =>int()     //親 = ["parent"]
}

*カテゴリーにのみ存在するパラメータは、共通で存在するパラメータと被っているので、正直覚える必要はありませんが。

get_○○s 関数を使ってターム一覧を取得する

改めて紹介しておくと、WordPressにはタームの取得用関数として、使用法も名前もよく似た、以下のような関数があります。

これら3種の関数は、いずれも取得したいタームに関する条件を配列で引数に指定し、WP_Termオブジェクトを戻り値として得るためのものです。

3つの関数の使用形式

$categories = get_categories( $args );
$tags       = get_tags( $args );
$terms      = get_terms( $taxonomies, $args );

左辺の変数に、右辺の get_○○s関 数によって取得した情報を代入しています。

引数 説明
$args 取得したいタームの条件を指定する配列です。get_○○s系の関数では共通して必要となる引数です。
$taxonomies タクソノミー名を指定します。(get_terms() のみ、第一引数にこの引数が必要。)
 'category' を指定するとカテゴリー、'post_tag' を指定するとタグ情報を取得できます。その他のカスタムタクソノミー名を取得したい場合は、そのタクソノミー名のスラッグを指定します。

取得したいタームの条件を配列($args)で指定するという使い方が共通しています。 ただし、get_terms()のみ、その配列の前にタクソノミー名を指定する必要があります。

$argsで指定できるもの

3つの関数で共通となる、$argsという引数にはどのような条件を指定できるのかを見てみましょう。

それぞれのパラメータの初期値と簡単な説明

$args = array(
  'orderby'            => 'name',  //何でソートするか
  'order'              => 'ASC',   //ソートの昇順or降順
  'hide_empty'         => true,    //投稿のないタームも取得するかどうか
  'exclude'            => array(), //除外するタームの ID の配列または文字列
  'exclude_tree'       => array(), //除外する親タームの ID の配列
  'include'            => array(), //含めるタームの ID の配列
  'number'             => '',      //返すタームの最大個数
  'fields'             => 'all',   //戻り値に何を返すか
  'slug'               => '',      //指定したスラッグに一致するタームを返す
  'parent'             => '',      //直近の子タームを返すかどうか
  'hierarchical'       => true,    //子タームを持つタームを含めるかどうか
  'child_of'           => 0,       //指定したタームの子孫をすべて取得する
  'childless'          => false,   //タクソノミーが階層有りの場合、子を持たないタームのみを返すかどうか
  'get'                => '',      //この値を 'all' にすると 'hide_empty' と 'child_of' が無効に
  'name__like'         => '',      //ターム名にマッチさせたい文字列
  'description__like'  => '',      //タームの説明に指定した文字列が含まれるタームを返す
  'pad_counts'         => false,   //子孫タームすべてのカウントを合計するかどうか
  'offset'             => '',      //numberが指定されている時、見つかったタームの先頭から指定の個数を読み飛ばして返す
  'search'             => '',      //ターム名とスラッグにマッチさせたい文字列
  'cache_domain'       => 'core'   //作成したクエリにユニークなキャッシュ用キーを付与できる
); 

何も指定しないパラメータには、それぞれの初期値が自動で指定される仕組みです。

*注意点:上記は get_temrs() に指定できるものをまとめています。get_categories() や get_tags() について指定できるパラメータについては get_terms()で指定できるものよりいくつか少ないとしている記事が多かったのですが、その内容にはばらつきがありました。ただ、基本的によく使うパラメータに関しては共通で指定可能なので、とりあえず上記のパラメータを覚えておき、もしget_tags() などで動作しないものがあれば、「あ、このパラメータはget_terms()専用のものなんだな」と思ってください。

$argsの各パラメータについて

それぞれのパラメータに関する説明を表にまとめてみました。

パラメータ名 説明
orderby (string) 何でソートするか
  • id
  • count
  • name (デフォルト)
  • slug
  • term_group (実装が充分ではないので利用は避けるべき)
  • none
order (string) ソートする方向。
  • ASC : 昇順 (デフォルト)
  • DESC : 降順
hide_empty (bool) まだ投稿のないタームを返さないのかどうか
exclude (int|string|array) 除外するタームIDの配列、またはIDをコンマで区切りで指定。
exclude_tree (int|array) 除外する親タームIDの配列
include (int|array) 取得したいタームIDの配列。空文字列を指定するとすべてのタームを対象にします。
number (int|array) 取得するタームの最大個数。デフォルト(null)ではすべてのタームを返します。
fields (string) 戻り値に何を返すか
  • all : WP_Termオブジェクトの配列を返す (デフォルト)
  • ids : タームIDの配列を返す
  • names : ターム名の配列を返す
  • count : 見つかったタームの個数を返す
  • id=>parent : 連想配列を返す(キーはタームID、値は親タームID)。親がない場合の値は0
  • id=>slug : 連想配列を返す(キーはタームID、値はスラッグ)。
  • id=>name : 連想配列を返す(キーはタームID、値はターム名)。
slug (string|array) 指定した値がスラッグに一致するタームを返す。
parent (int) 指定した値が親タームのIDである場合に、直近の子タームを返す。0 を指定すると第一階層(トップレベル)のタームのみを返す。
hierarchical (bool) 子タームを持つタームを含めるかどうか。
child_of (int) 指定したタームの子孫をすべて取得する。
*child_of と parent の違い : parent が直近(1階層下)の子タームのみを取得するのに対し、child_of はすべての子孫タームを取得する。
childless (bool) タクソノミーが階層有りの場合、 子を持たないタームのみを返すかどうか。
階層無しの場合はすべてのタームを取得
get (string) 'all' を指定すると、'hide_empty' と 'child_of' が無効になる(すべてのタームを取得する)。
name__like (string) 指定した文字列がターム名にマッチするものを取得する。ターム名に対してのみ、データベースクエリの LIKE '%string%' を実行する。
description__like (string) 指定した文字列がタームの説明にマッチするものを取得する。説明に対してのみ、データベースクエリの LIKE '%string%' を実行する。
pad_counts (bool) 子孫タームすべてのカウント(紐づけられている投稿数)を合計するかどうか。
offset (int) 'number'が指定されている場合、見つかったタームの先頭から指定の個数を読み飛ばして取得する。
search (string) 指定した文字列がターム名またはスラッグにマッチするものを取得する。ターム名とスラッグにデータベースクエリの LIKE '%search_string%' を実行する。
cache_domain (string) get_〇〇s() が作成したクエリにユニークなキャッシュ用キーを付与できる。
例えば、この関数のフィルターを使ってクエリを変更するとき、この値にユニークな値を指定しておけばキャッシュにある同様のクエリを上書きせず残しておける。

使用例

たくさんのパラメータを列挙しましたが、実際に使用する時はこれらを全て使うことはありません。

その時に取得したいタームの条件に合わせて、必要なパラメータを数個だけ指定して使います。

いくつか例を挙げておきます。

例1: 第一階層カテゴリだけを取得する

$args = array(
  'parent' => 0
);
$terms = get_categories($args);

例2: カウント数の多い順にタグを5つ取得する

$args = array(
  'orderby' => 'count',
  'order' => 'DESC',
  'number' => 5
);
$terms = get_tags($args);

もちろん、$argsに何も指定せず、初期値のままでも使えます。

例3: $argsを指定せずget_categories() を使う

$terms = get_categories();

取得した情報の扱い方

戻り値の設定 'fields' パラメータが初期値の 'all' のままの場合、上記の例1~例3で取得したターム一覧情報$termsは、WP_Termオブジェクトの配列になります。

「例2」の場合で言うと、カウント数の多い順でタグを5つ取得していますが、これら5つのタグ情報がそれぞれWP_Termオブジェクトで返ってきます。

試しに「例2」で取得した$termsvar_dump()してみると、以下のようになります。

array(5){
  [0] => object(WP_Term) {}
  [1] => object(WP_Term) {}
  [2] => object(WP_Term) {}
  [3] => object(WP_Term) {}
  [4] => object(WP_Term) {}
}

つまり、これら5つのタグを表示しようと思ったら、取得した$termsをさらにループ処理します。

例4:例2で取得した5つのタグの名前とカウントをリスト表示する

$args = array(
  'orderby' => 'count',
  'order' => 'DESC',
  'number' => 5,
);
$terms = get_tags($args);
$list_src = "";

foreach ($terms as $t) {
  $list_src .= '<li>'.$t->name.' ('.$t->count.')</li>';
}
echo '<ul>'.$list_src.'</ul>';

これによって、

・タグ1 (80)
・タグ1 (60)
・タグ3 (24)
・タグ4 (21)
・タグ5 (12)

のようにタグがulタグのリストで表示されます。

タームへのリンクの取得方法

例4の記述だけだと、ただタグ表示しているだけで、そのタグのついた投稿一覧ページ(タグアーカイブ)に飛ぶことができません。

これでは意味がないので、タグアーカイブページへのリンクもつけてみましょう!
...と思っても、WP_Termオブジェクトが持つ情報の中にはタグアーカイブへのURL情報がないですよね?

そこで、get_term_link()という関数を使用します。

この関数の詳細は省きますが、foreeachで回している$t (WP_Termオブジェクト)をそのまま引数に指定することで、そのタームアーカイブへのURLが取得できます。

例5 : 例4を改良し、タグアーカイブへのリンクをつけて出力(foreach以降のみ抜粋)

foreach ($terms as $t) {
  $list_src .= '<li><a href="'.get_term_link($t).'">'.$t->name.' ('.$t->count.')</a></li>';
}
echo '<ul>'.$list_src.'</ul>';

WP_Term_Queryを使ってターム一覧を取得する

次に、WP_Term_Queryを使用する方法をまとめていきます。ちなみに、 WP_Term_Query は ver.4.6 で追加された機能です。

取得できる情報や条件の指定などは get_〇〇s関数 とほぼ同じです。

初見では少し複雑に見えますが、関数の種類を気にせずにWP_Term_Queryさえ覚えておけばなんとかなる、というメリットがあります。

基本的な使用方法

<?php
  $args = array(
    //条件の指定
  );  
  $the_query = new WP_Term_Query($args);
  foreach($the_query->get_terms() as $term){
    //ループ処理 ($termはWP_Termオブジェクト)
  }
?>

get_terms() が処理の中で呼び出されていますが、取得するタームの条件を指定する$argsnew WP_Term_Query()に渡します。

*試しにget_terms()にも渡してみたのですが、指定した条件は無視されました。

$args に指定できる条件については、 get_〇〇sで使えるパラメータに加え、'taxonomy'でタクソノミー名を指定します。

カテゴリを取得する時は'category'、タグを取得したいときは'post_tag'を指定しましょう。

例:単純にカテゴリ一覧を取得し、カテゴリ名を出力する。(条件の初期値は$argsの初期値を参照)

$args = array(
  'taxonomy' => 'category',
);
$the_query = new WP_Term_Query($args);
foreach($the_query->get_terms() as $term):
  echo $term->name."\n";
endforeach;

'taxonomy'の指定がない場合は、カテゴリ・タグ・カスタムタクソノミーの全てを一緒に取得できます。

WP_Term_Queryの使用例

いくつか具体的な使用例を挙げてみます。

例:第一階層のカテゴリ一覧を取得し、リスト表示する

$args = array(
  'taxonomy' => 'category',
  'parent' => 0
);
$list_src = "";

$the_query = new WP_Term_Query($args);
foreach($the_query->get_terms() as $term):

  $list_src .= '<li><a href="'.get_term_link($term).'">'.$term->name.' ('.$term->count.')</a></li>';

endforeach;
echo '<ul>'.$list_src.'</ul>';

例:カウントの多い順にタグ一覧を取得し、リスト表示する

$args = array(
  'taxonomy' => 'post_tag',
  'orderby' => 'count',
  'order' => 'DESC'
);
$list_src = "";

$the_query = new WP_Term_Query($args);
foreach($the_query->get_terms() as $term):

  $list_src .= '<li><a href="'.get_term_link($term).'">'.$term->name.' ('.$term->count.')</a></li>';

endforeach;
echo '<ul>'.$list_src.'</ul>';

このように、使う関数が一緒なので$argsの中身を変えるだけで様々なターム情報を取得できます。

例:カテゴリをIDの低い順に取得・カウント0も含める・タームID10のカテゴリを除く

$args = array(
  'taxonomy' => 'category'
  'orderby' => 'id',
  'hide_empty' => false,
  'exclude' => 10
);

カテゴリの一覧表示ならwp_list_categories()が便利

最後に、カテゴリを一覧で出力してくれる便利な関数、 wp_list_categories()についてメモしておこうと思います。

ちなみに、Codexには以下のような注意書きがありました。

参考: wp_list_categories() は、WordPress 2.1 で非推奨となった list_cats() および wp_list_cats() の後継で、この二つとほぼ同じように動作します。

get_〇〇s関数みたいにタグ用の wp_list_tags() とかがないのが不思議だったのですが、あくまでwp_list_cats()などの後継として作られただけみたいですね。

使用形式

wp_list_categories( $args ); 

引数には取得したいカテゴリに関する条件を配列で指定できます。

ここでの$argsは、これまでのget_〇〇s関数のものとは指定できるパラメータが異なるので注意して下さい。

$argsに指定できるパラメータそれぞれの初期値

<?php 
$args = array(
  'show_option_all' => '',
  'orderby' => 'name',
  'order' => 'ASC',
  'style' => 'list',
  'show_count' => 0,
  'hide_empty' => 1,
  'use_desc_for_title' => 1,
  'child_of' => 0,
  'feed' => '',
  'feed_type' => '',
  'feed_image' => '',
  'exclude' => '',
  'exclude_tree' => '',
  'include' => '',
  'hierarchical' => 1,
  'title_li' => __( 'Categories' ),
  'show_option_none' => __( '' ),
  'number' => null,
  'echo' => 1,
  'depth' => 0,
  'current_category' => 0,
  'pad_counts' => 0,
  'taxonomy' => 'category',
  'walker' => null
);
wp_list_categories( $args ); 
?>

各パラメータの説明は以下の通りです

show_option_all (string) 空文字以外の文字列を設定すると、トップページへのリンクがリストの先頭に表示される。リンクテキストは指定した文字列。
orderby (string) 何でソートするか。有効な値は'ID','name','slug','count','term_group'
order (string) ソート順。有効な値は'ASC','DESC'
style (string) カテゴリーリストの表示形式。
  • list - 箇条書き(<li>)(初期値)
  • none - 表示形式なし(各カテゴリーは <br>(改行)で区切られる)
show_count (bool) 各カテゴリーに投稿数を表示するかどうか。初期値は false。
hide_empty (bool) 投稿のないカテゴリーを非表示にするかどうか。初期値は true
use_desc_for_title (bool) カテゴリーの説明をリンクの title 属性に挿入するかどうか。初期値は true
child_of (int) このパラメータで指定したカテゴリーID の子カテゴリーのみ表示。
(このパラメータを使うと、'hide_empty' パラメータには false がセットされる。
feed (string)空文字以外を指定すると各カテゴリーの rss-2 フィードへのリンクを表示する(リンクテキストは指定した文字列)。
feed_type (string)フィードタイプ
feed_image (string) 各カテゴリーの rss-2 フィードへのリンクを画像で表示したいとき、その画像の URI を指定。このパラメータは 'feed' パラメータより優先される。
exclude (string) 指定したカテゴリーをリストから除外。複数指定する場合はカテゴリーIDをコンマ区切りで指定する。'child_of' パラメータは自動的に無効となる。
exclude_tree (string) 結果から除外するカテゴリーツリー。除外するツリーの最上位親カテゴリーID をコンマ区切りで指定。 注意点 : 'include' パラメータは空にすること。また、'hierarchical' パラメータが true の場合、'exclude_tree' の代わりに 'exclude' が使われる。
include (string) 指定したカテゴリーID のみリストに表示する。複数の場合はコンマ区切りで指定。
hierarchical (bool)サブカテゴリーを箇条書き項目の内側に表示するかどうか。(つまり、箇条書きを入れ子・ツリー表示にするかどうか。)
初期値は true
title_li (string) 箇条書きの外側に表示するタイトルと表示形式。デフォルトは "Categories" (日本語化ファイルで定義されていればそのstring)。空文字を指定すると何も表示しない。
show_option_none (文字列) 表示するカテゴリーが一つも無いときに代わりに表示する文字列。デフォルトは "No categories" (日本語化ファイルで定義されていればそのstring)。
number (int) 表示するカテゴリーの個数を設定(SQL の LIMIT 値)。初期値では無制限。
echo (bool) 結果を表示するか、変数等へ値を返すか。初期値は true
depth (int) カテゴリー階層のどのレベルまでをカテゴリーリストに出力するかを指定。初期値は 0<code>(全ての親子カテゴリーを出力)。
  • <code>0 - 全ての親子カテゴリーを出力 (初期値)
  • -1 - 全てのカテゴリーをフラット(インデントなし)形式で出力('hierarchical' パラメータより優先)
  • 1 - 最上位カテゴリーのみ出力
  • n - n(int)階層目までを出力。'2' と指定すれば、最上位とすぐ下の子カテゴリーまでを出力。
('hierarchical'と'depth'の関係がなんかややこしいみたい。意図した結果が得られない場合は調べてみる。)
current_category (int) カテゴリーアーカイブページ以外で "current-cat" を表示させる。普通はカテゴリーアーカイブページのみで current-cat がセットされるが、それとは別の使い方をしたり、他のカテゴリーをハイライトしたい場合、このパラメータ(カテゴリー ID を指定)で関数による「現在」のカテゴリーの判断を上書きできる。
pad_counts (bool) 子カテゴリーからの値を含めてリンク数または投稿数を計算するかどうか。初期値は false
'show_counts' と 'hierarchical' がどちらも true なら、自動的に true に設定される。
taxonomy (string) カテゴリーを取得するタクソノミーの名前。
walker (obj) リストをレンダリングする Walker クラス。有効な値は、Walker_Category en または Walker enを拡張するクラスのインスタンス

$args初期値状態で呼び出した時の出力に注意

引数を特に指定せずに、単純に <?php wp_list_categories(); ?>とした時に、どのようなソースが吐き出されるのかを確認してみましょう。

wp_list_categories()のデフォルト出力

<li class="categories">カテゴリー
<ul>
  <li class="cat-item cat-item-{ID}">
    <a href="カテゴリアーカイブへのリンク" title="カテゴリー概要があればその内容">カテゴリー名</a>
  </li>
  <li class="cat-item cat-item-{ID}">
    <a href="カテゴリアーカイブへのリンク">カテゴリー名</a>
    <ul class="children">
      <li class="cat-item cat-item-{ID}"><a href="カテゴリアーカイブへのリンク">子カテゴリー名</a></li>
      <li class="cat-item cat-item-{ID}"><a href="カテゴリアーカイブへのリンク">子カテゴリー名</a></li>
    </ul>
  </li>
</ul>
</li>

ulタグの外側にliタグがあり、構造的におかしな状態で出力されていることに注意してください。

つまり、デフォルトのままでは使えません。

使用例

基本的に、'title_li' パラメータを空文字に指定して、ulタグは自分で記述するのがおすすめです。

例 (空カテゴリなし・第二階層まで表示・カウント数を表示)

<ul>
  <?php
    $args = array(
      'title_li' => "",
      'depth' => 2,
      'hide_empty' => true,
      'show_count' => true
    );
    wp_list_categories($args);
  ?>
</ul>


<ul>
  <?php wp_list_categories('title_li=&depth=2&hide_empty=1&show_count=1'); ?>
</ul>

ちなみに、当サイトのサイドバーに表示しているカテゴリ一覧のリストはこの設定で出力したものです。

また、'show_count'をtrueにしたときに表示される 投稿数はデフォルトではaタグの外に出されていますが、当サイトではaタグの中に表示するようにカスタマイズしています。

後日、その方法もメモしておこうと思います。

まとめ

少し情報量が多くてややこしかったかもしれないですが、個人的には WP_Term_Query wp_list_categories()だけを覚えておけばいいと思います。

get_〇〇s 関数でできることはWP_Term_Queryでできるので。

では、よきWordPress ライフを!

- Thank you for reading. -

コメント

コメントする