WordPress 4.4から詳細記事ページ用(single.php)に新しいテンプレートが用意されました。
テンプレートのファイル名をsingle-{post_type}-{post_name}.php
の仕様に則ることで、詳細記事ごとに専用のテンプレートを割り当てることができます。
これを利用し、WooCommerceで登録した特定の商品に対して独自のテンプレートを割り当てようとしたのですが、通常の方法では適用できなかったのでメモです。
WooCommerceの商品ページに独自のテンプレートを割り当てる
例えば商品ページのスラッグを「note」と設定し、テーマディレクトリ直下にsingle-product-note.php
というテンプレートを配置しても適用されません。これはWooCommerceがtemplate_include
フィルターにテンプレート読み込み処理をフックしているためです。(WC_Template_Loader
クラスのメソッドでフックしています)
ですので、更に追加でtemplate_includeフィルターに処理をフックしましょう。テーマのfunctions.phpに以下のコードを追加します。
function wc_product_original_template_include( $template ) {
$product_slug = "note"; // 商品のスラッグを指定
// 投稿タイプが"product"で、商品のスラッグが指定した文字列の場合
if ( get_post_type() == "product" ) {
if ( is_single( $product_slug ) ) {
// 独自テンプレートを指定
$template = get_stylesheet_directory() . "/single-product-{$product_slug}.php";
}
}
return $template;
}
add_filter( 'template_include', 'wc_product_original_template_include' );
上記のコードを追加後、以下2点の作業を行えば商品に独自テンプレートの適用が可能です。
- 2行目の
$product_slug
に商品のスラッグを指定 - テーマディレクトリ直下にsingle-product-{スラッグ名}.phpというテンプレートファイルを用意
テンプレートは8行目の指定に依存するので何でも良いのですが、分かりやすくするためWordPressのテンプレート名と同じ構造にしています。
おまけ
おまけとして、ほかの投稿タイプ詳細記事ページ用テンプレートのように、スラッグ名が一致したテンプレートがあれば自動的に読み込むコードも追記しておきます。以下のコードをfunctions.phpに入力すると、商品のスラッグと同じスラッグ名のテンプレートがあれば優先的に読み込むようになります。
function wc_product_original_template_include( $template ) {
$page = get_post( get_the_ID() );
$post_name = $page->post_name;
if ( get_post_type() == "product" && is_single( $post_name ) ) {
$template_path = get_stylesheet_directory() . "/single-product-{$post_name}.php";
if ( file_exists( $template_path ) ) {
$template = $template_path;
}
}
return $template;
}
add_filter( 'template_include', 'wc_product_original_template_include' );
例えば商品が「key」というスラッグで、テーマディレクトリ直下に「single-product-key.php」というテンプレートがあれば優先的に読み込まれるようになります。
2017年7月18日追記:
子テーマでも動くようコードの一部、get_template_directory()
をget_stylesheet_directory()
に変更しました。