【Cocoon】記事ヘッダーに出力される要素の配置を入れ替えるカスタマイズ

Cocoon

今回は、WordPressテーマ「Cocoon」の投稿記事・固定記事の本文のヘッダーに表示される要素の順序を自由に入れ替えるカスタマイズを紹介します。

これにより、「アイキャッチを投稿日時の下で表示したい」、「レビューの星をタイトルの上で表示したい」といった事が可能になります。

始めに

私は以前、「アイキャッチの位置を変更するカスタマイズ」という記事にて、記事ヘッダーに出力されるアイキャッチの表示位置を変更する方法を解説しました。

ただ、この方法は以下のようなものでした。

子テーマに「tmp」フォルダを作成し、その中に親テーマから「content.php」をコピペした上で、ファイル内部の出力関数の順番を入れ替える。

これは、「子テーマは親テーマの関数やファイルを上書きする」というWordPressの仕組みを利用したものでした。

ただ、この方法では親テーマのアップデートが反映されなくなってしまいます。正確に言うと、親テーマにアップデートが来るたび、子テーマのファイルを見比べ、変更箇所を手動で更新する必要が生じてしまいます。

なので、単純と言えば単純なのですが、とても面倒くさくメンテナンス性に欠けるものでした。

できれば、一度カスタマイズのコードを入力した後はそのままでいたい、変更点があったとしても、1行から2行程度のコードを書き加えるだけで対応できるようにしたい。

そんなわけで、以前のカスタマイズを見直し、子テーマのfunctions.phpのみで完結する「記事ヘッダー内の要素の表示順を自在に変更する関数」を作成するに至りました。

カスタマイズを行う前に確認すること等

カスタマイズを行う前に、必要なもの・ことをいくつか確認しておきましょう。

子テーマの「functions.php」

今回のカスタマイズはPHPを用いるので、編集するファイルはこれだけです。

なお、必ず子テーマのファイルを選択してください。

まず、管理者画面左サイドバーの「外観」にカーソルを合わせ、ポップアップが表示されたら「テーマエディター」をクリックしてください。

すると、このように使用中のテーマの編集画面に入りますので、編集画面右側のサイドバーから「テーマのための関数(functions.php)」と書かれたものをクリックしましょう。

また、ちゃんと子テーマのものを選択していることも確認するようにしてください。

WEBサイトのバックアップ

また、カスタマイズを行う前には、必ずWEBサイトのバックアップも行うようにしてください。

万が一の場合も考えて、です。

WordPressのバックアップに関する具体的な解説は、こちらの記事で行っております。

カスタマイズの実装

それでは、カスタマイズの実装に移ります。

なお、今回は例として「投稿日時」と「本文中のアイキャッチ画像」の入れ替えを行うことにします。

スポンサーリンク

PHPコード

まず、下記のPHPコードを、「子テーマのfanctions.php」にコピペしてください。「テーマのための関数」と表示されているものです。

PHPコード
// Cocoonの記事ヘッダーの順序を入れ替えるカスタマイズ
// Cocoonの最終出力フィルターを利用
function mycus_reoutput_article_header_func( $run = null ) {

  if ( $run == true ) {

    // 記事ヘッダー削除
    add_filter( 'code_minify_call_back', function ( $element ) {

      $specify = '#<header class="article-header entry-header">(.*?)</header>#s';
      $delete = '';

      return preg_replace( $specify, $delete, $element, 1 );

    }, 0 );

    // 記事ヘッダー再出力
    // アイキャッチ画像の出力順を入れ替えている
    // 親テーマ側で変更があった場合は、その都度出力関数を付け加えること
    add_action( 'singular_entry_content_before', function () {

      // 変数化
      $h1_func = function () { if ( is_wpforo_plugin_page() ) { echo wp_get_document_title(); } else { the_title(); } };
      $review_func = function () { if ( is_the_page_review_enable() ) { echo '<div class="review-rating">' , get_rating_star_tag(get_the_review_rate(), 5, true) . '</div>'; } };
      $ad_pos_below_title_func = function () { 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() ); } };
      $title_under_widget_post_func = function () { if ( is_single() && is_active_sidebar( 'below-single-content-title' ) ) { dynamic_sidebar( 'below-single-content-title' ); } };
      $eye_catch_func = function () { get_template_part('tmp/eye-catch') . do_action('singular_eye_catch_after'); };
      $title_under_widget_page_func = function () { if ( is_page() && is_active_sidebar( 'below-page-content-title' ) ) { dynamic_sidebar( 'below-page-content-title' ); } };
      $sns_top_share_buttons_func = function () { 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); } };
      $date_func = function () { get_template_part('tmp/date-tags'); };
      $category_tag_display_position_content_top_func = function () { if ( is_category_tag_display_position_content_top() && is_single() ) { get_template_part('tmp/categories-tags'); } };
      $content_read_time_func = function () { if ( is_content_read_time_visible() && is_the_page_read_time_visible() && !is_plugin_fourm_page() ) { echo '<div class="read-time"><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>'; } };
      $ad_pos_content_top_func = function () { 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() ); } };
      $content_top_widget_post_func = function () { if ( is_single() && is_active_sidebar( 'single-content-top' ) ) { dynamic_sidebar( 'single-content-top' ); } };
      $content_top_widget_page_func = function () { if ( is_page() && is_active_sidebar( 'page-content-top' ) ) { dynamic_sidebar( 'page-content-top' ); } };

      // 出力
      echo '<header class="article-header entry-header">';
        echo '<h1 class="entry-title" itemprop="headline">' , $h1_func() . '</h1>';
        echo $review_func();
        echo $ad_pos_below_title_func();
        echo $title_under_widget_post_func();
        echo $title_under_widget_page_func();
        echo $sns_top_share_buttons_func();
        echo $date_func();
        echo $category_tag_display_position_content_top_func();
        echo $eye_catch_func();
        echo $content_read_time_func();
        echo $ad_pos_content_top_func();
        echo $content_top_widget_post_func();
        echo $content_top_widget_page_func();
      echo '</header>';

    } );

  }

}
mycus_reoutput_article_header_func( true );

正しく写したことを確認したら、ページ左下の「ファイルを更新」ボタンをクリックしてください。

これで、カスタマイズの実装は完了です。

実装結果

さて、先ほどのコードを実装した場合、こうなります。

それから、デフォルトの状態の画像と見比べてみてください。

上の画像のように、投稿日時とサムネイル画像が正しく入れ替わっているのであれば、カスタマイズは成功です!

カスタマイズの解説

まず、先ほどのカスタマイズコードが行った動作を簡単に説明すると、こうなります。

  1. 正規表現を使って既存の記事ヘッダーを削除する。
  2. 親テーマから記事ヘッダーの要素の出力関数を拝借し、その関数の出力順を並び替えた関数を作成する。
  3. 上記の関数を、Cocoonのアクションフックを使って同じ位置に出力する。

それでは、下に詳しく書いていきます。

始めに、既存の記事ヘッダーを削除する必要があります。

なので、正規表現「preg_replace」を使用して、記事ヘッダーを削除してしまいましょう。

なおこのとき、置き換えの回数は「1度だけ」に指定してください。回数を指定しなかった場合、「無限回」置き換えが発生してしまいますので、アクションフックから記事ヘッダーを出力できなくなってしまいます。


この関数は、Cocoonの最終出力フィルターである「code_minify_call_back」にフックさせる必要があります。

最終出力フィルター」とは何なのか?という方は、こちらの記事をお読みください。

次に、記事ヘッダーの要素を並び替えて再出力する関数を作成しましょう。

まず、親テーマの「tmp/content.php」ファイルから、記事ヘッダーに表示する要素の出力を制御している関数を全て見つけてください。場所は、以下のタグの内部に全て存在しています。

<header class="article-header entry-header"> // このタグから
// ここにH1見出しや
// 記事投稿日時や
// アイキャッチの出力の関数が
// 存在している
</header> // このタグまでの中のもの全部

そして、それらを子テーマの「functions.php」で使えるように変数化しましょう。

例えば、こんな感じです。

// これを
<h1 class="entry-title" itemprop="headline">
  <?php
  if (is_wpforo_plugin_page()) {
    echo wp_get_document_title();
  } else {
    the_title();
  }
  ?>
</h1>
// こうする
$h1_func = function () { if ( is_wpforo_plugin_page() ) { echo wp_get_document_title(); } else { the_title(); } };

このようにして、記事ヘッダーの中に存在する出力関数を全て変数にして行ってください。なおその際、変数の名前は「何の関数を変数にしたか」一目でわかるようにすることをおすすめします。

そして、関数を全て変数にし直したら、「echo」を使って順番に出力していきます。

まず、最初と最後に出力するものは必ず「記事ヘッダータグ」にしてください

echo '<header class="article-header entry-header">';
// この間に変数化した出力関数を入れる
echo '</header>';

また、今回のカスタマイズのメインである「要素の表示順の変更」は、echoの順番で制御します。

// 「投稿日時」を「本文上のアイキャッチ」より上に置きたい場合
echo $date_func(); // 変数化した「投稿日時」出力関数
echo $eye_catch_func(); // 変数化した「本文上のアイキャッチ」出力関数

こうすることで、自分の意図したい表示順の記事ヘッダーにすることが可能になります。


こちらの関数は、Cocoonのアクションフック「singular_entry_content_before」にフックさせましょう。

このアクションフックは記事ヘッダータグ直下に配置されています。

以上が、今回のカスタマイズの解説になります。

関数全体を「if」で囲っているのは、単にメンテナンス性を上げたいだけです。なくても構いません。

最後に

今回は、Cocoonの本文の記事ヘッダー内に表示される要素の配置を自由に変更するカスタマイズを紹介しました。

こちらの方法であれば、Cocoonのアップデートの影響も最小限にとどまり、例え親テーマ側で記事ヘッダー内に新しい要素が追加されたとしても、対応する無名関数の変数の追加だけで簡単に更新することができます。

なので、Cocoonの記事ヘッダーの表示を出来るだけシンプルに組み替えたいな……と思っている方は、ぜひ参考にしてみてください。

それでは、また。