cocoonテーマの子テーマ運用をやめました。ジレンマを解消した方法、改造するならプラグイン

最近、ワードプレスのテーマはcocoonを採用することが多いです。

テーマのちょっとした改造には「子テーマ」の利用を勧める情報源が多いです。私もそれにならって、cocoon-childを利用していました。

子テーマを使って何を改造したの?

cocoonの子テーマを利用し、以下のような改造を行っています。

  1. スタイル(css)を追加。

    style.css

  2. カテゴリ一覧等の一覧表示形式のページに絞り込み検索を追加。

    tmp/list-index.php tmp/list.php tmp/siborikomi.phpを追加

  3. カテゴリ一覧内の各エントリーのタイトルに強調すべき内容を追加(別データベースとの連携)

    tmp/entry-card.php

  4. Googleサーチコンソールで指摘を受けやすい余計なCSSやJSをページ内の利用状況に応じて動的に読み込むようにした

    header.php footer.php

しばらく使っていると「子テーマ運用のジレンマ」に気がつきました。

子テーマ運用のジレンマとは?

  • 親テーマの更新を躊躇する

    子テーマを使うことで、親テーマは自動更新でメンテ不要って思い込んでいました。コレ、間違った認識でした。

    今回改造したような方法では、親テーマに存在するlist-index.phpやlist.php、entry-card.php等を子テーマ内にコピーし、そのファイルを改造ています。

    親テーマが最新になり、新しいクラスや階層構造になっても、実際は子テーマ側にコピーした結果になります。

    →子テーマは親テーマの変更があった場所を手動で更新する必要があります。

  • 手動で更新って?

    よくある手法はローカルにcocoon-master、cocoon-child-masterをタグをつけてバージョン管理(git等)します。新しいcocoon-masterがリリースされたら、本番サイトを更新する前に、cocoon-masterを更新し、git等で比較し、変更があった場所を特定し、cocoon-child-masterに反映していきます。反映が終わったら本番サイトのテーマを更新し、ローカルのcocoon-child-masterをコピーするような流れのようです。

    style.cssのみの編集ならこのようなことにはなりません。phpファイルに手をつけると手間がかかります。

    →子テーマは更新に弱い。めんどくさいね・・

テーマは手間なく運用したいのですが、実際は結構手間です。コレならマスターをそのまま改造してしまっても・・・って思うかもしれません。

以前、マスター改造で運営したことがあります。2度とアップデートできなくなりました。

ポイント:cocoonは子テーマじゃなくて、プラグインで改造するのが簡単です。

子テーマを脱却しました。プラグインで改造するポイントがいくつかあります。

  1. テーマのフック、アクションはafter_setup_themeで設定する
  2. cocoonのテンプレート読み込み関数cocoon_template_part()のフック、アクションを使う
  3. wp_head内でpost_idを確定させる方法がある

テーマのフック、アクションはafter_setup_themeで設定する

ワードプレスのオブジェクトの生成順番では、プラグイン→テーマのような順番になります。
プラグインのオブジェクトが生成されたタイミングでcocoon専用のフックやアクションを設定しても、無効になり、呼び出されることはありません。

テーマのフックやアクションの設定は、after_setup_themeが最適です。

例えば、wp_cocoonというプラグインを作ったとして、以下のようにafter_setup_themeアクションを追加します。

class wp_cocoon {
    static $instance = null;
    static public function getInstance(){
        if( wp_cocoon::$instance == null ){
            wp_cocoon::$instance = new wp_cocoon();
        }
        return wp_cocoon::$instance;
    }
    function __construct(){
        add_action( 'after_setup_theme', array($this, 'after_setup_theme'),1);
    }
    function after_setup_theme(){
        // ここにフック、アクションを設定する
    }
    function style(){
    }
    function js(){
    }
}
wp_cocoon::getInstance();

cocoonのテンプレート読み込み関数cocoon_template_part()のフック、アクションを使う

cocoonテンプレートのソースを見ると以下のようにcocoon_template_part()を使っています。

////////////////////////////
  //カテゴリーページのパンくずリスト
  ////////////////////////////
  if (is_single_breadcrumbs_position_main_top()) {
    cocoon_template_part('tmp/breadcrumbs');
  }

  ////////////////////////////
  //カテゴリーページのコンテンツ
  ////////////////////////////
  if (!is_paged()) {
    cocoon_template_part('tmp/category-content');
  } else {
    cocoon_template_part('tmp/list-title');
  }

cocoon_template_partのソース(lib/utils.php)は以下のようにフック、アクションが設定可能です。apply_filtersを呼び出す場所、do_actionの呼び出す場所を確認してみてください。

//get_template_partに関するフック付加
if ( !function_exists( 'cocoon_template_part' ) ):
function cocoon_template_part($slug){
  ob_start();
  get_template_part($slug);
  $content = ob_get_clean();

  // 読み込み前発火
  if (has_filter("cocoon_part_before__{$slug}")) {
    do_action("cocoon_part_before__{$slug}");
  }

  // 書き換え
  if (has_filter("cocoon_part__{$slug}")) {
    $content = apply_filters("cocoon_part__{$slug}" ,$content);
  }
  echo $content;

  // 読み込み後発火
  if (has_filter("cocoon_part_after__{$slug}")) {
    do_action("cocoon_part_after__{$slug}");
  }
}
endif;

上記から例えば、cocoon_template_part(‘tmp/category-content’);のような呼び出しパターンだと以下のようなフック、アクションを追加することができます。

  • category-contentの前に出力する改造 add_action( ‘cocoon_part_before__tmp/category-content’, function(){ echo “前”; } );
  • category-contentの出力内容を修正する改造 add_filter(‘cocoon_part__tmp/category-content’, function($content){ return $content;});
  • category-contentの後に出力する add_action( ‘cocoon_part_after__tmp/category-content’, function(){ echo “後”; } );

add_actionはecho等で直接出力、add_filterはcontentの内容を編集し、returnでcontentを応答するのもポイントです。

cocoon-masterのtmpのファイル群を理解することで、子テーマを使わなくても、任意の場所の表示内容を変更することが可能になります。

子テーマの改造と同じくcocoon-masterの理解は必須です。

wp_head内でpost_idを確定させる方法がある

header.phpを修正せざるおえなかった理由がコレでした。wp_head()内でpost_idが判明しない。wp_head()を使えば簡単なはずでしたが、ワードプレスの挙動を確認したところwp_head()の呼び出し後にpost_idが確定する流れでした。

wp_headアクション内で、以下関数を呼び出すことで表示するPOST/PAGEのIDが取得できました。

$obj = get_queried_object();/* $obj->ID */

一覧系のページはIDが確定しないので、isset()することが必須です。

まとめ:子テーマ使わなくても、子テーマで実現していた内容を自作プラグインで実現できました。

子テーマの利用をやめました。

ほぼ「プラグインで改造するポイント」で子テーマで実現していた内容をプラグインに実装できました。

cocoonテーマの自動更新を有効にしました。今後はアップデートでactionやfilterの名称変化で修正が必要になります。
手間なくて簡単になりました。

コメント

タイトルとURLをコピーしました