WordPress でパンくずリスト(Breadcrumbs)をプラグインなしで配置する方法を紹介します。
カスタム投稿タイプやカスタム タクソノミーにも対応していて、ほとんどのケースにおいてそのまま使用できると思います。
出力される HTML は、Bootstrap3 や Foundation5/6 の Breadcrumbs スタイルに準拠した形式となっています。
functions.php
まずは、functions.php などに下記のコードを記述します。
/**
* パンくずリストのアイテムの配列を取得します。
*
* @since 1.0.0
* @since 1.1.0
*
* @param array $args Arguments to retrieve breadcrumb.
* @return array Breadcrumb items.
*/
function get_breadcrumb_items( $args ) {
global $wp_query;
global $post;
$items = array();
if ( is_front_page() ) {
if ( $args['home'] ) {
$items[] = array( 'title' => $args['home_template'], 'link' => false );
}
return $items;
}
if ( $args['home'] ) {
$items[] = array( 'title' => $args['home_template'], 'link' => home_url( '/' ) );
}
$post_type = get_post_type();
if ( 'post' === $post_type && ! is_search() ) {
if ( $blog_id = get_option( 'page_for_posts' ) ) {
$items[] = array( 'title' => get_the_title( $blog_id ), 'link' => get_page_link( $blog_id ) );
}
} else {
if ( is_post_type_archive() ) {
$items[] = array( 'title' => post_type_archive_title( null, false ), 'link' => false );
}
}
if ( is_home() ) {
/*
* Blog homepage page.
*/
$items[] = array( 'title' => wp_title( '', false ), 'link' => false );
} elseif ( is_single() ) {
/*
* Single Post page.
*/
$post_type = get_post_type( $post->ID );
if ( 'post' === $post_type ) {
/*
* Post page.
*/
if ( $cats = get_the_category( $post->ID ) ) {
$current_cat = null;
foreach ( $cats as $cat ) {
if ( ! $current_cat || cat_is_ancestor_of( $current_cat, $cat ) ) {
$current_cat = $cat;
}
}
if ( $current_cat->parent ) {
$ancestor_cat_ids = array_reverse( get_ancestors( $current_cat->cat_ID, 'category' ) );
foreach ( $ancestor_cat_ids as $cat_id ) {
$items[] = array( 'title' => get_cat_name( $cat_id ), 'link' => get_category_link( $cat_id ) );
}
}
$items[] = array( 'title' => get_cat_name( $current_cat->cat_ID ), 'link' => get_category_link( $current_cat->cat_ID ) );
}
} else {
/*
* Custom Post Type page.
*/
$post_type_object = get_post_type_object( $post->post_type );
if ( false !== $post_type_object->has_archive ) {
$items[] = array( 'title' => $post_type_object->labels->name, 'link' => get_post_type_archive_link( get_post_type() ) );
}
}
$strtitle = the_title( '', '', false );
if ( ! isset( $strtitle ) || $strtitle == '' ) {
$strtitle = $post->ID;
}
$items[] = array( 'title' => $strtitle, 'link' => false );
} elseif ( is_category() ) {
/*
* Category archive page.
*/
$cat = get_queried_object();
if ( $cat->parent ) {
$ancestor_cat_ids = array_reverse( get_ancestors( $cat->cat_ID, 'category' ) );
foreach ( $ancestor_cat_ids as $cat_id ) {
if ( ! in_array( $cat_id, $args['exclude_categorys'] ) ) {
$items[] = array( 'title' => get_cat_name( $cat_id ), 'link' => get_category_link( $cat_id ) );
}
}
}
$items[] = array( 'title' => $cat->cat_name, 'link' => false );
} else if ( is_tag() ) {
/*
* Tag archive page.
*/
$tag_id = get_query_var( 'tag_id' );
$tag = get_tag( $tag_id );
if ( $tag ) {
$items[] = array( 'title' => $tag->name, 'link' => false );
}
} elseif ( is_tax() ) {
/*
* Taxonomy archive page.
*/
$query_obj = get_queried_object();
$post_types = get_taxonomy( $query_obj->taxonomy )->object_type;
$cpt = $post_types[0];
$items[] = array( 'title' => get_post_type_object( $cpt )->label, 'link' => get_post_type_archive_link( $cpt ) );
$taxonomy = get_query_var( 'taxonomy' );
$term = get_term_by( 'slug', get_query_var( 'term' ), $taxonomy );
if ( is_taxonomy_hierarchical( $taxonomy ) && $term->parent != 0 ) {
$ancestors = array_reverse( get_ancestors( $term->term_id, $taxonomy ) );
foreach ( $ancestors as $ancestor_id ) {
$ancestor = get_term( $ancestor_id, $taxonomy );
$items[] = array( 'title' => $ancestor->name, 'link' => get_term_link( $ancestor, $term->slug ) );
}
}
$items[] = array( 'title' => $term->name, 'link' => false );
} elseif ( is_year() ) {
/*
* Year archive page.
*/
$items[] = array( 'title' => get_the_time( _x( 'Y', 'breadcrumb year format', 'jp-for-twentytwentyone' ) ), 'link' => false );
} elseif ( is_month() ) {
/*
* Month archive page.
*/
$items[] = array( 'title' => get_the_time( _x( 'Y', 'breadcrumb year format', 'jp-for-twentytwentyone' ) ), 'link' => get_year_link( get_the_time( 'Y' ) ) );
$items[] = array( 'title' => get_the_time( _x( 'F', 'breadcrumb month format', 'jp-for-twentytwentyone' ) ), 'link' => false );
} elseif ( is_date() ) {
/*
* Date archive page.
*/
$items[] = array( 'title' => get_the_time( _x( 'Y', 'breadcrumb year format', 'jp-for-twentytwentyone' ) ), 'link' => get_year_link( get_the_time( 'Y' ) ) );
$items[] = array( 'title' => get_the_time( _x( 'F', 'breadcrumb month format', 'jp-for-twentytwentyone' ) ), 'link' => get_month_link( get_the_time( 'Y' ), get_the_time( 'm' ) ) );
$items[] = array( 'title' => get_the_time( _x( 'd', 'breadcrumb day format', 'jp-for-twentytwentyone' ) ), 'link' => false );
} elseif ( is_page() ) {
/*
* Single page.
*/
$post = $wp_query->get_queried_object();
if ( $post->post_parent == 0 ) {
$items[] = array( 'title' => get_the_title( '', '', true ), 'link' => false );
} else {
$ancestors = array_reverse( get_post_ancestors( $post->ID ) );
array_push( $ancestors, $post->ID );
foreach ( $ancestors as $ancestor ) {
$strtitle = get_the_title( $ancestor );
if ( ! isset( $strtitle ) || $strtitle == '' ) {
$strtitle = $post->ID;
}
if ( $ancestor != end( $ancestors ) ) {
$items[] = array( 'title' => strip_tags( apply_filters( 'single_post_title', $strtitle ) ), 'link' => get_permalink( $ancestor ) );
} else {
$items[] = array( 'title' => strip_tags( apply_filters( 'single_post_title', $strtitle ) ), 'link' => false );
}
}
}
} elseif ( is_search() ) {
/*
* Search page.
*/
$items[] = array( 'title' => __( 'Search Results', 'jp-for-twentytwentyone' ), 'link' => false );
} elseif ( is_404() ) {
/*
* 404 page.
*/
$items[] = array( 'title' => __( '404', 'jp-for-twentytwentyone' ), 'link' => false );
}
return $items;
}
/**
* パンくずリストを取得します。
*
* @since 1.0.0
* @since 1.1.0
*
* @param array $args Optional. Arguments to retrieve breadcrumb.
* @return string Breadcrumb html.
*/
function get_breadcrumb( $args = array() ) {
$defaults = array(
'before' => '<nav id="breadcrumb" role="navigation" class="alignwide">',
'after' => '</nav>',
'home' => true,
'home_template' => 'HOME',
'exclude_categorys' => array()
);
$args = wp_parse_args( $args, $defaults );
$items = get_breadcrumb_items( $args );
$html = $args['before'];
$html .= '<ul itemscope itemtype="https://schema.org/BreadcrumbList" class="breadcrumbs">';
foreach ( $items as $index => $item ) {
$html .= '<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">';
if ( $item['link'] ) {
$html .= '<a itemprop="item" href="' . $item['link'] . '"><span itemprop="name">' . $item['title'] . '</span></a>';
} else {
$html .= '<span itemprop="name">' . $item['title']. '</span>';
}
$html .= '<meta itemprop="position" content="' . ( $index + 1 ) . '" />';
$html .= '</li>';
}
$html .= '</ul>';
$html .= $args['after'] . "\n";
return $html;
}
/**
* パンくずリストを表示します。
*
* @since 1.0.0
*
* @param array $args Optional. Arguments to retrieve breadcrumb.
* @return void
*/
function breadcrumbs( $args ) {
echo get_breadcrumb( $args );
}
テンプレート ファイル
あとは、表示したい場所に下記のコードを記述します。
<?php breadcrumbs(); ?>
breadcrumbs はパラメータで条件を指定できます。使い方は下記のとおりです。
breadcrumbs テンプレートタグの使い方
<?php breadcrumbs( $args ); ?>
パラメータ
$args に指定された条件に基づいてパンくずリストを表示します。 以下に示す引数のリストを $args に入れるとデフォルトを上書きできます。
引数 | デフォルト | 説明 |
---|---|---|
before | ‘<nav id=”breadcrumb” role=”navigation” class=”alignwide”>’ | 全体の前のテキストです。 |
after | ‘</nav>’ | 全体の後のテキストです。 |
home | true | ホームを表示するかどうかです。 |
home_template | ‘HOME’ | ホームのテキストです。 |
exclude_categorys | array() | カテゴリーから除外するカテゴリー ID の配列です。 |
CSS
Bootstrap や Foundation のスタイルを使用しない場合の CSS の例です。
ul.breadcrumbs {
list-style: none;
margin: .25rem 0 .5rem;
font-size: 0.95rem;
}
ul.breadcrumbs li {
display: inline-block;
}
ul.breadcrumbs li:not(:last-child)::after {
color: #cacaca;
content: ">";
margin: 0 .25rem;
}