wordpress WordPress でカテゴリーのリストを出力する

2013年4月16日

WordPress でカテゴリーのリストを出力するには、wp_list_categories() を使って簡単に出力できるが、除外するカテゴリーは ID で指定しなければならなかったり、li 要素の前に画像を出力することができなかったりと微調整が難しい。また、毎回「get_categories()」を使って記述するのも面倒くさい。

そこで自前でリストを出力する関数「my_category_list()」を作成する。

出力したい場所に、以下のように記述する。

パラメータの指定は「’excludes=写真, 旅行&show_counts=true’」か「array(‘excludes’ => ‘写真, 旅行’, ‘show_counts’ = > true)」の形式で可能。指定しなければデフォルトの値で表示される。

div 要素にクラスやIDを指定して囲めば、CSS や jQuery の指定もしやすくなる。

<div id="cat_list">
<?php
$args = array(
    'excludes' => '写真, 旅行',    //除外するカテゴリー名
    'image_html' => '<img src="'.get_template_directory_uri() . '/images/arrow-trans.png" width="10" height="10" alt="" />'    //li 要素の前に挿入する画像
  );
my_category_list($args);
?>
</div>

以下を functions.php に記述。

//カテゴリーを表示する関数
function my_category_list($args = array()) {
  //デフォルト値(必要に応じて get_categories() の引数に対応するものを追加したり削除すればよい)
  $defaults = array(
    'parent' => '',  //出力する親カテゴリーの名前またはID(0 を指定すると最上位の全てのカテゴリーを読み込む)
    'include' => '',    //出力するカテゴリー名をカンマで区切って指定。
    'exclude' => '',    //除外するカテゴリー名をカンマで区切って指定。
    'hide_empty' => 0,    //記事(投稿)のないカテゴリーも読み込むかどうか(0:読み込む、1:読み込まない)
    'show_counts' => false,     //記事(投稿)の件数を表示するかどうか
    'show_children' => false,   //子カテゴリーを出力するかどうか
    'show_ancestor' => false,   //孫カテゴリー(以下)を出力するかどうか
    'orderby' => 'name',  //並べ替えのキー id, slug, name, count
    'order' => 'ASC',  //並べ替えの順序 'ASC'または'DESC'
    'image_html' => '',  //挿入する画像のHTML 例:'<img src="'.get_template_directory_uri().'/images/arrow.png" width="10" height="10" alt=""/>'
  );
  $args = wp_parse_args( $args, $defaults );    //パラメータを解析し、省略されたパレメータにはデフォルト値をセット
  extract( $args, EXTR_SKIP );    //キーを変数名、値を変数の値として処理
  
  if(!is_numeric($parent)) {  //親カテゴリーはIDでも名前でも指定可能なため、数値以外はIDに変換
    $parent = get_cat_ID(trim($parent)); 
  }
  
  $include = explode(',', $include);
  $include_ids = '';    //インクルードするカテゴリーIDのリスト(カンマ区切りの文字列)
  $count = count($include);
  if($count) {
    for($i=0; $i < $count; $i++) {    //カテゴリー名からカテゴリーIDを取得
      $include_ids .= get_cat_ID(trim($include[$i]));    //カテゴリー名の前後に空白がある可能性があるので取り除く
      if($i != $count-1) {
        $include_ids .= ',';    //最後の要素以外はカンマで区切る
      }
    }
  }
  
  $exclude = explode(',', $exclude);
  $exclude_ids = '';    //除外するカテゴリーIDのリスト(カンマ区切りの文字列)
  $count = count($exclude);
  if($count) {
    for($i=0; $i < $count; $i++) {    //カテゴリー名からカテゴリーIDを取得
      $exclude_ids .= get_cat_ID(trim($exclude[$i]));    //カテゴリー名の前後に空白がある可能性があるので取り除く
      if($i != $count-1) {
        $exclude_ids .= ',';    //最後の要素以外はカンマで区切る
      }
    }
  }
  
  $cats = get_categories(array(  //以下のパラメータで指定したカテゴリーオブジェクトの配列を変数に代入
    'parent' => $parent,  //親カテゴリーのIDの指定
    'hide_empty' => $hide_empty,  //記事(投稿)のないカテゴリーも読み込むかどうか
    'include' => $include_ids,  //インクルードするカテゴリーIDのリスト
    'exclude' => $exclude_ids,  //除外するカテゴリーIDのリスト
    'orderby' => $orderby,  //並べ替えのキー
    'order' => $order  //並べ替えの順序
  ));
  
  if(count($cats)) {  //カテゴリーがある時だけ、以降の処理を行う
    echo "<ul>\n";
    foreach($cats as $cat) {
      echo '<li>';
      if($image_html != '') echo $image_html;  //画像の指定があれば挿入
      echo '<a href=" ' .get_category_link($cat->term_id) . ' ">' . $cat->name . '';  //カテゴリーのリンクと名前を出力
      echo $show_counts  ? '<span>(' . $cat->count . ")</span></a>\n" :  "</a>\n";  //$show_countsが真の場合は件数を出力
      if($show_children){
        //現在処理中のカテゴリー名、挿入する画像、子孫カテゴリー出力の有無を渡して再起呼び出し
        my_category_list(array(
          'parent' => $cat->name, 
          'image_html' => $image_html, 
          'show_children' => $show_ancestor
        ));  
      }
      echo "</li>\n";
    }
    echo "</ul>\n";
  }
}

上記のように、画像を指定すれば jQuery を使ってマウスオーバー時に画像を表示するなどができる。wp_list_categories() を使っても、CSS で li 要素の背景画像を指定して、jQuery で背景画像を表示・非表示にできるが、その際に画像のパスをフルパスで指定しなければならない。この方法だと画像を挿入するので、jQuery では単に「display」を「none」と「block」に切り替えるでけですむ。

以下はその例。

jQuery(document).ready(function($) { 
    
  $('#cat_list ul li img').css('display', 'none');
  
  $('#cat_list ul li a').hover(
    function() {
      $(this).parent().find('img').css('display', 'block');
    },
    function() {
      $(this).parent().find('img').css('display', 'none');

    });

  imgHeight = $('#cat_list ul li img').outerHeight(false);
  liHeight = $('#cat_list ul li').outerHeight(false);
  $('#cat_list ul li img').css('top',(liHeight - imgHeight)/2+'px');
});

また CSS では以下を指定。
#cat_list ul li {
  margin-left: 20px;
  position: relative;  
}
#cat_list ul li img { 
  float: left;
  position: absolute;
}

もう少し汎用的なリンクの出力はこちら「タームの名前(スラッグ)から ID を取得」を参照。