最近、ワードプレスのテーマはcocoonを採用することが多いです。
テーマのちょっとした改造には「子テーマ」の利用を勧める情報源が多いです。私もそれにならって、cocoon-childを利用していました。
子テーマを使って何を改造したの?
cocoonの子テーマを利用し、以下のような改造を行っています。
- スタイル(css)を追加。
style.css
- カテゴリ一覧等の一覧表示形式のページに絞り込み検索を追加。
tmp/list-index.php tmp/list.php tmp/siborikomi.phpを追加
- カテゴリ一覧内の各エントリーのタイトルに強調すべき内容を追加(別データベースとの連携)
tmp/entry-card.php
- 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は子テーマじゃなくて、プラグインで改造するのが簡単です。
子テーマを脱却しました。プラグインで改造するポイントがいくつかあります。
- テーマのフック、アクションはafter_setup_themeで設定する
- cocoonのテンプレート読み込み関数cocoon_template_part()のフック、アクションを使う
- 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の名称変化で修正が必要になります。
手間なくて簡単になりました。
コメント