今回は、カテゴリー・タグ・カスタムタクソノミーのターム情報を全て取得する方法をまとめていこうと思います。
サイドバーやフッターに、「カテゴリー一覧」や「タグ一覧」を表示させたい時などに使える知識になります。
まず知っておくべきなことは、カテゴリーやタグを全取得する方法はいくつかあるということ。
タームの一覧を取得する方法は主に以下の2パターンです。
get_categories()
,get_tags()
,get_terms()
といったget_〇〇s
関数を使用するWP_Term_Query
を使用する
両者ともに カテゴリーでもタグでもカスタムタクソノミーでも、どのタクソノミーでも使用でき、取得したいタームの条件を詳細に指定してデータを得ることができます。
また、カテゴリー限定で使えるwp_list_categories()
という関数も非常に便利ですので、知っておくといいでしょう。
では、それぞれの違いや特徴を整理していきます。
呼び方が「??」となってしまう人は、以下の記事を読んでおくと良いかと思います!
混乱しがちなカテゴリー、タグ、タクソノミー、タームの意味と違い
目次
ターム情報が詰まっている「WP_Termオブジェクト」について
まずはじめに、「タームの情報」がどのように取得できるかを前提知識として知っておくといいかなと思います。
各タクソノミーのターム情報を取得する場合、「WP_Termオブジェクト」というオブジェクトデータでターム情報を取得することがほとんどです。
今回解説していくget_terms()
や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() //フィルタ
}
このように、「タームの名前」や「ID」、「所属しているタクソノミー」などの様々な情報が詰まったオブジェクトデータがWP_Termオブジェクトです。
カテゴリーやタグの各タームごとに、これらの情報が保存されています。
ただし、カテゴリーのタームデータには注意が必要です。
カテゴリーに関するタームにのみ、追加で以下の情報も保存されています。
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"]
}
「お!カテゴリーには特別な情報があるんだな」と思いきや、実は共通パラメータと全く同じ情報なんですよね...笑
( 例えば、term_id
とcat_ID
というパラメータに保存されている情報は全く同じです。)
名前が違うだけで取得できる情報は同じという、なんとも謎な仕様になっているので注意しましょう。
ややこしくなってしまうので、カテゴリーにのみ存在するパラメータは覚えなくていいかなと思います。
方法1:「get_○○s 関数」を使ってターム一覧を取得する
ここからは実際に、カテゴリーやタグの全ターム情報を取得する方法について解説していきます。
「get_○○s 関数」と称しているのは、以下の3種類の関数のことです。
WordPressが用意してくれているこれらの関数は、いずれもターム情報を一括で取得するものです。
取得したいタームの条件を指定して、その条件に一致したタームの情報(WP_Termオブジェクト)をごっそり取得できます。
- カテゴリーのターム情報を取得できるのが
get_<strong>categories</strong>()
- タグのターム情報を取得できるのが
get_<strong>tags</strong>()
- タクソノミーのターム情報を取得できるのが
get_<strong>terms</strong>()
です。
実はカテゴリーでもタグでも<strong>get_terms()</strong>
を使用できるので、困惑しそうであればget_terms()
だけ覚えておきましょう。
get_categories()
とget_tags()
は、内部でget_terms()
を呼び出しています。
get_categories / get_tags / get_terms の基本的な使い方
名前の似ている「get_○○s 関数」たちですが、使用法もほぼ同じです。
3つの関数の基本となる使用形式
$categories = get_categories( $args );
$tags = get_tags( $args );
$terms = get_terms( $taxonomies, $args );
上記のようにすることで、左辺の変数に取得できたターム情報が代入されます。
取得したいタームの条件を配列($args
)で指定するという使い方が共通していますね。
ただしget_terms()
のみ、その$args
の前にタクソノミー名として$taxonomies
を指定する必要があります。
各引数の説明
引数 | 説明 |
---|---|
$args | 取得したいタームの条件を指定する配列です。 3つの関数で共通して必要となります。 |
$taxonomies | 【get_terms() でのみ、第1引数として必要】
タクソノミー名を指定します。 |
引数の $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' => '', //親タームのIDを指定するとその一つ下の階層の子タームを返す
'hierarchical' => true, //親タームのIDを指定するとその子孫タームを全て返す
'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()
の$args
に指定できるものをまとめています。
その他の2つの関数で指定できるパラメータについては、これらよりいくつか少ないとしている記事が多かったのですが、その内容にはばらつきがありました。
ただ、基本的なパラメータに関しては共通で指定可能なことは間違いないので、とりあえず上記のパラメータを覚えておき、もしget_tags()
などで動作しない条件があれば「このパラメータはget_terms()
専用のものなんだな」と思ってください...。
各パラメータについての説明
それぞれのパラメータに関する説明を表にまとめてみました。
パラメータ名 | 説明 |
---|---|
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() が作成したクエリにユニークなキャッシュ用キーを付与できる。 例えば、この関数のフィルターを使ってクエリを変更するとき、この値にユニークな値を指定しておけばキャッシュにある同様のクエリを上書きせず残しておける。 |
get_categories / get_tags / get_terms の使用例
$args
に指定できるたくさんのパラメータを列挙しましたが、実際にはこれら全てを使うことはありません。
その時に取得したいタームの条件に合わせて、必要なパラメータだけを指定して使います。
いくつか例を挙げておきます。
例1: 第一階層のカテゴリーだけを取得する
$args = array(
'parent' => 0
);
$terms = get_categories($args);
これは、以下のようにget_terms()
を使っても同じです。
$args = array(
'parent' => 0
);
$terms = get_terms('category', $args);
例2: 使用回数の多い順にタグを5つ取得する
$args = array(
'orderby' => 'count',
'order' => 'DESC',
'number' => 5
);
$terms = get_tags($args);
これも、get_terms()
で同じことを実現できます。
$args = array(
'orderby' => 'count',
'order' => 'DESC',
'number' => 5
);
$terms = get_terms('post_tag', $args);
取得したターム情報の扱い方
さて、ターム情報の取得方法が分かったところで、その取得できた情報をどう扱えばいいのかを説明していきます。
取得できる情報は、最初に説明したように「WP_Termオブジェクト」で返ってきます。
$args
の'fields'
の指定によってオブジェクトデータではなく配列で取得できたりもしますが、ややこしいので今回はデフォルトで返ってくるWP_Termオブジェクトについて説明していきます。
例えば、使用例として紹介した「例2」ではタグを5つ取得していますが、この時取得できる情報(変数$terms
)には5つのWP_Termオブジェクトが配列として順番に保存されています。
「例2」で取得した$terms
をvar_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
をループ処理していくことになります。
タグ一覧の出力例1:取得した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>';
これによって、以下のように5つのタグに関する情報がリストとして表示されます。
- タグ1 (80)
- タグ1 (60)
- タグ3 (24)
- タグ4 (21)
- タグ5 (12)
タームアーカイブページへのリンクを取得する方法
先ほどの「タグ一覧の出力例1」の記述だけだと、ただタグの名前やカウント数を表示しているだけです。
これではあまり意味がないので、タグアーカイブページへのリンクもつけてみましょう。
...と思っても、WP_Termオブジェクトが持つ情報の中にはアーカイブページへのURL情報がない!
そこで、ターム情報からアーカイブページへのリンクを取得できるget_term_link()
という関数を使用します。
foreach
で回している$t
(WP_Termオブジェクト)をそのまま引数に指定することで、そのタームアーカイブページのURLが取得できます。
タグ一覧の出力例2 :タグアーカイブページへのリンクをつけて出力
//(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>';
方法2:WP_Term_Queryを使ってターム一覧を取得する
次に、WP_Term_Queryを使用する方法をまとめていきます。
WP_Term_Query は WordPress ver.4.6 で追加された新しい機能ですが、取得できる情報や条件の指定などは get_〇〇s 関数たちとほぼ同じです。
初見では少し複雑に見えますが、get_〇〇s()関数のように似たようなものが複数あって迷ったりすることがないので、WP_Term_Queryさえ覚えておけばなんとかなる、というメリットがあります。
あと、無駄な処理やフックを通したくない時に非常に便利です。
get_terms() 関数の中では、WP_Term_Queryが使われています。
基本的な使用方法
$args = array(
//取得したいタームの条件を指定
);
$term_query = new WP_Term_Query( $args );
foreach( $term_query->get_terms() as $term ) {
//ループ処理 ( $term は WP_Termオブジェクト )
}
$term_query->get_terms()
のところでget_terms()
が呼び出されているように見えますが、これはテンプレートタグのget_terms()
関数とは別物です。
取得するタームの条件を指定する$args
はnew WP_Term_Query()
の時点で渡しておかないといけないので注意しましょう。
new WP_Term_Query()
時に渡す$args
に指定できる条件については、 get_〇〇sで使えるパラメータとほぼ同じですが、'taxonomy'
というパラメータでタクソノミー名を指定する必要があることに注意しましょう。
カテゴリを取得する時は'category'
、タグを取得したいときは'post_tag'
を指定しましょう。
例:単純にカテゴリ一覧を取得し、カテゴリ名を出力する。
$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) カテゴリーリストの表示形式。
|
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>(全ての親子カテゴリーを出力)。
('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 ライフを!