[WordPress] 最上位(一番上)のカテゴリーを取得して表示する

 2016.04.28  2017.09.20

最上位カテゴリーを取得

以前、get_categoryとget_the_categoryの違いについてという記事を書きました。 これらの関数を使って、実際にカテゴリー名を表示させてみようと思います。

現在のカテゴリーをただ表示させるだけというのは左程難しくないと思うので、今回は「2階層以上あるカテゴリーで、どのページにいても現在表示されているカテゴリーおよび所属しているカテゴリーの最上位カテゴリー名」を表示させます。PHP勉強中の私でも、果たしてきちんと「理解」をしてコードを書けるのでしょうか…?

最上位カテゴリにこだわる!

最上位カテゴリーというのは、下記の例でいうと「食品・衣料品・日用品」にあたります。もう上にカテゴリーがないカテゴリーです。当たり前ですが…。

  • 食品
    • 果物
      • りんご
      • みかん
    • 野菜
      • りんご
      • みかん
    • お肉
  • 衣料品
    • トップス
      • カットソー
      • セーター
    • ボトムス
      • スカート
      • キュロット
  • 日用品
    • 文房具…

カテゴリーアーカイブの場合(category.php)

使用関数
get_ancestors(), get_category(), get_queried_object(), array_pop(), array_reverse()

「カテゴリーページにて、最上位のカテゴリーが表示されていたらそのカテゴリー名を表示、親カテゴリーがあればそのカテゴリーの最上位カテゴリー名を表示」としてみます。

<?php
$catInfo = get_queried_object(); //get_category($cat)でも可能。$catは現在のカテゴリーIDは入る。
$catName = $catInfo -> cat_name; //現在表示のカテゴリー名
$catParent = $catInfo -> parent; //親カテゴリーのID。なければ0。
$thisCat =  $catInfo -> cat_ID; //現在表示のカテゴリーID
if($catParent){ //現在のページが一番上の親カテゴリーなら(0なら)
  echo $catName; //カテゴリー名を表示
}else{
  $ancestor = array_pop(get_ancestors( $thisCat, 'category' )); //配列の一番最後の値(一番上のカテゴリーID)を取得
  echo get_cat_name($ancestor); //カテゴリー名取得
}
?>

現在表示されているカテゴリー情報はget_categoryかget_queried_objectで取得できます。中身はvar_dump()様やprint_r()様に確認してもらいましょう。(もはや神のような存在..)

$catInfo = get_category($cat);  //$catには現在表示されているカテゴリーIDが入る
$catInfo = get_queried_object(); 

親カテゴリーの有無($catParent)の分岐は下記のような書き方もできます。親カテゴリーがない場合は「0」が帰ってくるので「0だったら、『0ではない』ではなかったら」、親カテゴリーがある場合は0以外の親カテゴリーIDが帰ってくるので「0以外、0より上だったら」というように分岐ができます。

//親カテゴリーがある場合、{}を処理する
if($catParent > 0){ ... }
if($catParent != 0){ ... }

//親カテゴリーがない場合(最上位カテゴリー)、{}を処理する
if($catParent == 0){ ... } 
if(!$catParent){ ... } 

array_popは、配列一番最後の値を取り出すPHP関数です。get_ancestorsは孫→子→親(一番上)と逆の順番で帰ってくるので、その順番を利用して値を取得します。
例えば、get_ancestors( $thisCat, ‘category’ )で返される値が下記だとすると、

Array ( 
[0] => 16 //上から2番目のカテゴリー
[1] => 60 //一番上のカテゴリー
)

60が最上位カテゴリーのIDで配列の一番最後の値なので、array_popで最後の60を取得するという感じです。配列の要素が1つ減っちゃうのですが、最後の値を取るだけなら問題ないのかな…?

get_ancestorsは通常のカテゴリー構造とは逆の順番で帰ってくるのですが、array_reverse()というPHPの関数を使うと、配列の順番を逆さにすることが可能になり、親→子→孫という順番で値が帰ってきます。

$ancestors = array_reverse(get_ancestors( $thisCat, 'category' ));
print_r($ancestors);

上記のように書くと、

Array ( 
[0] => 60 //一番上のカテゴリー
[1] => 16 //上から2番目のカテゴリー
)

という順番で帰ってきます。パンくずリストなど作る時には使えそうです。因みにarray_reverseを使って最上位のカテゴリーを取得すると、下記のような感じになります。(やや強引)

//配列の順番を逆にする。一番後ろのカテゴリIDが一番前に来る→最上位のカテゴリIDが配列の一番前に来る。
$ancestors = array_reverse(get_ancestors( $thisCat, 'category' ));
$topCat = $ancestors[0]; //配列の一番初めのカテゴリーID(=最上位のカテゴリ)を取得
echo get_cat_name($topCat); //カテゴリー名取得

スラッグを表示させる場合は、else以降でまず最上位のカテゴリIDの情報を取得してからスラッグを取得します。

  
$ancestor = array_pop(get_ancestors( $thisCat, 'category' ));
echo get_category($ancestor) -> slug;

これで、どのレベルのカテゴリーページでも最上位のカテゴリー名が表示されます。されているはず…!

使用関数について

指定された子オブジェクトの祖先オブジェクトの配列を返す。

<?php get_ancestors( $object_id, $object_type ); ?>
$object_id
(必須)子オブジェクトのID
$object_type
(必須)祖先オブジェクトの種類:’page’’category’など。
その他階層を持った投稿タイプ、階層を持ったタクソノミーが指定可能。

問い合わせパラメータにマッチするカテゴリーのオブジェクトを配列として返す。

<?php $categories = get_categories( $args ); ?>
パラメーターの初期値
<?php 
$args = array(
	'type'                     => 'post',
	'child_of'                 => 0,
	'parent'                   => '',
	'orderby'                  => 'name',
	'order'                    => 'ASC',
	'hide_empty'               => 1,
	'hierarchical'             => 1,
	'exclude'                  => '',
	'include'                  => '',
	'number'                   => '',
	'taxonomy'                 => 'category',
	'pad_counts'               => false 
); 
?>
戻り値
$category->term_id
$category->name
$category->slug
$category->term_group
$category->term_taxonomy_id
$category->taxonomy
$category->description
$category->parent
$category->count
$category->cat_ID
$category->category_count
$category->category_description
$category->cat_name
$category->category_nicename
$category->category_parent

現在クエリされているオブジェクトを取得する。カテゴリーアーカイブを表示中なら、カテゴリーオブジェクト。

<?php
$queried_object = get_queried_object();
var_dump( $queried_object );
?>

投稿記事の場合(single.php)

投稿記事は複数のカテゴリーに登録している場合がありますので、一番初めのカテゴリーをひとつ取り出して、そのカテゴリーの親カテゴリーを調べます。

<?php
$catInfo = get_the_category($post->ID); //現在の投稿記事のIDからカテゴリー情報を取得
$cat = $catInfo[0]; //複数登録されている場合、一番最初のカテゴリー情報を取得
$catName = $cat -> cat_name;
$catParent = $cat -> parent;
$thisCat = $cat -> cat_ID;
if( $catParent == 0){ //一番上の親カテゴリーなら
  echo $catName;
}else{
  $ancestor = array_pop(get_ancestors( $thisCat, 'category' ));
  echo get_cat_name($ancestor); //カテゴリー名表示
}
?>

親カテゴリー有無の分岐はカテゴリーページと同じです。投稿記事の場合は、get_the_categoryを使って、登録しているカテゴリー情報を取得します。

使用関数について

<?php get_the_category( $id ); ?>

$id:投稿 ID。初期値: $post->ID (現在の投稿の ID)
この記事が所属する全カテゴリーの情報取得。複数あれば配列で返ってくる。

最上位のカテゴリーのみのカテゴリーリストを作成する

カテゴリーのリストを表示するタグを使って、最上位のみのカテゴリーリストを作ってみます。上記の例でいうと、

  • 食料
  • 衣料品
  • 日用品
のみをリスト表示します。

wp_list_categoriesを使う

こちらのタグはリンク付きでフォーマットされたカテゴリーリストを表示します。フォーマットされていない生のデータが必要な時は、後述のget_categories()を使用します。 「depth=1」と指定すると、最上位カテゴリーのみ出力します。

<?php wp_list_categories( 'depth=1' ); ?>
<?php wp_list_categories( $args ); ?>

デフォルトの使い方と$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 ); 
?>

get_categoriesを使う

パラメーターを指定して、カテゴリーのオブジェクトを配列として返します。パラメータの内容はwp_list_categoriesとほぼ同じで、クエリ文字列形式でも配列形式でも渡すことが可能。こちらの方が色々と応用がききますね。

<?php
//最上位のカテゴリーのみを取得するにはparentの値をゼロにする
$args = array(
  'orderby' => 'name',
  'parent' => 0
  );
$categories = get_categories( $args );
foreach ( $categories as $category ) {
    echo '<a href="' . get_category_link( $category->term_id ) . '">' . $category->name . '</a><br/>';
}
?>

デフォルトの使い方と$argsで指定できるパラメーター一覧

<?php 
$args = array(
	'type'                     => 'post',
	'child_of'                 => 0,
	'parent'                   => '',
	'orderby'                  => 'name',
	'order'                    => 'ASC',
	'hide_empty'               => 1,
	'hierarchical'             => 1,
	'exclude'                  => '',
	'include'                  => '',
	'number'                   => '',
	'taxonomy'                 => 'category',
	'pad_counts'               => false 
); 
$categories = get_categories( $args );
?>

戻り値

$category->term_id
$category->name
$category->slug
$category->term_group
$category->term_taxonomy_id
$category->taxonomy
$category->description
$category->parent
$category->count
$category->cat_ID
$category->category_count
$category->category_description
$category->cat_name
$category->category_nicename
$category->category_parent
Pocket