wordpress WordPress でパンくずリストを出力する

2013年4月15日

プラグインを使わずに、パンくずリストを出力する方法。

以下のサイトにとても丁寧でわかりやすい解説があったので、それを元にカスタム投稿タイプやカスタムタクソノミーにも対応するように、このサイト用に作成してみたもの。

パンくずリストを作ってみるとWordPress でのサイト構築のコツがつかめるかもしれない(Web Design Recipes)

パラメータの指定は「’home=Top&class=list’」または「array(‘home’ => ‘Top’, ‘class’ = > ‘list’)」の形式で可能。指定しなければデフォルトの値で表示される。

//パンくずリストを出力する関数
function breadcrumbs($args = array()){
global $post;
$str ='';
$defaults = array(
  'id' => "breadcrumbs",
  'class' => "clearfix",
  'home' => "Home",
  'search' => "で検索した結果",
  'tag' => "タグ",
  'author' => "投稿者",
  'notfound' => "404 Not found",
  'separator' => ' > '
);
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
if(is_home()) {
  echo  '<div id="'. $id .'" class="' . $class.'" >'.'<ul><li>'. $home .'</li></ul></div>';
}
if(!is_home()&&!is_admin()){ //!is_admin は管理ページ以外という条件分岐
  $str.= '<div id="'. $id .'" class="' . $class.'" >';
  $str.= '<ul>';
  $str.= '<li><a href="'. home_url() .'/">'. $home .'</a></li>';
  $str.= '<li>'.$separator.'</li>'; 
  $my_taxonomy = get_query_var('taxonomy');  //[taxonomy] の値(タクソノミーのスラッグ)
  $cpt = get_query_var('post_type');   //[post_type] の値(投稿タイプ名)
  if($my_taxonomy &&  is_tax($my_taxonomy)) {//カスタム分類のページ
    $my_tax = get_queried_object();  //print_r($my_tax);
    $post_types = get_taxonomy( $my_taxonomy )->object_type;
    $cpt = $post_types[0];  //カスタム分類名からカスタム投稿名を取得。
    $str.='<li><a href="' .get_post_type_archive_link($cpt).'">'. get_post_type_object($cpt)->label.'</a></li>';  //カスタム投稿のアーカイブへのリンクを出力
    $str.='<li>'.$separator.'</li>'; 
  if($my_tax -> parent != 0) {  //親があればそれらを取得して表示
    $ancestors = array_reverse(get_ancestors( $my_tax -> term_id, $my_tax->taxonomy ));
    foreach($ancestors as $ancestor){
      $str.='<li><a href="'. get_term_link($ancestor, $my_tax->taxonomy) .'">'. get_term($ancestor, $my_tax->taxonomy)->name .'</a></li>';
      $str.='<li>'.$separator.'</li>';
    }
  }
    $str.='<li>'. $my_tax -> name . '</li>';  
  }elseif(is_category()) {  //カテゴリーのアーカイブページ
    $cat = get_queried_object();
    if($cat -> parent != 0){
      $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' ));
      foreach($ancestors as $ancestor){
        $str.='<li><a href="'. get_category_link($ancestor) .'">'. get_cat_name($ancestor) .'</a></li>';
        $str.='<li>'.$separator.'</li>';
      }
    }
    $str.='<li>'. $cat -> name . '</li>'; 
  }elseif(is_post_type_archive()) {  //カスタム投稿のアーカイブページ
    $cpt = get_query_var('post_type');
    $str.='<li>'. get_post_type_object($cpt)->label . '</li>'; 
  }elseif($cpt && is_singular($cpt)){  //カスタム投稿の個別記事ページ
    $taxes = get_object_taxonomies( $cpt  );
    $mytax = $taxes[0];  
    $str.='<li><a href="' .get_post_type_archive_link($cpt).'">'. get_post_type_object($cpt)->label.'</a></li>';  //カスタム投稿のアーカイブへのリンクを出力
    $str.='<li>'.$separator.'</li>';
    $taxes = get_the_terms($post->ID, $mytax); 
    $tax = get_youngest_tax($taxes, $mytax );  //print_r($tax);
    if($tax -> parent != 0){
      $ancestors = array_reverse(get_ancestors( $tax -> term_id, $mytax ));
      foreach($ancestors as $ancestor){
        $str.='<li><a href="'. get_term_link($ancestor, $mytax).'">'. get_term($ancestor, $mytax)->name . '</a></li>';
        $str.='<li>'.$separator.'</li>';
      }
    }
    $str.='<li><a href="'. get_term_link($tax, $mytax).'">'. $tax -> name . '</a></li>';  
    $str.='<li>'.$separator.'</li>';
    $str.= '<li>'. $post -> post_title .'</li>';
  }elseif(is_single()){  //個別記事ページ
    $categories = get_the_category($post->ID);
    $cat = get_youngest_cat($categories);
    if($cat -> parent != 0){
      $ancestors = array_reverse(get_ancestors( $cat -> cat_ID, 'category' ));
      foreach($ancestors as $ancestor){
        $str.='<li><a href="'. get_category_link($ancestor).'">'. get_cat_name($ancestor). '</a></li>';
        $str.='<li>'.$separator.'</li>';
      }
    }
    $str.='<li><a href="'. get_category_link($cat -> term_id). '">'. $cat-> cat_name . '</a></li>';
    $str.='<li>'.$separator.'</li>';
    $str.= '<li>'. $post -> post_title .'</li>';
  } elseif(is_page()){  //固定ページ
    if($post -> post_parent != 0 ){
      $ancestors = array_reverse(get_post_ancestors( $post->ID ));
      foreach($ancestors as $ancestor){
        $str.='<li><a href="'. get_permalink($ancestor).'">'. get_the_title($ancestor) .'</a></li>';
        $str.='<li>'.$separator.'</li>';
      }
    }
    $str.= '<li>'. $post -> post_title .'</li>';
  } elseif(is_date()){  //日付ベースのアーカイブページ
    if(get_query_var('day') != 0){  //年別アーカイブ
      $str.='<li><a href="'. get_year_link(get_query_var('year')). '">' . get_query_var('year'). '年</a></li>';
      $str.='<li>'.$separator.'</li>';
      $str.='<li><a href="'. get_month_link(get_query_var('year'), get_query_var('monthnum')). '">'. get_query_var('monthnum') .'月</a></li>';
      $str.='<li>'.$separator.'</li>';
      $str.='<li>'. get_query_var('day'). '日</li>';
    } elseif(get_query_var('monthnum') != 0){  //月別アーカイブ
      $str.='<li><a href="'. get_year_link(get_query_var('year')) .'">'. get_query_var('year') .'年</a></li>';
      $str.='<li>'.$separator.'</li>';
      $str.='<li>'. get_query_var('monthnum'). '月</li>';
    } else {  //年別アーカイブ
      $str.='<li>'. get_query_var('year') .'年</li>';
    }
  } elseif(is_search()) {  //検索結果表示ページ
    $str.='<li>「'. get_search_query() .'」'. $search .'</li>';
  } elseif(is_author()){  //投稿者のアーカイブページ
    $str .='<li>'. $author .' : '. get_the_author_meta('display_name', get_query_var('author')).'</li>';
  } elseif(is_tag()){  //タグのアーカイブページ
    $str.='<li>'. $tag .' : '. single_tag_title( '' , false ). '</li>';
  } elseif(is_attachment()){  //添付ファイルページ
    $str.= '<li>'. $post -> post_title .'</li>';
  } elseif(is_404()){  //404 Not Found ページ
    $str.='<li>'.$notfound.'</li>';
  } else{  //その他
    $str.='<li>'. wp_title('', true) .'</li>';
  }
  $str.='</ul>';
  $str.='</div>';
  }
  echo $str;
}

69行目の一番下の階層のカテゴリーを返す関数。

//一番下の階層のカテゴリーを返す関数
function get_youngest_cat($categories){
  global $post;
  if(count($categories) == 1 ){
    $youngest = $categories[0];
  }
  else{
    $count = 0;
     foreach($categories as $category){  //それぞれのカテゴリーについて調査
        $children = get_term_children( $category -> term_id, 'category' );  //子カテゴリーの ID を取得
      if($children){  //子カテゴリー(の ID )が存在すれば
        if ( $count < count($children) ){  //子カテゴリーの数が多いほど、そのカテゴリーは階層が下なのでそれを元に調査するかを判定
          $count = count($children);  //$count に子カテゴリーの数を代入
          $lot_children = $children;
          foreach($lot_children as $child){  //それぞれの「子カテゴリー」について調査 $childは子カテゴリーのID
            if( in_category( $child, $post -> ID ) ){  //現在の投稿が「子カテゴリー」のカテゴリーに属するか
              $youngest = get_category($child);  //属していればその「子カテゴリー」が一番若い(一番下の階層)
              }
            }
          }
        }
      else{  //子カテゴリーが存在しなければ
        $youngest = $category;  //そのカテゴリーが一番若い(一番下の階層)
      }
    }
  }
  return $youngest;
}

56行目の一番下の階層のタクソノミーを返す関数

//一番下の階層のタクソノミーを返す関数
function get_youngest_tax($taxes, $mytaxonomy){
  global $post;
  if(count($taxes) == 1 ){
    $youngest = $taxes[key($taxes)];
  }
  else{
     $count = 0;
    foreach($taxes as $tax){  //それぞれのタクソノミーについて調査
      $children = get_term_children( $tax -> term_id, $mytaxonomy );  //子タクソノミーの ID を取得
      if($children){  //子カテゴリー(の ID )が存在すれば
        if ( $count < count($children) ){  //子タクソノミーの数が多いほど、そのタクソノミーは階層が下なのでそれを元に調査するかを判定
          $count = count($children);  //$count に子タクソノミーの数を代入
          $lot_children = $children;
          foreach($lot_children as $child){  //それぞれの「子タクソノミー」について調査 $childは子タクソノミーのID
            if( is_object_in_term( $post -> ID, $mytaxonomy ) ){  //現在の投稿が「子タクソノミー」のタクソノミーに属するか
              $youngest = get_term($child, $mytaxonomy);  //属していればその「子タクソノミー」が一番若い(一番下の階層)
            }
          }
        }
      }
      else{  //子タクソノミーが存在しなければ
        $youngest = $tax;  //そのタクソノミーが一番若い(一番下の階層)
      }
    }
  }
  return $youngest;
}