Cocoonでカスタム投稿タイプのパンくずリストとカテゴリ表示する方法

Cocoonでサイト作成する機会があり、詰まったところがあったので備忘録として残しておきます。

やりたいことは、カスタム投稿タイプの追加した際の以下の問題点の改善。

  • カテゴリ(ターム名)が表示されない
  • パンくずリストが表示されない

今回、子テーマを編集することで問題を無事解決することができました。

この記事で以下のことが出来るようになります。

  • パンくずリストの表示(階層バッチリ!)
  • 親ターム・子タームの表示
  • コアのタグを使って通常投稿と混ぜて表示

カスタム投稿タイプは、プラグイン「Custom Post Type UI」を利用しています。

目次

まず完成形がこちら

カスタム投稿タイプのアーカイブページで、パンくずリスト、ターム(カテゴリ)のラベルが問題なく表示されています。

デザインはCSSで独自のカードタイプに調整しました。

カテゴリ別(ターム別)に分けて表示することも可能です。

新規をクリックした状態
その他をクリックした状態

投稿ページのパンくずリスト、ターム表示も完璧です。

前提条件

前提条件として以下の構成で作成しています。

カスタム投稿タイプの設定

Custom Post Type UIで以下のように設定しました。

追加項目ラベルスラッグ
カスタム投稿タイプ制作実績works
カスタムタクソノミー制作ジャンルgenre

プラグインの使い方は省略しますが、投稿タイプの追加と編集で「アーカイブあり」が“偽”になっていると一覧は表示されませんので“真”にしておきます

その他

  • パンくずリストの配置は「メインカラム手前」に設定
  • 編集するのは全て子テーマの方
  • Cocoonバージョン: 2.5.5(2022年1月時点最新)
  • コードの行数は目安

便宜上、以下のように表記揺れがあることをご了承ください。

  • 一覧ページ=アーカイブページ
  • 投稿ページ=個別記事ページ
  • カテゴリ=タクソノミー
  • カスタム分類=カスタムタクソノミー

テンプレート階層の確認

今回Cocoonで使用するテンプレートファイルと、テンプレート階層の確認をしておこうと思います。

投稿ページ

命名規則と優先順位

  1. single-(投稿タイプスラッグ).php
  2. single.php
  3. singular.php
  4. index.php

Cocoonでは通常の投稿ページを、single.phpで表示しています。

カスタム投稿タイプの投稿ページを表示するために、single-(投稿タイプスラッグ).phpを作成します。

一覧ページ

命名規則と優先順位

  1. archive-(投稿タイプスラッグ).php
  2. archive.php
  3. index.php

Cocoonでは通常の一覧ページを、index.phpで表示しています。

カスタム投稿タイプの一覧ページを表示するために、archive-(投稿タイプスラッグ).phpを作成します。

カスタム分類ページ

命名規則と優先順位

  1. taxonomy-(タクソノミースラッグ)-(タームスラッグ).php
  2. taxsonomy-(タクソノミースラッグ).php
  3. taxsonomy.php
  4. archive.php
  5. index.php

Cocoonではカテゴリページを、index.phpで表示しています。

カスタム投稿タイプのカテゴリ(タクソノミー)ページを表示するために、taxsonomy-(タクソノミースラッグ).phpを作成します。

各ページの作成

カスタム投稿タイプ用に、以下の3つのテンプレートファイルを作ります。

  • single-works.php→(投稿ページ用)
  • archive-works.php→(一覧ページ用)
  • taxonomy-genre.php→(カスタム分類ページ用)

青字はスラッグです。

投稿ページを作成

カスタム投稿タイプの個別ページ

通常の投稿ページで使われているsingle.phpを複製して、single-works.php(投稿ページ)を作成します。

手順

  1. 親テーマのsingle.phpを子テーマにコピー
  2. コピーしたsingle.phpsingle-(投稿タイプスラッグ).phpに名称変更

カスタム投稿タイプ・カスタム分類の一覧ページを作成

カスタム投稿タイプの一覧ページ
カスタム分類の一覧ページ

通常の一覧ページ・カテゴリページで使われているindex.phpを複製して、archive-works.php(一覧ページ)とtaxonomy-genre.php(カスタム分類ページ)を作成します。

※同じようなデザインになっているため分かりにくいですが、それぞれ独立した別のページとなります。

手順

  1. 親テーマのindex.phpを子テーマにコピー
  2. archive-(投稿タイプスラッグ).phpに名称変更
  3. もう一度index.phpを子テーマにコピー
  4. taxonomy-(タクソノミースラッグ).phpに名称変更

以上でカスタム投稿タイプ関連のページを作ることができました。

どのテンプレートファイルが使われているか確認するには

Show Current Templateというプラグインを使えば、現在表示されているページはどのテンプレートファイルが使われているのかを知ることができます。

有効化すると、管理バー(アドミンバー)に現在使われているテンプレートファイル名が表示されます。

タイトルを変更

デフォルトの状態だとタイトルが以下のようになっています。

  • カスタム投稿タイプの一覧ページ→「Archive
  • カスタム分類の一覧ページ→「ターム名

どちらも「Works」というタイトルに統一したいのでfunctions.phpに以下のコードを記述しタイトルを書き換えます。

////////////////////////////
//カスタム投稿一覧のタイトル
////////////////////////////
function custom_archive_title( $title ){
  if ( is_post_type_archive('works') || is_tax('genre')) {
    // ↓ラベルを出力する場合
    // $title = (get_post_type_object(get_post_type())->label);
    // ↓スラッグを出力する場合
    // $title = (get_post_type_object(get_post_type())->name);
    // ↓任意のタイトルにする場合
    $title = 'Works';
  }
return $title;
}
add_filter( 'get_archive_chapter_title', 'custom_archive_title', 10 );

ラベル、スラッグ、任意を選べるようにしています。

あると便利!
ターム別ナビゲーションの作成

一覧ページのタイトルの下に、ターム別に表示させるためのナビゲーション(ジャンルナビ)を作成します。

例:以下のようなリンクです。

すべて ターム1 ターム2 ターム3

これがあるとワンクリックでターム別に表示することができて便利です。

手順

  1. 子テーマにtmpディレクトリを作成
  2. 親テーマのtmp/list.phpを子テーマのtmpの中にコピーします。

コピーしたtmp/list.phpの「インデックストップ広告」の上に、ジャンルナビのコードを追加します。
(最初の?>から<?phpまで)

////////////////////////////
// カスタム投稿のジャンルナビ追加
////////////////////////////
?><!-- カスタム投稿アーカイブのジャンルナビ -->
<?php if (is_post_type_archive('works')) : ?>
 <div class="genre-nav">
  <div class="genre-nav-link"><a class="is-active" href="<?php echo esc_url( get_post_type_archive_link( 'works' ) ); ?>">すべて</a></div><!-- /.genre-nav-link -->
  <?php
    $genre_terms = get_terms( 'genre', array( 'hide_empty' => false, 'orderby'=> 'id', 'parent' => 0) );
    foreach ( $genre_terms as $genre_term ) :
  ?>
  <div class="genre-nav-link"><a href="<?php echo esc_url( get_term_link( $genre_term, 'genre' ) ); ?>"><?php echo esc_html( $genre_term->name ); ?></a></div><!-- /.genre-nav-link -->
  <?php
    endforeach;
  ?>
</div><!-- /.genre-nav -->
<?php endif; ?>

<!-- カスタムタクソノミーアーカイブのジャンルナビ追加 -->
<?php if (is_tax('genre')) : ?>
<div class="genre-nav">
  <div class="genre-nav-link"><a  href="<?php echo esc_url( get_post_type_archive_link( 'works' ) ); ?>">すべて</a></div><!-- /.genre-nav-link -->
  <?php $cat = get_queried_object();
  $cat_name = $cat -> name;
  $genre_terms = get_terms( 'genre', array( 'hide_empty' => false, 'orderby'=> 'id', 'parent' => 0) );
  foreach ( $genre_terms as $genre_term ) :
  ?>
  <div class="genre-nav-link">
    <a class="<?php if( $cat_name == esc_html( $genre_term->name ) ) {	echo "is-active";
      } ?>" href="<?php echo esc_url( get_term_link( $genre_term, 'genre' ) ); ?>"><?php echo esc_html( $genre_term->name ); ?></a></div><!-- /.genre-nav-link -->
  <?php
  endforeach;
  ?>
</div><!-- /.genre-nav -->
<?php endif; ?><?php

////////////////////////////
//インデックストップ広告
////////////////////////////

これでタイトル下にジャンルナビを追加することが出来ました。

コードを簡単に説明すると、1つ目(上)のコードはカスタム投稿タイプの一覧ページ用で、作成した全てのタームを出力するようにしています。

2つ目(下)のコードはカスタム分類の一覧ページ用で、現在のページと一致している場合にis-activeを付与するようにしています。

cssのカスタマイズ例
/* ジャンルナビ */
.genre-nav {
	display: flex;
	gap: 16px;
	margin-top: 40px;
	margin-bottom: 60px;
	justify-content: center;
	white-space: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

@media screen and (max-width: 1023px) {
	.genre-nav {
	margin-top: 20px;
	margin-bottom: 30px;
	}
}

/* スクロールで左にはみ出さないように左寄せ */
@media screen and (max-width: 480px) {
	.genre-nav {
	justify-content: start;
	}
}

.genre-nav::-webkit-scrollbar {
	display: none;
}

.genre-nav-link a {
	color: #888;
	font-weight: bold;
	padding: 4px 20px;
	text-decoration: none;
	display: inline-block;
	border-bottom: 2px solid transparent;
	transition: border .3s, color .3s;
}

@media screen and (max-width: 480px) {
	.genre-nav-link {
		width: 100%;
	}
	
	.genre-nav-link a {
		font-size: 14px;
		margin-right: 0;
		margin-bottom: 8px;
		padding-left: 0;
		padding-right: 0;
		width: 100%;
		text-align: center;
	}
}

.genre-nav-link a:hover,
.genre-nav-link .is-active {
	border-bottom: 2px solid;
	color: #333;
}

以上でページ作成は完了です。

次にパンくずリストとカテゴリータグを表示させるため、一覧ページの構造について解説していきます。

一覧ページの構造の説明

Cocoonでは細かくパーツ化されており、以下のそれぞれのパーツファイルを編集する必要があります。

親テーマから、以下のファイルを子テーマのtmpにコピーします。

  • tmp/body-top.php
  • tmp/breadcrumbs.php
  • tmp/entry-card.php
パンくずリストが「フッター手前」の場合

パンくずリストを「フッター手前」にしている場合はfooter.phpを子テーマにコピーして同様に編集します。

パンくずリストが「メインカラムトップ」「メインカラムボトム」の場合

tmp/list.phpを同様に編集します。

パンくずリストを作成

body-top.phpを編集

「メインカラム手前」でパンくずリストのパーツが適用されるように編集します。

パンくずリストの位置がどこであっても、編集方法はほぼ同じです。

「投稿パンくずリストがメイン手前の場合」の分岐(50行目)に、is_tax(),is_post_type_archive()を追加します。

<!-- カスタム投稿タイプ追加	 -->
<?php //投稿パンくずリストがメイン手前の場合
if ((is_single() || is_category() || is_tax() || is_post_type_archive()) && is_single_breadcrumbs_position_main_before()){
  get_template_part('tmp/breadcrumbs');
} ?>

これでbreadcrumbs.phpが適用されるようになりました。

breadcrumbs.phpを編集

次にパンくずリストのパーツであるbreadcrumbs.phpを編集します。

まずコード全体をカスタム投稿タイプに適用させるため、分岐タグを追加します。

breadcrumbs.phpの最初の分岐(10行目)にis_tax(),is_post_type_archive()を追加します。

if (is_single_breadcrumbs_visible() && (is_single() || is_category() || is_tax() || is_post_type_archive())){
  $cat = null;
  //投稿ページの場合

変数を書き換え

// 「投稿ページの場合」の$cats(14行目)
$cats = get_the_category();
↓
$cats = get_the_terms($post->ID,array('category','genre'));

// 「メインカテゴリがない場合は先頭のカテゴリを適用」の$cat(24行目)
$cat = (is_single() && isset($cats[0])) ? $cats[0] : get_category(get_query_var("cat"));
↓
$cat = (is_single() && isset($cats[0])) ? $cats[0] : get_queried_object();

// 「カテゴリ情報の取得」の手前の$par(34行目)
$par = get_category($cat->parent);
↓
$par = get_term($cat->parent);

// 「カテゴリ情報の取得」の下の$par(39行目)
$par = get_category($par->parent);
↓
$par = get_term($cat->parent);

$catsのarrayにはcategory(通常投稿で使われているスラッグ)に加え、必要なタクソノミースラッグを入力。

これでパンくずリストが機能するようになったはずです。

カスタム投稿タイプのパンくずを追加

カスタム分類ページと投稿ページを見ると「ホーム > 新規」になっていて階層が分かりづらいので、間にカスタム投稿タイプの「パンくず」を追加します。

  • 現在:「ホーム > 新規」
  • 目標:「ホーム > 制作実績 > 新規」

「カテゴリの順番の入れ替え」の下に「カスタム投稿タイプのパンくずを追加」のコードを書き加えます。

    //カテゴリの順番入れ替え
    $cats = array_reverse($cats);
    
    //カスタム投稿タイプのパンくずを追加
    if(is_tax() || is_single() && !is_singular('post')) {
      ++$count;
      $echo .= '<div class="breadcrumb-item" itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement"><span class="fa fa-folder fa-fw" aria-hidden="true"></span><a href="'.esc_url(get_post_type_archive_link( get_post_type() )).'" itemprop="item"><span itemprop="name" class="breadcrumb-caption">'.esc_html(get_post_type_object(get_post_type())->name).'</span></a><meta itemprop="position" content="'.$count.'" /><span class="sp"><span class="fa fa-angle-right" aria-hidden="true"></span></span></div>';
    }

もし、表示をラベルからスラッグに変更したい場合は、esc_htmlコード内のlabelnameに書き換えればOKです。

WorksやWORKSなど、大文字の指定はCSSで調整できます。

一覧ページのパンくずをラベルに変更する方法

カスタム投稿タイプの一覧ページでは「ホーム > works」となっており、「ホーム > 制作実績」にラベル表示したい場合は少し編集が必要です。

「現カテゴリの出力」の箇所に変数を加え、htmlに定義した変数を置き換えます。

// 現カテゴリの出力
//カスタム投稿一覧ページのパンくずをラベルに変更
if(is_post_type_archive()){
  $name = 'label';
} else {
  $name = 'name';
}

…省略…
// nameを変数に書き換える
esc_html($cat->name)
↓
esc_html($cat->$name)

カスタム投稿タイプの一覧ページでは変数にlabelを代入して、htmlの中のnameを変数$nameに変更しました。

参考

カスタム投稿タイプの一覧ページでget_queried_object()から取得できる値

  • label→カスタム投稿タイプ名
  • name→スラッグ

以上で、パンくずリストが全て完成しました。

カテゴリ名(ターム)を表示させる

個別ページにタームを表示

カスタム投稿タイプの個別ページ

functions.phpに以下のコードを書き加えます。

////////////////////////////
//ターム(カテゴリ)リンクの取得
////////////////////////////
//カテゴリーリンクの取得
if ( !function_exists( 'get_the_category_links' ) ):
 function get_the_category_links(){
  // 取得するタクソノミー(categoryはデフォルト)
  $taxonomies = [ 'category', 'genre' ];
  $categories = null;
  foreach ( $taxonomies as $taxonomy_slug ){
      $terms = get_the_terms( get_the_ID(), $taxonomy_slug );
      if(!empty($terms) && !is_wp_error($terms)){
          foreach($terms as $term){
              $style = null;
              $categories .= '<a class="cat-link cat-link-'.$term->term_id.'" href="'.get_term_link( $term->slug, $taxonomy_slug ).'"'.$style.'><span class="fa fa-folder cat-icon tax-icon" aria-hidden="true"></span>'.$term->name.'</a>';
          }
      }
  }
  return $categories;
}
endif;

get_the_category_linksでカテゴリーのみの取得しかしていなかったものを、カテゴリーとタクソノミーの両方を取得できるよう編集にしました。

追加したいタクソノミーがあれば、[ 'category', 'genre' ]を編集します。

一覧ページにタームを表示

tmp/entry-card.phpの「サムネイルを持っていないとき」の下に、タームラベル表示用のコードを追加します。

      <?php else: // サムネイルを持っていないとき ?>
        <?php echo get_entry_card_no_image_tag($count); ?>
      <?php endif; ?>
    
      <!-- 追加:カスタム投稿タイプのタームラベルを表示 -->
      <?php
      if (has_term('','genre') && (is_tag() || is_tax() || is_post_type_archive())): ?>
      <span class="cat-label cat-label-<?php echo get_the_terms( get_the_ID(), 'genre' )[0]->term_id; ?>"><?php echo esc_html( get_the_terms( get_the_ID(), 'genre' )[0]->name ); ?></span>
      <?php endif ?>

has_term()は第2因数であるタクソノミースラッグが必須なので、「genre」を入れています。

Cocoonで定義されているthe_nolink_categoryではカスタムタクソノミーのタームは取得出来ないため、htmlを直書きし先頭のタームを出力するようにしました。

functions.phpで編集する方法があればそちらの方が楽かも…?

以上で、投稿ページと一覧ページにタームを表示することが出来ました。

カスタム投稿にコアのタグを使う場合

カスタム投稿タイプにも通常投稿にも東京という同じコアのタグをつけた場合、東京タグ一覧ページには通常の投稿しか表示されません。

functions.phpに以下のコードで、カスタム投稿タイプも混ぜて表示することが可能です。

// タグアーカイブをカスタム投稿タイプとまとめて表示
function my_main_query( $query ) {
  if ( is_admin() || ! $query->is_main_query() )
    return;

  if ( $query->is_category() || $query->is_tag() ) {
    $query->set( 'post_type', array( 'post', 'works' ) );
    return;
  }
}
add_action( 'pre_get_posts', 'my_main_query' );

array( 'post', 'post_type1' )post_type1にはカスタム投稿タイプのスラッグを入力します。

この方法は以下の記事で知りました。
(ありがとうございます)

カスタム投稿タイプのページ作成まとめ

Cocoonは元々カスタム投稿タイプの利用は想定されていないため、自身でカスタマイズする他ありません。

ググっても詳しいコードが出てこなかったために、自分で作成した次第です。

今回は

  • single-works.php→(投稿ページ用)
  • archive-works.php→(一覧ページ用)
  • taxonomy-genre.php→(カスタム分類ページ用)

と3つのカスタム投稿タイプのページを作成し、パンくずリストとターム(カテゴリ)表示させる方法を解説しました。

もしテーマの大型アップデートで、構造が変われば見直す必要があります。

もし、これよりも簡単簡潔に実装できる方法があれば共有していただければ幸いです…!

あと少しのカスタマイズでお困りではないですか?

スキルを身につけるなら、デイトラがおすすめです。

管理人

私はWeb制作とWebデザインを受講しました!

業界最安値で、学習内容もサポートも充実!
気になるコースがあれば是非覗いてみてください。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

目次