Cocoon カスタムテンプレート 新着記事だけ全文表示2 備忘録

Cocoon

前回はフロントページにて個別投稿ページのヘッダ内リソース読み込みを行いたくて、固定ページをベースにメインクエリを上書きする方法でカスタムページを作りました。

当時は、lib フォルダ内ファイルの関数をテンプレートからオーバーライドできないと思っていたので、この方法をとったのですが、方法が分かったのでメインクエリを上書きせずに、より自然(たぶん)な方法でカスタムページを作ります。

ついでに、ブログカードを複数列にも対応するようにしています。
2020/9/16 現在、本サイトはこのカスタムテンプレートを使用しています。

スポンサーリンク

変更方法検討

index.php を使用するページが多かったため、フロントページでのみ、新着投稿を全文表示にする方法を検討します。

前回使った、WordPress のホームページ設定を変更することでカスタムページ設定する方法は、解除の際もファイル管理やコード変更などの手間がかからないため採用することにしました。

ただし、前回と違って固定ページ表示ではなく投稿ページ表示設定を使います。
これでメインクエリを上書きせずに済みます。
あとは、フロントページでかつホームページ設定が特定の投稿ページ表示設定の時のみ、新着記事だけ全文表示するテンプレートを使うように場合分けしていきます。

以下の順にテンプレートが読まれているので、

  1. index.php
  2. tmp/list.php
  3. tmp/list-index.php

2. の「tmp/list.php」から分岐させることにします。

実装

全文表示判定関数

新着記事だけ全文表示するかどうかを判定するための条件は以下の通りです。

  • ブログ投稿インデックスページの表示中である
  • ホームページ設定が投稿ページ「full-text」である

これを判定する関数を、テーマフォルダ直下の functions.php に追記します。

functions.php
… 省略 …
// ホームページの表示 > 固定ページ > 投稿ページ > 'full-text' なら true
function is_full_text() {
	if ( is_home() ) {
		$page = get_post( get_option( 'page_for_posts' ) );
		if ( strcmp( $page->post_name, 'full-text' ) === 0 ) {
			return true;
		}
	}
	return false;
}

Cocoon のテーマフォルダ直下の functions.php の変更には注意が必要です。

ファイル内容は以下の通りで、追記をする場合は必ず「//以下に子テーマ用の関数を書く」の次の行以降に追記してください。

<?php //子テーマ用関数
if ( !defined( 'ABSPATH' ) ) exit;

//子テーマ用のビジュアルエディタースタイルを適用
add_editor_style();

//以下に子テーマ用の関数を書く

ここで、「あれ?先頭の『<?php』タグ閉じてなくない?」と思われた場合は、WordPress の PHP コード規約が参考になります。

文末の空白の除去

コードの各行末尾のスペースは削除してください。ファイル末尾の PHP 終了タグの除去は推奨です。終了タグを使用する場合には、その後にスペースがないことを確認してください。

https://ja.wordpress.org/team/handbook/coding-standards/wordpress-coding-standards/php/#%e6%96%87%e6%9c%ab%e3%81%ae%e7%a9%ba%e7%99%bd%e3%81%ae%e9%99%a4%e5%8e%bb

要は、PHP 終了タグで閉じなくてOK!

ヘッダ内リソース読み込み関数のオーバーライド

ソースコードの色分けや画像のポップアップなどのスクリプトは、特定のページでしか読み込まないように設計されているので、全文表示判定のときも読み込むように関数オーバーライドします。

オーバーライド元の関数は以下の3つです。
(関数名 : ファイル)

  • wp_enqueue_highlight_js() : lib/utils.php
  • is_lightboxable_page() : lib/image.php
  • is_lightboxable_page() : lib/utils.php

Cocoon は以下の場所で WordPress のアクションフックによるスクリプトやスタイルのエンキューを行っています。

  • wp_enqueue_scripts_custom() : cocoon-master/lib/scripts.php
cocoon-master/lib/scripts.php
add_action( 'wp_enqueue_scripts', 'wp_enqueue_scripts_custom', 1 );
if ( !function_exists( 'wp_enqueue_scripts_custom' ) ):
function wp_enqueue_scripts_custom() {
…省略…

この関数内でコールされている関数を1個ずつ確認し、全文表示の際に必要だが、条件判定によりフロントページで実行されない関数を洗い出しました。

これらのオーバーライド関数を、テーマフォルダ直下の functions.php に追記します。

functions.php
… 省略 …
// lib/utils.php
//ソースコードのハイライト表示に必要なリソースの読み込み
if ( !function_exists( 'wp_enqueue_highlight_js' ) ):
function wp_enqueue_highlight_js(){
  //global $pagenow;
  if ( (is_code_highlight_enable() && (is_singular() || is_full_text())) || is_admin_php_page() ) {
    if (is_code_highlight_package_light()) {
      $file_name = 'highlight.min.js';
    } else {
      $file_name = 'highlight.all.min.js';
    }
    //ソースコードハイライト表示用のスタイル
    wp_enqueue_style( 'code-highlight-style',  get_highlight_js_css_url() );
    //ソースコードハイライト表示用のライブラリ
    $url = get_template_directory_uri() . '/plugins/highlight-js/'.$file_name;
    $url = apply_filters( 'code_highlight_js_url', $url );
    wp_enqueue_script( 'code-highlight-js', $url, array( 'jquery' ), false, true );
    if (is_admin_php_page()) {
      $selector = '.entry-content pre';
    } else {
      $selector = get_code_highlight_css_selector();
    }

    $data = minify_js('
          (function($){
           $("'.$selector.'").each(function(i, block) {
            hljs.highlightBlock(block);
           });
          })(jQuery);
        ');
    wp_add_inline_script( 'code-highlight-js', $data, 'after' ) ;
  }
}
endif;

// lib/image.php
//Lightboxを表示するページかどうか
if ( !function_exists( 'is_lightboxable_page' ) ):
function is_lightboxable_page(){
  return (is_singular() || is_full_text()) || (is_category() && !is_paged()) || (is_tag() && !is_paged());
}
endif;

// lib/utils.php
//ScrollHint
if ( !function_exists( 'wp_enqueue_scrollhint' ) ):
function wp_enqueue_scrollhint(){
  if (is_responsive_table_enable() && ((is_singular() || is_full_text()) || (is_category() && !is_paged())|| (is_tag() && !is_paged()))) {
    //ScrollHintスタイルの呼び出し
    wp_enqueue_style( 'scrollhint-style', get_template_directory_uri() . '/plugins/scroll-hint-master/css/scroll-hint.css' );
    //ScrollHintスクリプトの呼び出し
    wp_enqueue_script( 'scrollhint-js', get_template_directory_uri() . '/plugins/scroll-hint-master/js/scroll-hint.min.js', array( 'jquery' ), false, true  );
    $data = minify_js('
          (function($){
            new ScrollHint(".scrollable-table", {
              suggestiveShadow: true,
              i18n: {
                scrollable: "'.__( 'スクロールできます', THEME_NAME ).'"
              }
            });
          })(jQuery);
        ');
    wp_add_inline_script( 'scrollhint-js', $data, 'after' ) ;

  }
}
endif;

変更箇所の概要は以下の通りです。

|| is_full_text()

いずれの関数も、上記の判定を追加しました。

新着投稿の全文表示用条件分岐

tmp/list.php に条件分岐を追加して、新着投稿の全文表示用一覧テンプレート tmp/list-index-full-text を使うように変更します。

tmp/list.php
<?php //一覧
/**
 * Cocoon WordPress Theme
 * @author: yhira
 * @link: https://wp-cocoon.com/
 * @license: http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
 */
if ( !defined( 'ABSPATH' ) ) exit;

////////////////////////////
//アーカイブのタイトル
////////////////////////////
if ( is_category() && !is_paged() ){
  ////////////////////////////
  //カテゴリページのコンテンツ
  ////////////////////////////
  get_template_part('tmp/category-content');
} elseif ( is_tag() && !is_paged() ) {
  get_template_part('tmp/tag-content');
} elseif (!is_home()) {
  //それ以外
  get_template_part('tmp/list-title');
}

////////////////////////////
//インデックストップ広告
////////////////////////////
if (is_ad_pos_index_top_visible() && is_all_adsenses_visible()){
  //レスポンシブ広告
  get_template_part_with_ad_format(get_ad_pos_index_top_format(), 'ad-index-top', is_ad_pos_index_top_label_visible());
};

////////////////////////////
//インデックスリストトップウィジェット
////////////////////////////
if ( is_active_sidebar( 'index-top' ) ){
  dynamic_sidebar( 'index-top' );
};

////////////////////////////
// トップシェアボタン
////////////////////////////
//SNSトップシェアボタンの表示
if (is_sns_top_share_buttons_visible() &&
  //フロントページトップシェアボタンの表示
  (is_front_page() && !is_paged() && is_sns_front_page_top_share_buttons_visible())
){
  get_template_part_with_option('tmp/sns-share-buttons', SS_TOP);
} ?>

<?php
  if (is_front_index_page() && is_front_page_type_tab_index()) {
    get_template_part('tmp/list-tab-index');
  } elseif (is_front_index_page() && is_front_page_type_category()) {
    get_template_part('tmp/list-category');
  } elseif ((is_front_index_page() && is_front_page_type_category_2_columns()) || is_front_index_page() && is_front_page_type_category_3_columns()) {
    get_template_part('tmp/list-category-columns');
  /* add >>> */
  } elseif ( is_full_text() ) {
    get_template_part('tmp/list-index-full-text');
  /* add <<< */
  } else {
    get_template_part('tmp/list-index');
  }
?>

<?php
////////////////////////////
//インデックスボトム広告
////////////////////////////
if (is_ad_pos_index_bottom_visible() && is_all_adsenses_visible()){
  //レスポンシブ広告のフォーマットにrectangleを指定する
  get_template_part_with_ad_format(get_ad_pos_index_bottom_format(), 'ad-index-bottom', is_ad_pos_index_bottom_label_visible());
};

////////////////////////////
//インデックスリストボトムウィジェット
////////////////////////////
if ( is_active_sidebar( 'index-bottom' ) ){
  dynamic_sidebar( 'index-bottom' );
};

////////////////////////////
//フロントページボトムシェアボタン
////////////////////////////
//SNSボトムシェアボタンの表示
if (is_sns_bottom_share_buttons_visible() && !is_paged() &&
  (
  //フロントページボトムシェアボタンの表示
  (is_front_page() && is_sns_front_page_bottom_share_buttons_visible()) ||
  //カテゴリーページトップシェアボタンの表示
  (is_category() && is_sns_category_bottom_share_buttons_visible()) ||
  //タグページトップシェアボタンの表示
  (is_tag() && is_sns_tag_bottom_share_buttons_visible())
  )

){
  get_template_part_with_option('tmp/sns-share-buttons', SS_BOTTOM);
}

////////////////////////////
//フロントページフォローボタン
////////////////////////////
//SNSフォローボタンの表示
if (is_sns_follow_buttons_visible() && !is_paged() &&
  (
    //フロントページフォローボタンの表示
    (is_front_page() && is_sns_front_page_follow_buttons_visible()) ||
    //カテゴリーページボトムフォローボタンの表示
    (is_category() && is_sns_category_follow_buttons_visible()) ||
    //タグページボトムフォローボタンの表示
    (is_tag() && is_sns_tag_follow_buttons_visible())
  )

){
  get_template_part_with_option('tmp/sns-follow-buttons', SF_BOTTOM);
}

////////////////////////////
//ページネーション
////////////////////////////
if (is_front_page_type_index() || !is_front_index_page()) {
  get_template_part('tmp/pagination');
}

////////////////////////////
//メインカラム追従領域
////////////////////////////
get_template_part('tmp/main-scroll'); ?>

変更箇所の概要は以下の通りです。
(参照ファイル:cocoon-master/tmp/list.php)

  /* add >>> */
  } elseif ( is_full_text() ) {
    get_template_part('tmp/list-index-full-text');
  /* add <<< */

全文表示判定が真なら、tmp/list-index-full-text を使うように変更しています。

一覧表示テンプレート(新着投稿だけ全文表示用)

新着投稿だけ全文表示する一覧表示テンプレート tmp/list-index-full-text.php を作ります。

tmp/list-index-full-text.php
<?php //インデックス
/**
 * Cocoon WordPress Theme
 * @author: yhira
 * @link: https://wp-cocoon.com/
 * @license: http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
 */
if ( !defined( 'ABSPATH' ) ) exit;
?>
<?php
////////////////////////////
//一覧の繰り返し処理
////////////////////////////
$current_pgae = get_query_var( 'paged' ); 
$current_pgae = $current_pgae == 0 ? '1' : $current_pgae;

$count = 0;				// 一覧ページ内での表示記事番号
if ( have_posts() ) : // WordPress ループ
  while ( have_posts() ) : the_post(); // 繰り返し処理開始
    $count++;
    set_query_var( 'count', $count );

    if ( $count == 1 ) {
      if ( $current_pgae == 1 ) {
        get_template_part( 'tmp/content-in-home' );
        echo '<div id="list" class="' . get_index_list_classes() . ' front">';
        get_template_part( 'tmp/entry-card' );
      }
      else {
        echo '<div id="list" class="' . get_index_list_classes() . '">';
        get_template_part( 'tmp/entry-card' );
      }
    }
    else {
      get_template_part( 'tmp/entry-card' );
    }

    //インデックスミドルに広告を表示してよいかの判別
    if (is_ad_pos_index_middle_visible() && is_index_middle_ad_visible($count) && is_all_adsenses_visible()) {
      get_template_part_with_ad_format(get_ad_pos_index_middle_format(), 'ad-index-middle', is_ad_pos_index_middle_label_visible());
    }

    ////////////////////////////
    //インデックスリストミドルウィジェット
    ////////////////////////////
    if ( is_active_sidebar( 'index-middle' ) && is_index_middle_widget_visible($count) ){
      dynamic_sidebar( 'index-middle' );
    };

  endwhile; // 繰り返し処理終了 ?>
<?php else : // ここから記事が見つからなかった場合の処理
  get_template_part('tmp/list-not-found-posts');
endif;
?>
</div><!-- .list -->

変更箇所の概要は以下の通りです。
(参照ファイル:cocoon-master/tmp/list-index.php)

ページ番号取得

$current_pgae = get_query_var( 'paged' ); 
$current_pgae = $current_pgae == 0 ? '1' : $current_pgae;

現在のページが一覧ページの何ページ目かを取得します。

新着投稿分岐

    if ( $count == 1 ) {
      if ( $current_pgae == 1 ) {
        get_template_part( 'tmp/content-in-home' );
        echo '<div id="list" class="' . get_index_list_classes() . ' front">';
        get_template_part( 'tmp/entry-card' );
      }
      else {
        echo '<div id="list" class="' . get_index_list_classes() . '">';
        get_template_part( 'tmp/entry-card' );
      }
    }
    else {
      get_template_part( 'tmp/entry-card' );
    }

新着投稿のみ一覧ブロックの前に全文表示し、他は一覧ブロックの中でブログカード表示するようにしています。
念のため、やっていることの詳細は以下の通りです。

  • 新着投稿(1ページ目の1件目投稿)
    • 全文表示用テンプレート tmp/content-in-home 使用
    • 「<div id=”list”~」表示(一覧ブロックの開始)
    • ブログカード表示用テンプレート tmp/entry-card 使用
  • 2ページ目以降の1件目投稿
    • 「<div id=”list”~」表示(一覧ブロックの開始)
    • ブログカード表示用テンプレート tmp/entry-card 使用
  • 2件目以降投稿
    • ブログカード表示用テンプレート tmp/entry-card 使用

新着投稿のブログカード装飾

ブログカードを複数列表示設定にしている場合、新着投稿のブログカード非表示にするとレイアウトが著しくくずれてしまうため、新着投稿は全文表示にしつつブログカード表示も残すようにしました。
その代わり、スタイルシートで新着投稿のブログカードを装飾できるように、1ページ目の一覧ブロックにだけ「front」クラスを追加しています。

.front .entry-card-wrap:first-child

と指定することで、新着投稿のブログカードを装飾可能です。

サンプル

本サイトでは、以下の装飾を行っています。

  • グレースケール化(80%)
  • 半透明化(不透明度:40%)
  • 表示中のアイコン表示
.front .entry-card-wrap:first-child {
	filter: opacity(0.4) grayscale(0.8);
}
.front .entry-card-wrap:first-child::before {
	filter: opacity(1);
	width: 100px;
	background-color: rgba(0,0,0,0);
	color: #fff;
	content: '表示中';
	text-align: center;
	
	position: absolute;
	z-index: 100;
	top: 50%;
	left: 50%;
	transform: translateY(15px) translateX(-50px);
}
.front .entry-card-wrap:first-child::after {
	filter: opacity(0.8);
	padding-top: 5px;
	height: 100px;
	width: 100px;
	background-color: #000;
	border-radius: 25%;
	
	color: #fff;
	font-family: "Font Awesome 5 Free";
	font-weight: 900;
	font-size: 2.4em;
	content: '\f26c';
	text-align: center;
	vertical-align: middle;
	
	position: absolute;
	z-index: 99;
	top: 50%;
	left: 50%;
	transform: translateY(-50px) translateX(-50px);
}

※ 日本語を使用していますので、css ファイルの文字コードにはお気を付けください。

フロントページでの全文表示テンプレート

ご注意

過去記事の「フロントページでの全文表示テンプレート」と同じ内容ですが、ファイル名を「tmp/index-content.php」→「tmp/content-in-home.php」に修正しています。

個別投稿ページテンプレート参考に、新規ファイル tmp/content-in-home.php を作ります。

フロントページの構成と同じ要領で個別投稿ページで使用されるテンプレートを確認します。

  • single.php
  • tmp/single-contents.php
  • tmp/content.php

single.php はヘッダフッタの作成部分で index.php で作成済みのため無視し、tmp/single-contents.php、tmp/content.php をコピペでひとまとめにし、適宜変更したテンプレートファイルを作ります。

tmp/content-in-home.php
<?php // single-contents 代替
/**
 * Cocoon WordPress Theme
 * @author: yhira
 * @link: https://wp-cocoon.com/
 * @license: http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
 */
if ( !defined( 'ABSPATH' ) ) exit;
$article_id_attr = null;
if (is_front_page_type_index()) {
  $article_id_attr = ' id="post-'.get_the_ID().'"';
}
?>

<?php //パンくずリストがメイントップの場合
if (is_single_breadcrumbs_position_main_top()){
	get_template_part('tmp/breadcrumbs-forced');
} ?>

<article id="post-<?php the_ID(); ?>" <?php post_class('article') ?> itemscope="itemscope" itemprop="blogPost" itemtype="https://schema.org/BlogPosting">

	<?php //タイトル上の広告表示
	if (is_ad_pos_above_title_visible() && is_all_adsenses_visible()){
		get_template_part_with_ad_format(get_ad_pos_above_title_format(), 'ad-above-title', is_ad_pos_above_title_label_visible());
	}; ?>

	<?php //投稿タイトル上ウイジェット
	if ( is_single() && is_active_sidebar( 'above-single-content-title' ) ): ?>
		<?php dynamic_sidebar( 'above-single-content-title' ); ?>
	<?php endif; ?>

	<?php //固定ページタイトル上ウイジェット
	if ( is_page() && is_active_sidebar( 'above-page-content-title' ) ): ?>
		<?php dynamic_sidebar( 'above-page-content-title' ); ?>
	<?php endif; ?>

	<?php //タイトル上のカテゴリー・タグ
	if (is_category_tag_display_position_title_top() && is_single()) {
		get_template_part('tmp/categories-tags');
	} ?>

<a href="<?php echo esc_url(get_the_permalink()); ?>" class="entry-card-wrap a-wrap border-element cf" title="<?php echo esc_attr(get_the_title()); ?>">

	<header class="article-header entry-header">
		<h1 class="entry-title" itemprop="headline">
			<?php
			if (is_wpforo_plugin_page()) {
				echo wp_get_document_title();
			} else {
				the_title();
			}
			 ?>
		</h1>

		<?php //レビュー表示
		if (is_the_page_review_enable()) {
			echo '<div class="review-rating">';
			echo get_rating_star_tag(get_the_review_rate(), 5, true);
			echo '</div>';
		}
		?>

		<?php //タイトル下の広告表示
		if (is_ad_pos_below_title_visible() && is_all_adsenses_visible()){
			get_template_part_with_ad_format(get_ad_pos_below_title_format(), 'ad-below-title', is_ad_pos_below_title_label_visible());
		}; ?>

		<?php //投稿タイトル下ウイジェット
		if ( is_single() && is_active_sidebar( 'below-single-content-title' ) ): ?>
			<?php dynamic_sidebar( 'below-single-content-title' ); ?>
		<?php endif; ?>

		<?php //固定ページタイトル下ウイジェット
		if ( is_page() && is_active_sidebar( 'below-page-content-title' ) ): ?>
			<?php dynamic_sidebar( 'below-page-content-title' ); ?>
		<?php endif; ?>

		<?php //アイキャッチ挿入
		get_template_part('tmp/eye-catch');

		do_action('singular_eye_catch_after');
		?>

		<?php //SNSトップシェアボタンの表示
		if (is_sns_top_share_buttons_visible() &&
			(
				//投稿ページトップシェアボタンの表示
				(is_single() && is_sns_single_top_share_buttons_visible()) ||
				//固定するページトップシェアボタンの表示
				(is_page() && is_sns_page_top_share_buttons_visible())
			)
		){
			get_template_part_with_option('tmp/sns-share-buttons', SS_TOP);
		} ?>


		<?php //投稿日と更新日テンプレート
		get_template_part('tmp/date-tags'); ?>

		<?php //本文上のカテゴリー・タグ
		if (is_category_tag_display_position_content_top() && is_single()) {
			get_template_part('tmp/categories-tags');
		} ?>

		<?php if (is_content_read_time_visible() && is_the_page_read_time_visible() && !is_plugin_fourm_page()): ?>
			<div class="read-time"><?php echo '<span class="fa fa-hourglass-half" aria-hidden="true"></span>
'.sprintf(__( 'この記事は<span class="bold">約%s分</span>で読めます。', THEME_NAME ), get_time_to_content_read(get_the_content())); ?></div>
		<?php endif; ?>

		 <?php //本文上の広告表示
		if (is_ad_pos_content_top_visible() && is_all_adsenses_visible()){
			get_template_part_with_ad_format(get_ad_pos_content_top_format(), 'ad-content-top', is_ad_pos_content_top_label_visible());
		}; ?>

		<?php //投稿本文上ウイジェット
		if ( is_single() && is_active_sidebar( 'single-content-top' ) ): ?>
			<?php dynamic_sidebar( 'single-content-top' ); ?>
		<?php endif; ?>

		<?php //固定ページ本文上ウイジェット
		if ( is_page() && is_active_sidebar( 'page-content-top' ) ): ?>
			<?php dynamic_sidebar( 'page-content-top' ); ?>
		<?php endif; ?>

	</header>
</a>

	<?php //投稿・固定ページ本文前のアクションフック
	do_action('singular_entry_content_before'); ?>

	<div class="entry-content cf<?php echo get_additional_entry_content_classes(); ?>" itemprop="mainEntityOfPage">
	<?php //記事本文の表示
		the_content( '続きを読む' ); ?>
	</div>

	<?php ////投稿・固定ページ本文後のアクションフック
	do_action('singular_entry_content_after'); ?>

	<?php //マルチページ用のページャーリンク
	get_template_part('tmp/pager-page-links'); ?>
	
	<?php	// カスタムcss
	$custom_css = get_post_meta(get_the_ID(), '_custom_css', true);
	if ($custom_css) {
		echo '<!-- '.THEME_NAME.' Custom CSS -->'.PHP_EOL;
		echo '<style>' . $custom_css . '</style>'.PHP_EOL;
	}
	?>
	
	<?php	// カスタムjs
	$custom_js = get_post_meta(get_the_ID(), '_custom_js', true) ;
	if ($custom_js) {
		echo '<!-- '.THEME_NAME.' Custom JS -->'.PHP_EOL;
		echo '<script type="text/javascript">' . $custom_js . '</script>'.PHP_EOL;
	}
	?>

	<footer class="article-footer entry-footer">

		<?php //投稿本文下ウイジェット
		if ( is_single() && is_active_sidebar( 'single-content-bottom' ) ): ?>
			<?php dynamic_sidebar( 'single-content-bottom' ); ?>
		<?php endif; ?>

		<?php //固定ページ本文下ウイジェット
		if ( is_page() && is_active_sidebar( 'page-content-bottom' ) ): ?>
			<?php dynamic_sidebar( 'page-content-bottom' ); ?>
		<?php endif; ?>

		<?php //本文下ページ送りナビ
		if (is_post_navi_position_under_content()) {
			get_template_part('tmp/pager-post-navi');
		} ?>

		<?php //本文下のカテゴリー・タグ
		if (is_category_tag_display_position_content_bottom() && is_single()) {
			get_template_part('tmp/categories-tags');
		} ?>

		<?php //本文下の広告表示
		if (is_ad_pos_content_bottom_visible() && is_all_adsenses_visible()){
			//レスポンシブ広告のフォーマットにrectangleを指定する
			get_template_part_with_ad_format(get_ad_pos_content_bottom_format(), 'ad-content-bottom', is_ad_pos_content_bottom_label_visible());
		}; ?>

		<?php //SNSシェアボタン上の広告表示
		if (is_ad_pos_above_sns_buttons_visible() && is_all_adsenses_visible()){
			get_template_part_with_ad_format(get_ad_pos_above_sns_buttons_format(), 'ad-above-sns-buttons', is_ad_pos_above_sns_buttons_label_visible());
		}; ?>

		<?php //投稿SNSボタン上ウイジェット
		if ( is_single() && is_active_sidebar( 'above-single-sns-buttons' ) ): ?>
			<?php dynamic_sidebar( 'above-single-sns-buttons' ); ?>
		<?php endif; ?>

		<?php //固定ページSNSボタン上ウイジェット
		if ( is_page() && is_active_sidebar( 'above-page-sns-buttons' ) ): ?>
			<?php dynamic_sidebar( 'above-page-sns-buttons' ); ?>
		<?php endif; ?>

		<?php //SNSボトムシェアボタンの表示
		if (is_sns_bottom_share_buttons_visible() &&
			(
				//投稿ページボトムシェアボタンの表示
				(is_single() && is_sns_single_bottom_share_buttons_visible()) ||
				//固定するページボトムシェアボタンの表示
				(is_page() && is_sns_page_bottom_share_buttons_visible())
			)
		){
			get_template_part_with_option('tmp/sns-share-buttons', SS_BOTTOM);
		} ?>

		<?php //SNSフォローボタン
		if (
			is_sns_follow_buttons_visible() &&
			(
				//投稿ページフォローボタンの表示
				(is_single() && is_sns_single_follow_buttons_visible()) ||
				//固定するページフォローボタンの表示
				(is_page() && is_sns_page_follow_buttons_visible())
			)
		){
			get_template_part_with_option('tmp/sns-follow-buttons', SF_BOTTOM);
		} ?>

		<?php //SNSシェアボタン上の広告表示
		if (is_ad_pos_below_sns_buttons_visible() && is_all_adsenses_visible()){
			get_template_part_with_ad_format(get_ad_pos_below_sns_buttons_format(), 'ad-below-sns-buttons', is_ad_pos_below_sns_buttons_label_visible());
		}; ?>

		<?php //投稿SNSボタン下ウイジェット
		if ( is_single() && is_active_sidebar( 'below-single-sns-buttons' ) ): ?>
			<?php dynamic_sidebar( 'below-single-sns-buttons' ); ?>
		<?php endif; ?>

		<?php //固定ページSNSボタン下ウイジェット
		if ( is_page() && is_active_sidebar( 'below-page-sns-buttons' ) ): ?>
			<?php dynamic_sidebar( 'below-page-sns-buttons' ); ?>
		<?php endif; ?>

		<?php //投稿者等表示用のテンプレート
		get_template_part('tmp/footer-meta'); ?>

		<!-- publisher設定 -->
		<?php
		$home_image_url = get_amp_logo_image_url();
		$size = get_image_width_and_height($home_image_url);
		$width = isset($size['width']) ? $size['width'] : 600;
		$height = isset($size['height']) ? $size['height'] : 60;

		$sizes = calc_publisher_image_sizes($width, $height);
		$width = $sizes ? $sizes['width'] : 600;
		$height = $sizes ? $sizes['height'] : 60;
		 ?>
		<div class="publisher" itemprop="publisher" itemscope itemtype="https://schema.org/Organization">
				<div itemprop="logo" itemscope itemtype="https://schema.org/ImageObject">
					<img src="<?php echo $home_image_url; ?>" width="<?php echo $width; ?>" height="<?php echo $height; ?>" alt="">
					<meta itemprop="url" content="<?php echo $home_image_url; ?>">
					<meta itemprop="width" content="<?php echo $width; ?>">
					<meta itemprop="height" content="<?php echo $height; ?>">
				</div>
				<div itemprop="name"><?php bloginfo('name'); ?></div>
		</div>
	</footer>

</article>

<?php //パンくずリストがメインボトムの場合
if (is_single_breadcrumbs_position_main_bottom()){
	get_template_part('tmp/breadcrumbs-forced');
} ?>

<?php //メインカラム追従領域
get_template_part('tmp/main-scroll'); ?>

変更箇所の概要は以下の通りです。

パンくずリストの強制表示

	get_template_part('tmp/breadcrumbs-forced');

既存のパンくずリストテンプレートは、個別投稿やカテゴリページでのみの表示になっているため、現在のページに関わらず表示する tmp/breadcrumbs-forced テンプレートを作ることにしました。

ループ重複の削除

参考にした tmp/content.php の中で、if ( have_posts() ){ … } が行われていますが、tmp/list-index-content.php で既にこの処理を行っているので、重複しないように削除します。

不要コンテンツの削除

個別投稿ではコメントなどが表示されますが、フロントページでは不要と判断したので、それらをごっそり削っています。

カスタムスタイル、カスタムスクリプトの挿入

	<?php	// カスタムcss
	$custom_css = get_post_meta(get_the_ID(), '_custom_css', true);
	if ($custom_css) {
		echo '<!-- '.THEME_NAME.' Custom CSS -->'.PHP_EOL;
		echo '<style>' . $custom_css . '</style>'.PHP_EOL;
	}
	?>
	
	<?php	// カスタムjs
	$custom_js = get_post_meta(get_the_ID(), '_custom_js', true) ;
	if ($custom_js) {
		echo '<!-- '.THEME_NAME.' Custom JS -->'.PHP_EOL;
		echo '<script type="text/javascript">' . $custom_js . '</script>'.PHP_EOL;
	}
	?>

従来はヘッダ作成時に挿入されるカスタム css やカスタム js ですが、すでにヘッダは作成済みなので body タグ内に挿入しています。

ヘッダで読み込まれるスクリプトなどは、前述の通り固定ページ用のものなので、投稿ページ用のカスタム~系をここで挿入します。

個別投稿ページへのリンク

<a href="<?php echo esc_url(get_the_permalink()); ?>" class="entry-card-wrap a-wrap border-element cf" title="<?php echo esc_attr(get_the_title()); ?>">

個別投稿ページへのジャンプ方法として、記事ヘッダにリンクを貼りました。

強制パンくずリスト表示テンプレート

ご注意

過去記事の「強制パンくずリスト表示テンプレート」と同じ内容です。

投稿ページパンくずリストテンプレート tmp/breadcrumbs.php を参考に、新規ファイル tmp/breadcrumbs-forced.php を作ります。

以下の場所にファイルを新規作成します。

<テーマフォルダ>
  tmp
    breadcrumbs-forced.php
tmp/breadcrumbs-forced.php
<?php //カテゴリ用のパンくずリスト
/**
 * Cocoon WordPress Theme
 * @author: yhira
 * @link: https://wp-cocoon.com/
 * @license: http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
 */
if ( !defined( 'ABSPATH' ) ) exit;

if (is_single_breadcrumbs_visible()){
  $cats = get_the_category();
  //メインカテゴリが指定してある場合は該当カテゴリーを適用
  $main_cat_id = get_the_page_main_category();
  if ($main_cat_id && in_category($main_cat_id)) {
    $cat = get_category($main_cat_id);
  }
  //メインカテゴリがない場合は先頭のカテゴリを適用
  if (!$cat) {
    $cat = $cats[0];
  }
  // $cat = (is_single() && isset($cats[0])) ? $cats[0] : get_category(get_query_var("cat"));
  if($cat && !is_wp_error($cat)){
    $echo = null;
    $root_text = __( 'ホーム', THEME_NAME );
    $root_text = apply_filters('breadcrumbs_single_root_text', $root_text);
    //var_dump($par);
    echo '<div id="breadcrumb" class="breadcrumb breadcrumb-category'.get_additional_single_breadcrumbs_classes().'" itemscope itemtype="https://schema.org/BreadcrumbList">';
    echo '<div class="breadcrumb-home" itemscope itemtype="https://schema.org/ListItem" itemprop="itemListElement"><span class="fa fa-home fa-fw" aria-hidden="true"></span><a href="'.esc_url(get_home_url()).'" itemprop="item"><span itemprop="name" class="breadcrumb-caption">'.esc_html($root_text).'</span></a><meta itemprop="position" content="1" /><span class="sp"><span class="fa fa-angle-right" aria-hidden="true"></span></span></div>';
    $count = 1;
    $par = get_category($cat->parent);
    //カテゴリ情報の取得
    $cats = array();
    while($par && !is_wp_error($par) && $par->term_id != 0){
      $cats[] = $par;
      $par = get_category($par->parent);
    }
    //カテゴリの順番入れ替え
    $cats = array_reverse($cats);
    //先祖カテゴリの出力
    foreach ($cats as $par) {
      ++$count;
      //var_dump($par->name);
      $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_category_link($par->term_id)).'" itemprop="item"><span itemprop="name" class="breadcrumb-caption">'.esc_html($par->name).'</span></a><meta itemprop="position" content="'.$count.'" /><span class="sp"><span class="fa fa-angle-right" aria-hidden="true"></span></span></div>';
    }
    // 現カテゴリの出力
    ++$count;
    echo $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_category_link($cat->term_id)).'" itemprop="item"><span itemprop="name" class="breadcrumb-caption">'.esc_html($cat->name).'</span></a><meta itemprop="position" content="'.$count.'" />';
    //ページタイトルを含める場合はセパレーターを表示
    if (is_single_breadcrumbs_include_post()) {
      echo '<span class="sp"><span class="fa fa-angle-right" aria-hidden="true"></span></span>';
    }
    echo '</div>';
    //ページタイトルを含める場合
    if (is_single_breadcrumbs_include_post()) {
      echo '<div class="breadcrumb-item"><span class="fa fa-file-o fa-fw" aria-hidden="true"></span><a href="<?php echo esc_url(get_the_permalink()); ?>"><span class="breadcrumb-caption">'.esc_html(get_the_title()).'</span></a></div>';
    }

    echo '</div><!-- /#breadcrumb -->';
  }
} //is_single_breadcrumbs_visible ?>

変更箇所の概要は以下の通りです。

現在のページによる分岐削除

is_single() などの現在のページ分類による条件を削除します。

個別投稿ページへのリンク

      echo '<div class="breadcrumb-item"><span class="fa fa-file-o fa-fw" aria-hidden="true"></span><a href="<?php echo esc_url(get_the_permalink()); ?>"><span class="breadcrumb-caption">'.esc_html(get_the_title()).'</span></a></div>';

ページタイトル部分に個別投稿ページへのリンクを追加しました。

最後に

メインクエリの上書きをせず、より自然な形で実装できたのはいいですが、functions.php の変更が配布には向かないのが困りものですね…

コメント