ビジネス向けWEBサイトをつくる

WordPressテーマ/GENESIS(TCD103)にカスタム投稿タイプを追加する

本ページはプロモーションが含まれています

WordPressテーマTCDの「GENESIS」を購入しました。

「SOLARIS」にするか「GENESIS」にするかで悩みましたが、ブロックエディタ対応ということで「GENESIS」を選びました。

選んだのには比較的新しいテーマだということもあります。

しかし、よいことばかりではありません。

「GENESIS」のカスタム投稿タイプは「お知らせ」と「サービス(事業案内)」の2種類しかありません。

「SOLARIS」の4つのカスタム投稿タイプサポート(お知らせ・企業情報・サービス・プロジェクト)に比べると見劣りします。

そこで、「GENESIS」にカスタム投稿タイプを追加することにしました。

カスタム投稿タイプとは

WordPressに標準で搭載されている「投稿」とは別のグループとして、記事を管理するための機能です。
製品などが「投稿」とは別にページを管理できるので、便利です。

このページで、「GENESIS」にカスタム投稿タイプを追加するためのノウハウを全て公開いたします。

このページでできること

WordPressテーマにカスタム投稿タイプを追加する

こんな方のために役立つ記事
  • WordPressテーマ/GENESIS(TCD103)の購入を迷っている方
  • WordPressテーマ/GENESIS(TCD103)を購入したけど、サービス以外にも製品データをたくさん登録したい方
  • WordPressテーマのカスタマイズを具体的に知りたい方
このページで主に学べること
  • 子テーマの作り方
  • functions.phpでカスタム投稿を定義する方法
  • カスタム投稿のアーカイブページ、タクソノミーページ、シングルページのphp名称
  • カスタマイザーの設定方法
  • ショートコードの作り方
  • テンプレートを選択可能にする方法
  • テンプレートパーツの読み込み方
  • bodyクラスの活用方法
  • カスタムフィールドの作り方
  • 管理画面用のCSSやJavaScriputの読み込み方
  • 親テーマで「require」されたphpの変更方法
  • フックの取り消し方
  • フックの対象を見つける方法

記事の分量が多いので、ゆっくり、腰をすえて読み進めてください。

読んでよかったと思っていただけると期待しています。

【PR】「Theme3」では、企業サイトのWordPressテーマに「 ワードプレステーマTCD 」をオススメしています。
WordPressテーマ「GENESIS」の詳細をTCDのページで見る

ブロックエディタ対応
カスタム投稿タイプ「お知らせ」「サービス(事業案内)」
SEO機能(metaタグ、OGP、高速化)
他、機能多数。

ご購入は以下のバナーリンクページの購入ボタンをクリックしてください。

もくじ

「GENESIS」にカスタム投稿タイプを追加する考え方と子テーマのファイル構成

まず、テーマをカスタマイズする前提条件を設定します。

カスタム投稿タイプ追加の方針
  • 子テーマによるカスタマイズ
  • 添付ファイルの無効化方法
  • 「製品情報」をカスタム投稿タイプとして追加
  • 投稿タイプ名(スラッグ)「product」
  • 「製品情報」はカテゴリー(タクソノミー)で分類
  • 既サポートの「お知らせ」「サービス」投稿タイプをもとにカスタマイズ
  • トップページのインターフェイスはコンテンツビルダーで作成
  • トップページとアーカイブページの「製品情報」アイキャッチはブログと同等の大きさに表示
  • 「製品情報」ページは固定ページの機能とデザインを採用。さらに「サービス(事業案内)」カスタム投稿のフォーマットを選択可能にする
  • 「製品情報」ページはブロックエディタを採用

以上の考え方で子テーマのファイル構成を設計していきます。

先に子テーマのファイル構成結果を表にまとめておきます。

ファイル名
(フォルダー名)
機能作成方法(※備考)
(admin)カスタム投稿タイプのバックエンドを制御するJavaScriptと画像を設定します。
※以下の2ファイルを格納。
type2_image.jpgカスタム投稿タイプの設定を図示しています。※「img」フォルダーの中に配置
custom_script.jsカスタム投稿タイプのカスタムフィールドを制御するJavaScriptです。※「js」フォルダーの中に配置
ajax-product-item.phpアーカイブはajaxで指定した数分読み込みます。ページネーションでもいいのですが「お知らせ」と同様親テーマ「ajax-news-item.php」の「news」を「product」に変更してカスタマイズ
archive-product.phpアーカイブ親テーマ「archive-news.php」の「news」を「product」に変更してカスタマイズ
footer.phpカスタム投稿タイプ用のJavaScriptをまとめたphpを読み込む親テーマの同PHPにget_template_part()を追加
(functions)管理画面の下部に表示されるカスタムフィールドやカスタムCSS等の機能フォルダー
※以下の4ファイルを格納
custom_cf.phpカスタム投稿タイプ編集画面の「ページの設定」親テーマの「page_cf.php」を元に作成
custom_script.phpカスタム投稿タイプ編集画面の「カスタムCSS・スクリプト」親テーマの同PHPの対象となる投稿タイプを追加
※親テーマのフックはリムーブしない
password_form.phpカスタム投稿タイプ編集画面の「会員登録の誘導コンテンツ」同上
seo.php
カスタム投稿タイプ編集画面の「SEO」
同上
functions.php子テーマのfunctions.php
header.phpSEOのdescriptionタグを設定親テーマの同PHPのdescriptionタグを設定する関数を変更
(languages)子テーマ用の翻訳ファイルを格納します。
ja.po翻訳を定義※miなどのテキストアプリで作成
ja.moja.poをコンパイル※Poeditを使用
single-product.phpカスタム投稿タイプのシングルページを作成親テーマのpage.phpのファイル名を変更してカスタマイズ
single-type2.phpカスタム投稿タイプの別フォーマットのシングルページを作成親テーマのsingle-service.phpをもとにカスタマイズ
style.css子テーマのスタイルシート
taxonomy-product_category.phpカスタム投稿タイプのカテゴリーアーカイブ親テーマのtaxonomy-news_category.phpをカスタマイズ
(template-parts)子テーマのテンプレートパーツを格納するフォルダー。
以下の2ファイルを格納。
breadcrumb.phpパンくずを作成親テーマの同PHPにカスタム投稿タイプを追加
footer_custom_script.phpカスタム投稿タイプ用のJavaScriptをまとめたphp親テーマの「functions」フォルダー内のfooter_script.phpを元にカスタマイズ
子テーマのファイル構成(※細字はフォルダー内のファイル)

まとめてみると、たくさんのphpファイルを作成しないといけないことが分かっていただけると思います。

ほとんどのファイルは親テーマから作りますので、難易度は高くありません。

しかし、実際には思ったより手間取りました。

この「GENESIS」というテーマはJavaScriptの依存度が高いため、トップページ表示やアーカイブ表示、編集画面が複雑でした。

親テーマの「footer_script.php」のコードの分かりにくさと管理画面用の「my_script.js」以外のJavaScriptの追加がネックです。

では、ひとつひとつ説明していきます。

【PR】「Theme3」では、企業サイトのWordPressテーマに「 ワードプレステーマTCD 」をオススメしています。
WordPressテーマ「SOLARIS」の詳細をTCDのページで見る

レスポンシブ対応
カスタム投稿タイプ「お知らせ」「企業情報」「サービス」「プロジェクト」
高速化設定(絵文字読み込み・コード最適化)
他、機能多数。

ご購入は以下のバナーリンクページの購入ボタンをクリックしてください。

子テーマの作成

子テーマを作成するために、functions.phpとstyle.cssを設定します。

functions.php

<?php
// スタイルシートの読み込み -----------------------------------------------------------------------
add_action('wp_enqueue_scripts', 'theme_enqueue_styles');
function theme_enqueue_styles() {
	//wp_dequeue_style('main-style');
	wp_deregister_style('main-style');
    wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css');
    wp_enqueue_style( 'parent-design-plus', get_template_directory_uri() . '/css/design-plus.css', array('parent-style'),version_num() );
    wp_enqueue_style( 'parent-sns-botton', get_template_directory_uri() . '/css/sns-botton.css', array('parent-style'),version_num() );
    wp_enqueue_style( 'parent-responsive', get_template_directory_uri() . '/css/responsive.css', array('parent-style'),version_num(), 'screen and (max-width:1391px)' );
    wp_enqueue_style( 'style-child', get_stylesheet_directory_uri() . '/style.css', array( 'parent-style' ) );
    //JSをフッタで読み込む
	//wp_enqueue_script( 'jscript-child', get_stylesheet_directory_uri() . '/js/jscript.js', array(), '', true );
}

// 「wp_attachment_pages_enabled」を常に「false」にする  --------------------------------------------------------------------------------
add_filter( 'option_wp_attachment_pages_enabled', '__return_false' );


// 翻訳ファイルの読み込み  --------------------------------------------------------------------------------
function wpdocs_child_theme_setup() {
    load_child_theme_textdomain( 'tcd-genesis-child', get_stylesheet_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'wpdocs_child_theme_setup' );

//以下省略

functions.phpの冒頭部分です。

「GENESIS」の親のstyle.cssはwp_deregister_style(‘main-style’);で無効にします。

注意点は「main-style」を無効にすると、以下の3つが削除されてしまうことです。

main-styleに紐付いているcss
  • design-plus.css
  • sns-botton.css
  • responsive.css

いずれも重要なcssですので、子テーマで読み込むことが必要になります。

私は添付ファイルページがGoogleのキャッシュされた経験があるので、add_filter( ‘option_wp_attachment_pages_enabled’, ‘__return_false’ );で添付ファイルを無効化しています。

子テーマ用の翻訳ファイルも読み込みます。

style.css

style.cssの先頭は以下のように記述します。

@charset "utf-8";
/*
Theme Name:genesis_child
Author:Slashd
Template:genesis_tcd103
Version:1.5
*/

「genesis_child」は子テーマのフォルダー名称です。

【PR】「Theme3」では、企業サイトのWordPressテーマに「 ワードプレステーマTCD 」をオススメしています。
WordPressテーマ「GENESIS」の詳細をTCDのページで見る

ブロックエディタ対応
カスタム投稿タイプ「お知らせ」「サービス(事業案内)」
SEO機能(metaタグ、OGP、高速化)
他、機能多数。

ご購入は以下のバナーリンクページの購入ボタンをクリックしてください。

カスタム投稿タイプの設定をカスタマイザーでサポートする

「GENESIS」にカスタム投稿タイプを追加する場合、クリアしなければいけない問題があります。

それは、新しく追加するカスタム投稿タイプの定義が、TCDテーマオプションにないということです。

TCDテーマオプションとはTCDテーマの初期設定を行う機能です。

「GENESIS」では、以下の11項目を設定できます。

  • 基本設定
  • トップページ
  • ブログ
  • お知らせ
  • サービス
  • ヘッダー
  • フッター
  • 保護ページ
  • クイックタグ
  • SEO
  • テーマオプション管理

ここではそれぞれの設定項目についての解説は割愛します。

しかし、お分かりのようにカスタム投稿タイプ「お知らせ」や「サービス」の設定はここで管理しています。

「製品情報」をカスタム投稿タイプで追加する場合は、このTCDテーマオプションに項目を追加するのが良さそうです。

しかし、TCDテーマオプションはTCDテーマの根幹の部分であるため、この機能を子テーマで書き換えるのは開発のリスクが高まります。

そこで、新規追加するカスタム投稿タイプ「製品情報」の設定はカスタマイザーを使うことで対応します。

以下のコードでカスタム投稿設定用のカスタマイザーができあがります。

$wp_customize->add_section( 'my_theme_origin_scheme2', array(
  'title'     => __( 'Product custom post settings', 'tcd-genesis-child' ), // 項目名
  'priority'  => 200, // 優先順位
));

//見出し(トップページ・アーカイブ)
$wp_customize->add_setting('product_headline_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_headline_txt', array(
	'label' => __( 'Heading (top page archive)', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_headline_txt',
    'type' => 'text',
));
//子見出し(トップページ・アーカイブ)
$wp_customize->add_setting('product_sub_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_sub_txt', array(
	'label' => __( 'Child heading (top page archive)', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_sub_txt',
    'type' => 'text',
));
//トップページ説明文
$wp_customize->add_setting('product_top_desc_pc_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_top_desc_pc_txt', array(
	'label' => __( 'Top page description', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_top_desc_pc_txt',
    'type' => 'text',
));
//トップページ説明文(モバイル)
$wp_customize->add_setting('product_top_desc_mobile_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_top_desc_mobile_txt', array(
	'label' => __( 'Top page description (mobile)', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_top_desc_mobile_txt',
    'type' => 'text',
));
//トップページリンクボタンラベル名
$wp_customize->add_setting('product_top_label_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_top_label_txt', array(
	'label' => __( 'Top page link button label name', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_top_label_txt',
    'type' => 'text',
));
//アーカイブ説明文
$wp_customize->add_setting('product_desc_pc_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_desc_pc_txt', array(
	'label' => __( 'Archive description', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_desc_pc_txt',
    'type' => 'text',
));
//アーカイブ説明文(モバイル)
$wp_customize->add_setting('product_desc_mobile_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_desc_mobile_txt', array(
	'label' => __( 'Archive description (mobile)', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_desc_mobile_txt',
    'type' => 'text',
));
//アーカイブtitleタグ
$wp_customize->add_setting('product_title_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_title_txt', array(
	'label' => __( 'Archive title tag', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_title_txt',
    'type' => 'text',
));
//アーカイブdescriptionタグ
$wp_customize->add_setting('product_desc_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_desc_txt', array(
	'label' => __( 'Archive description tag', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_desc_txt',
    'type' => 'text',
));
//トップページ表示数
$wp_customize->add_setting( 'product_top_pc_number', array(
	'default'           => '6',
	'type'  => 'theme_mod',
	'sanitize_callback' => 'display_number_field',
) );
$wp_customize->add_control( 'product_top_pc_number', array(
	'settings'    => 'product_top_pc_number',
	'label'       => __( 'Number of top page displayed', 'tcd-genesis-child' ),
	'section'     => 'my_theme_origin_scheme2',
	'type'        => 'number',
	'input_attrs' => array(
		'min'  => 1,
		'max'  => 24,
		'step' => 1,
	),
) );
//トップページ表示数(モバイル)
$wp_customize->add_setting( 'product_top_mobile_number', array(
	'default'           => '6',
	'type'  => 'theme_mod',
	'sanitize_callback' => 'display_number_field',
) );
$wp_customize->add_control( 'product_top_mobile_number', array(
	'settings'    => 'product_top_mobile_number', 
	'label'       => __( 'Number of top page displayed (mobile)', 'tcd-genesis-child' ),
	'section'     => 'my_theme_origin_scheme2',
	'type'        => 'number',
	'input_attrs' => array(
		'min'  => 1,
		'max'  => 24,
		'step' => 1,
	),
) );
//アーカイブ表示数
$wp_customize->add_setting( 'product_pc_number', array(
	'default'           => '6',
	'type'  => 'theme_mod',
	'sanitize_callback' => 'display_number_field',
) );
$wp_customize->add_control( 'product_pc_number', array(
	'label'       => __( 'Number of archives displayed', 'tcd-genesis-child' ),
	'section'     => 'my_theme_origin_scheme2',
	'settings'    => 'product_pc_number', 
	'type'        => 'number',
	'input_attrs' => array(
		'min'  => 1,
		'max'  => 24,
		'step' => 1,
	),
) );
//アーカイブ表示数(モバイル)
$wp_customize->add_setting( 'product_mobile_number', array(
	'default'           => '6',
	'type'  => 'theme_mod',
	'sanitize_callback' => 'display_number_field',
) );
$wp_customize->add_control( 'product_mobile_number', array(
	'label'       => __( 'Number of archives displayed (mobile)', 'tcd-genesis-child' ),
	'section'     => 'my_theme_origin_scheme2',
	'settings'    => 'product_mobile_number', 
	'type'        => 'number',
	'input_attrs' => array(
		'min'  => 1,
		'max'  => 24,
		'step' => 1,
	),
) );
//ラベル名(パンくずリスト)
$wp_customize->add_setting('product_label_txt', array(
    'type' => 'option',
));
$wp_customize->add_control('product_label_txt', array(
	'label' => __( 'Label name (breadcrumb)', 'tcd-genesis-child' ),
	'section' => 'my_theme_origin_scheme2',
    'settings' => 'product_label_txt',
    'type' => 'text',
));
}
add_action( 'customize_register', 'my_theme_customize_register' );

/* japanese start */
function display_number_field( $value ) {
	if ( preg_match("/^[0-9]+$/", $value) ) {
		return $value;
	} else {
		return '6';
	}
}
カスタム投稿タイプ「製品情報」の定義カスタマイザー

実はもう一つ項目を追加して、アーカイブ画像を一覧に表示するかどうかを設定すればいいのですが、製品情報ということもあり、画像を表示しない設定は考えづらいので、カスタマイザーでのサポートを省略しました。

カスタマイザーですので、翻訳対応しなくてもよかったのですが、一応「ja.mo」に登録しました。

ja.moの作り方は以下を参照してください。

カスタマイザー設定で、注意する点は「アーカイブ表示数」‘type’ => ‘theme_mod’にしてある点です。

カスタマイザーは表示設定は可能ですが、値を変更しないとnullになっています。

‘type’ => ‘theme_mod’にすることで、データ取得時に初期値を設定することができます。

値を取得する際にget_theme_mod(‘product_pc_number’,6);とすることで、初期値「6」を設定できます。

もちろん、全項目を‘type’ => ‘theme_mod’にしても、かまいません。

その場合は、全てget_theme_mod()で取得します。

カスタム投稿タイプをfunctions.phpで定義する

カスタム投稿タイプはプラグインを使用しても追加できます。

しかし、「GENESIS」の既存のカスタム投稿タイプ「お知らせ」「サービス」のコードを利用得して新しいカスタム投稿タイプ「製品情報」を作りますので、親テーマの「functions.php」のコードを使って定義する方がよいでしょう。

// カスタム投稿とタクソノミーの追加 --------------------------------------------------------------------------------

function child_custom_post_type_init() {

$options = get_design_plus_option();

// カスタム投稿タイプ「製品」 --------------------------------------------------------------------------------
$product_label = __( 'Products', 'tcd-genesis-child' );
$product_slug = 'product';
$product_labels = array(
  'name' => $product_label,
  'add_new' => __( 'Add New', 'tcd-genesis' ),
  'add_new_item' => __( 'Add New Item', 'tcd-genesis' ),
  'edit_item' => __( 'Edit', 'tcd-genesis' ),
  'new_item' => __( 'New item', 'tcd-genesis' ),
  'view_item' => __( 'View Item', 'tcd-genesis' ),
  'search_items' => __( 'Search Items', 'tcd-genesis' ),
  'not_found' => __( 'Not Found', 'tcd-genesis' ),
  'not_found_in_trash' => __( 'Not found in trash', 'tcd-genesis' ),
  'parent_item_colon' => ''
);

register_post_type( 'product', array(
  'label' => $product_label,
  'labels' => $product_labels,
  'public' => true,
  'publicly_queryable' => true,
  'menu_position' => 5,
  'show_ui' => true,
  'query_var' => true,
  'rewrite' => array( 'slug' => $product_slug ),
  'capability_type' => 'post',
  'has_archive' => true,
  'hierarchical' => false,
  'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt'),
  'show_in_rest' => true	// ブロックエディターを使用
));

// カテゴリー
$product_category_label = sprintf(__('%s category', 'tcd-genesis'), $product_label);
$product_category_slug = $product_slug . '_category';
$product_category_labels = array(
  'name' => $product_category_label,
  'singular_name' => $product_category_label
);
register_taxonomy( 'product_category', 'product', array(
  'labels' => $product_category_labels,
  'hierarchical' => true,
  'public' => true,
  'show_in_rest' => true,
  'rewrite' => array( 'slug' => $product_category_slug )
));


// 説明文カラムを消す
add_filter('manage_edit-product_category_columns', function ( $columns ) {
    if( isset( $columns['description'] ) )
        unset( $columns['description'] );   
    return $columns;
});


// カスタム投稿タイプ「製品」ここまで

}
add_action( 'init', 'child_custom_post_type_init' );

親テーマの「functions.php」のカスタム投稿「サービス」をコピーして作成しています。

$product_label $product_slugは固定にしました。

トップページにショートコードでカスタム投稿タイプ一覧を表示する

「GENESIS」のトップページはTCDテーマ特有のコンテンツビルダーと、固定ページをブロックエディタで作成し、トップページにする2種類の方法が用意されています。

トップページはコンテンツビルダーで作る方が分かりやすいので、コンテンツビルダーの作成を選択しました。

「GENESIS」のコンテンツビルダーは以下の5種類が用意されています。

「GENESIS」トップページのコンテンツビルダー
  • デザインバナー
  • サービス一覧
  • ブログ一覧
  • お知らせ一覧
  • フリースペース

当然、カスタム投稿タイプ「製品情報」の一覧はコンテンツビルダーとして用意されていません。

このような場合はショートコードを作成し、フリースペースを使用することで解決します。

以下が「functions.php」に登録するショートコードです。

// 製品情報一覧を表示するショートコード -----------------------------------------------------------------------
function product_list_short_cord ($arg) {	
ob_start();
	global $post;
	$options = get_design_plus_option();
	
	$headline  = get_option('product_headline_txt');
    $sub_title = get_option('product_sub_txt');

    $desc = get_option('product_top_desc_pc_txt');
    $desc_mobile = get_option('product_top_desc_mobile_txt');
    $button_label = get_option('product_top_label_txt');

    $post_num = get_theme_mod('product_top_pc_number',6);
    $post_num_sp = get_theme_mod('product_top_mobile_number',6);
    
    $show_image = 'display';
	?>
	<section class="cb_product_list">
        <div class="design_header cb_design_header inview">
            <div class="title_area<?php if(!$desc){ echo ' no_desc'; }; ?>">
                <?php if($headline){ ?>
                <h3 class="large_headline"><span><?php echo wp_kses_post(nl2br($headline)); ?></span></h3>
                <?php }; ?>
                <?php if($sub_title){ ?>
                <p class="sub_title colored"><span><?php echo esc_html($sub_title); ?></span></p>
                <?php }; ?>
            </div>
            <?php if($desc){ ?>
            <p class="desc <?php if($desc_mobile){ echo 'pc'; }; ?> post_content"><?php echo wp_kses_post(nl2br($desc)); ?></p>
            <?php if($desc_mobile){ ?>
            <p class="desc mobile post_content"><?php echo wp_kses_post(nl2br($desc_mobile)); ?></p>
            <?php }; ?>
            <?php }; ?>
        </div>
        <div class="main_content inview">
            <?php
            // カテゴリー一覧 --------------------------------------
            $product_category_list = get_terms( 'product_category', array( 'hide_empty' => true ) );
            $category_total = count( $product_category_list );
            if ( $product_category_list && !is_wp_error( $product_category_list ) && ( $category_total > 1 ) ) {
                ?>
            <div class="product_category_button swiper">
                <ol class="swiper-wrapper">
                    <li class="swiper-slide current"><a data-category-id="product_cat_all" href="<?php echo esc_url(get_post_type_archive_link('product')); ?>">
                        <?php _e('All products', 'tcd-genesis-child');  ?>
                        </a></li>
                    <?php
                    foreach ( $product_category_list as $cat ):
                        $cat_id = $cat->term_id;
                    $cat_name = $cat->name;
                    $cat_url = get_term_link( $cat_id, 'product_category' );
                    ?>
                    <li class="swiper-slide"><a data-category-id="product_cat_<?php echo esc_attr($cat_id); ?>" href="<?php echo esc_url($cat_url); ?>"><?php echo esc_html($cat_name); ?></a></li>
                    <?php endforeach; ?>
                </ol>
            </div>
            <div class="genesis_carousel_scrollbar">
                <div class="product_category_scrollbar swiper-scrollbar"></div>
            </div>
            <?php }; ?>
            <div id="index_product_list_wrap">
                <?php
                // 最新の記事一覧 ----------------------
                if ( is_mobile() ) {
                    $post_num = $post_num_sp;
                } else {
                    $post_num = $post_num;
                };
                $args = array( 'post_type' => 'product', 'posts_per_page' => $post_num );
                $post_list = new wp_query( $args );
                if ( $post_list->have_posts() ):
                    ?>
                <div class="index_product_list active" id="product_cat_all">
                    <div class="index_product_list_inner">
                        <div class="product_carousel_cat_all_wrap">
                            <div class="product_carousel_wrap swiper" id="product_carousel_cat_all">
                                <div class="product_carousel swiper-wrapper">
                                    <?php
                                    while ( $post_list->have_posts() ): $post_list->the_post();
                                    if ( $show_image == 'display' ) {
                                        if ( has_post_thumbnail() ) {
                                            $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'size2' );
                                        } elseif ( $options[ 'no_image' ] ) {
                                            $image = wp_get_attachment_image_src( $options[ 'no_image' ], 'full' );
                                        } else {
                                            $image = array();
                                            $image[ 0 ] = get_bloginfo( 'template_url' ) . "/img/no_image2.gif";
                                            $image[ 1 ] = '770';
                                            $image[ 2 ] = '520';
                                        }
                                    }
                                    ?>
                                    <div class="item swiper-slide<?php if($show_image == 'hide'){ echo ' no_image'; }; ?>">
                                        <?php if($show_image == 'display'){ ?>
                                        <a class="image_link animate_background" href="<?php the_permalink(); ?>">
                                        <div class="image_wrap"> <img loading="lazy" class="image" src="<?php echo esc_attr($image[0]); ?>" width="<?php echo esc_attr($image[1]); ?>" height="<?php echo esc_attr($image[2]); ?>" /> </div>
                                        </a>
                                        <?php }; ?>
                                        <div class="content">
                                            <?php
                                            $post_category = wp_get_post_terms( $post->ID, 'product_category', array( 'orderby' => 'term_order' ) );
                                            if ( $post_category && !is_wp_error( $post_category ) ) {
                                                foreach ( $post_category as $post_cat ):
                                                    $post_cat_name = $post_cat->name;
                                                $post_cat_id = $post_cat->term_id;
                                                break;
                                                endforeach;
                                                ?>
                                            <a class="category_button" href="<?php echo esc_url(get_term_link($post_cat_id,'product_category')); ?>"><?php echo esc_html($post_cat_name); ?></a>
                                            <?php
                                            };
                                            ?>
                                            <h4 class="title"><a href="<?php the_permalink(); ?>"><span>
                                                <?php the_title(); ?>
                                                </span></a></h4>
                                            <time class="date entry-date published" datetime="<?php the_modified_time('c'); ?>">
                                                <?php the_time('Y.m.d'); ?>
                                            </time>
                                        </div>
                                    </div>
                                    <?php endwhile; ?>
                                </div>
                                <!-- END .product_carousel --> 
                            </div>
                            <!-- END .product_carousel_wrap --> 
                        </div>
                        <!-- END .product_carousel_cat_all_wrap -->
                        <div class="genesis_carousel_scrollbar">
                            <div class="swiper-scrollbar" id="product_carousel_scrollbar"></div>
                        </div>
                    </div>
                    <!-- END index_product_list_inner --> 
                </div>
                <!-- END index_product_list -->
                <?php endif; ?>
                <?php
                // カテゴリー別 記事一覧 ---------------------------------------------------
                if ( $product_category_list && !is_wp_error( $product_category_list ) ):
                    $i = 1;
                foreach ( $product_category_list as $cat ):
                    $cat_id = $cat->term_id;
                $args = array( 'post_type' => 'product', 'posts_per_page' => $post_num, 'tax_query' => array( array( 'taxonomy' => 'product_category', 'field' => 'term_id', 'terms' => $cat_id ) ) );
                $post_list = new wp_query( $args );
                $all_post_count = $post_list->found_posts;
                if ( $post_list->have_posts() ):
                    ?>
                <div class="index_product_list" id="product_cat_<?php echo esc_attr($cat_id); ?>">
                    <div class="index_product_list_inner">
                        <div class="product_carousel_wrap swiper" id="product_carousel_cat_<?php echo esc_attr($cat_id); ?>">
                            <div class="product_carousel swiper-wrapper">
                                <?php
                                while ( $post_list->have_posts() ): $post_list->the_post();
                                if ( $show_image == 'display' ) {
                                    if ( has_post_thumbnail() ) {
                                        $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'size2' );
                                    } elseif ( $options[ 'no_image' ] ) {
                                        $image = wp_get_attachment_image_src( $options[ 'no_image' ], 'full' );
                                    } else {
                                        $image = array();
                                        $image[ 0 ] = get_bloginfo( 'template_url' ) . "/img/no_image2.gif";
                                        $image[ 1 ] = '770';
                                        $image[ 2 ] = '520';
                                    }
                                }
                                ?>
                                <div class="item swiper-slide<?php if($show_image == 'hide'){ echo ' no_image'; }; ?>">
                                    <?php if($show_image == 'display'){ ?>
                                    <a class="image_link animate_background" href="<?php the_permalink(); ?>">
                                    <div class="image_wrap"> <img loading="lazy" class="image" src="<?php echo esc_attr($image[0]); ?>" width="<?php echo esc_attr($image[1]); ?>" height="<?php echo esc_attr($image[2]); ?>" /> </div>
                                    </a>
                                    <?php }; ?>
                                    <div class="content">
                                        <?php
                                        $post_category = wp_get_post_terms( $post->ID, 'product_category', array( 'orderby' => 'term_order' ) );
                                        if ( $post_category && !is_wp_error( $post_category ) ) {
                                            foreach ( $post_category as $post_cat ):
                                                $post_cat_name = $post_cat->name;
                                            $post_cat_id = $post_cat->term_id;
                                            break;
                                            endforeach;
                                            ?>
                                        <a class="category_button" href="<?php echo esc_url(get_term_link($post_cat_id,'product_category')); ?>"><?php echo esc_html($post_cat_name); ?></a>
                                        <?php
                                        };
                                        ?>
                                        <h4 class="title"><a href="<?php the_permalink(); ?>"><span>
                                            <?php the_title(); ?>
                                            </span></a></h4>
                                        <time class="date entry-date published" datetime="<?php the_modified_time('c'); ?>">
                                            <?php the_time('Y.m.d'); ?>
                                        </time>
                                    </div>
                                </div>
                                <?php endwhile; ?>
                            </div>
                            <!-- END .product_carousel --> 
                        </div>
                        <!-- END .product_carousel_wrap -->
                        <div class="genesis_carousel_scrollbar">
                            <div class="swiper-scrollbar" id="product_carousel_scrollbar_cat_<?php echo esc_attr($cat_id); ?>"></div>
                        </div>
                    </div>
                    <!-- END index_product_list_inner --> 
                </div>
                <!-- END index_product_list -->
                <?php
                endif;
                wp_reset_postdata();
                $i++;
                endforeach;
                endif;
                ?>
            </div>
            <!-- END #index_product_list_wrap -->
            
            <?php if($button_label){ ?>
            <div class="design_arrow_button cb_design_arrow_button"> <a href="<?php echo esc_url(get_post_type_archive_link('product')); ?>"><span class="label"><?php echo esc_html($button_label); ?></span><span class="arrow_button"></span></a> </div>
            <?php }; ?>
        </div>
    </section>
<?php	
return ob_get_clean();
}
add_shortcode('product_list', 'product_list_short_cord');

ショートコードはadd_shortcode()で追加します。ob_start()はバッファリングの指定です。

親テーマの「front-page.php」の「お知らせ記事一覧」のコードをコピーして作成します。

「news」なっている箇所を「product」に変更すればできあがります。

あとは、カスタマイザーで設定された項目を取得し、初期設定を行います。

カスタマイザーのデータ取得方法

‘type’ => ‘option’の場合はget_option()、’type’ => ‘option’の場合はget_option()、’type’ => ‘theme_mod’の場合はget_theme_mod()で取得します。

初期設定が可能なのはget_theme_mod()の場合です。

アーカイブ画像の大きさは「ブログ記事一覧」と同様に設定します。

$image[ 0 ] = get_bloginfo( 'template_url' ) . "/img/no_image2.gif";
$image[ 1 ] = '770';
$image[ 2 ] = '520';

このショートコード「product_list」をトップページのコンテンツビルダー「フリースペースで記述します。

カスタム投稿タイプのCSS

「フリースペース」を使用した際に注意する点は、フリースペースのパディングやマージンが追加されてしまうことです。

そのため、不都合なCSSをリセットしてやる必要があります。

/* フリースペース */
.cb_free_space:has(.cb_product_list) { padding:0; }
.cb_free_space .post_content:has(.cb_product_list) { max-width:initial; margin:0 auto; padding:0; }
.cb_free_space .post_content .cb_product_list a {
	text-decoration: none;
	color: inherit;
}
.cb_free_space .post_content .solution_category_button li.current a,
.cb_free_space .post_content .product_category_button li.current a {
	color: #fff;
}

トップページ以外にもアーカイブページのCSSもカスタム投稿タイプ「お知らせ」のCSSをもとに追加します。

/* 製品カルーセル */
.cb_product_list { padding:150px 0; }
.cb_product_list:nth-child(even) { background:#f6f6f6; }
.product_carousel_wrap { width:auto; margin:0 auto !important; padding:0 100px !important; }
@media only screen and (min-width: 1720px) {
  .product_carousel_wrap { padding-left:calc(50% - 750px) !important; padding-right:calc(50% - 750px) !important; }
}
.product_carousel { -webkit-user-select:none; user-select:none; }
.product_carousel { }
.product_carousel .item { position:relative; width:385px; margin: 0 50px 0 0; }
.product_carousel .image_link { display:block; width:100%; height:auto; position:relative; z-index:1; overflow:hidden; border-radius:5px; aspect-ratio:385 /260; margin: 0 0 30px 0;}
.product_listproduct_carousel.image_wrap { width:100%; height:100%; position:relatiive; overflow:hidden; z-index:2; }
.product_carousel .image_wrap img { width:100%; height:100%; position:absolute; top:0; left:0; object-fit:cover; }
.product_carousel .content { width:auto; }
.product_carousel .no_image .content { width:auto; padding:0; }
.product_carousel .category_button { margin-bottom:25px; }
.product_carousel .title { font-size:20px; line-height:1.8; margin-bottom:20px; }
.product_carousel .title a { display:block; max-height:3.6em; overflow:hidden; visibility:visible; }
.product_carousel .title span { display:-webkit-inline-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; }
.product_carousel .date { position:relative; color:#999; font-size:16px; margin:0; display:block; }
.product_carousel .date:before { font-family:'design_plus'; content:'\e903'; font-size:17px; margin:0 5px 0 0; position:relative; top:1px; }
.product_carousel_wrap + .genesis_carousel_scrollbar .swiper-scrollbar { margin-top:60px !important; }
.product_carousel_cat_all_wrap + .genesis_carousel_scrollbar .swiper-scrollbar { margin-top:60px !important; }
#index_product_list_wrap { position:relative; }
.index_product_list { display:none; pointer-events:none; }
.index_product_list.active { display:block; pointer-events:auto; }
.product_carousel_wrap { opacity:0; position:relative; }
.product_carousel_cat_all_wrap { opacity:0; transform: translate3d(140px,0,0); }
.cb_product_list .main_content.animate .product_carousel_cat_all_wrap { opacity:1; transform: translate3d(0,0,0); transition: transform 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.2s, opacity 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0.2s; }
.index_product_list.active .product_carousel_wrap { animation: index_product_tab_animate 1.4s cubic-bezier(0.22, 1, 0.36, 1) forwards 0.2s; }
@keyframes index_product_tab_animate {
  0% { opacity:0; top:0px; left:140px; }
  100% { opacity:1; top:0px; left:0; }
}
.cb_product_list .main_content .product_category_button, .cb_product_list .main_content .genesis_carousel_scrollbar { position:relative; transform: translate3d(0,30px,0); opacity:0; transition: opacity 1.4s ease 0s, transform 1.4s cubic-bezier(0.22, 1, 0.36, 1) 0s; }
.cb_product_list .main_content.animate .product_category_button, .cb_product_list .main_content.animate .genesis_carousel_scrollbar { transform: translate3d(0,0,0); opacity:1; }

/* カテゴリー一覧 */
.product_category_button { position:relative; width:auto; margin:0 auto 55px; padding:0 100px !important; }
@media only screen and (min-width: 1720px) {
  .product_category_button { padding-left:calc(50% - 750px) !important; padding-right:calc(50% - 750px) !important; }
}
.product_category_button ol { -webkit-user-select:none; user-select:none; }
.product_category_button li { flex: 0 0 auto !important; width:auto !important; min-width:140px; margin-right:20px; }
.product_category_button li:last-of-type { margin-right:0; }
.product_category_button a { height:50px; line-height:50px; border:1px solid #ddd; padding:0 25px; display:block; border-radius:50px; text-align:center; background:#fff; }
.product_category_button a:hover { color:#fff; }
.product_category_button li.current a { background:#000; border-color:#000; color:#fff; pointer-events:none; }
.product_category_button + .genesis_carousel_scrollbar { top:-25px !important; }

/* 追加 */
.product_category_button ol {
	margin-left: 0em !important;
}
.single-product #bread_crumb {
    max-width: 1700px !important;
    margin: 38px auto 130px !important;
}

/* 製品情報一覧 */
#archive_product { position:relative; max-width:1700px; margin:0 auto; padding:0 100px 150px; }
.product_list { display:flex; flex-wrap:wrap; position:relative; margin-bottom: -50px; justify-content: space-between; }
.product_list .item { position:relative; width: calc(100% / 3 - 32px);
	margin-bottom: 50px;
}
.product_list:after { 
	content: "";
	display: block; 
	width: calc(100% / 3 - 32px);
	height: 0;
}
.product_list:after { content: ""; display: block; width: calc(100% / 3 - 32px); height: 0; }
.product_list .image_link { display:block; width:100%; height:auto; position:relative; z-index:1; overflow:hidden; border-radius:5px; aspect-ratio:385 /260; margin: 0 0 30px 0;}
.product_list .image_wrap { width:100%; height:100%; position:relatiive; overflow:hidden; z-index:2; }
.product_list .image_wrap img { width:100%; height:100%; position:absolute; top:0; left:0; object-fit:cover; }
.product_list .no_image .content { width:auto; padding:0; }
.product_list .category_button { margin-bottom:25px; }
.product_list .title { font-size:20px; line-height:1.8; margin-bottom:20px; }
.product_list .title a { display:block; max-height:3.6em; overflow:hidden; visibility:visible; }
.product_list .title span { display:-webkit-inline-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; }
.product_list .date { position:relative; color:#999; font-size:16px; margin:0; display:block; }
.product_list .date:before { font-family:'design_plus'; content:'\e903'; font-size:17px; margin:0 5px 0 0; position:relative; top:1px; }

レスポンシブ対応は以下のCSSが必要です。

/* ----------------------------------------------------------------------
レスポンシブ:製品情報
---------------------------------------------------------------------- */
/* 製品情報一覧 */
.product_carousel .title {
	margin-top:inherit;
	margin-left:inherit;
	margin-right:inherit;
	margin-bottom: 20px;
}
@media screen and (max-width:1391px) {
	.product_carousel_wrap { padding:0 60px !important; }
}
@media screen and (max-width:1100px) {
	.product_carousel_wrap { /*height:190px;*/ padding:0 40px !important; }
  .product_carousel .item { width: 260px;
      margin: 0 20px 0 0; }
	.product_carousel .image_link { margin: 0 0 20px 0; }
	.product_carousel .content {  width: 260px; }
	.product_carousel .category_button { margin-bottom:15px; }
	.product_carousel .title { font-size: 16px;
	margin-top: 0px;
	    margin-bottom: 13px;
	    line-height: 1.6; }
	.product_carousel .date { font-size:14px; }
	.product_carousel .date::before { font-size:16px; top:1.5px; }
}
@media screen and (max-width:800px) {
	.cb_product_list { padding:40px 0; }
	.cb_product_list .design_header { margin-bottom:40px; }
	.product_carousel_wrap { /*height:195px;*/ padding:0 20px !important; }
	.product_carousel_wrap + .genesis_carousel_scrollbar .swiper-scrollbar { margin-top:40px !important; }
	.product_carousel_cat_all_wrap + .genesis_carousel_scrollbar .swiper-scrollbar { margin-top:40px !important; }
	.cb_product_list .cb_design_arrow_button { margin-top:35px; }
}

/* ----------------------------------------------------------------------
 製品情報
---------------------------------------------------------------------- */
@media screen and (max-width:1391px) {
.product_category_button { padding:0 60px !important; }
/* ブログ一覧 */
#archive_product { max-width:inherit; padding:0 60px 150px; }
}
@media screen and (max-width:1100px) {
.product_category_button { padding:0 40px !important; margin-top:-12px; }
	.product_category_button li { min-width:120px; margin-right:10px; }
.product_category_button li:last-of-type { margin-right:0; }
	.product_category_button a { height:40px; line-height:40px; padding:0 20px; font-size:14px; }
	
  #archive_product { padding:0 40px 150px; }
}
@media screen and (max-width:1000px) {
  .product_list .item { position:relative; width:calc(50% - 20px); margin:0 40px 50px 0; }
  #archive_product .product_list .item:nth-child(3n) { margin-right:40px; }
  #archive_product .product_list .item:nth-child(2n) { margin-right:0px; }
}
@media screen and (max-width:800px) {
.product_category_button { padding:0 20px !important; margin:0px 0 40px 0; }

  #archive_product { padding:0 20px 40px; }
	body.paged #archive_product { padding-top:20px; }
	.product_list { margin-bottom:-30px; }
  .product_list .item { position:relative; width:calc(50% - 10px); margin:0 20px 30px 0; }
  #archive_product .product_list .item:nth-child(3n) { margin-right:20px; }
  #archive_product .product_list .item:nth-child(2n) { margin-right:0px; }
	.product_list .title { font-size:16px; margin-bottom:10px; }
	.product_list .date { font-size:14px; }
	.product_list .date::before { font-size:16px; top:1.5px; }
	.product_list .image_link { margin-bottom:20px; }
	.product_list .category_button { margin-bottom:15px; }
}
@media screen and (max-width:600px) {
	#archive_product .product_list { display:block; margin-bottom:0; }
  .product_list .item { width:auto; margin:0 0 30px 0; }
  #archive_product .product_list .item:nth-child(3n) { margin-right:0; }
}

head内CSSの設置

これまでの設定で、以下のようなトップページ一覧が表示されます。

トップページのカスタム投稿タイプ一覧

ボタンの色が「TCDテーマオプション」で設定したカラーになっていないことがわかります。

これは、head内CSSを設定することで解決します。

親テーマを調べると「functions」フォルダーの「head.php」にdo_action( ‘tcd_head_css’ );があることがわかります。

このdo_actionにカスタム投稿用のcss設定をフックします。

do_actionにフックできると覚えておいてください。フックできる箇所を見つけるには「do_action」を探します。

以下を「functions.php」に記述すればOKです。

function custom_head_css(){
	$options = get_design_plus_option();
    global $post;
    // メインカラー ----------------------------------
    $main_color = $options['main_color'];
    $main_color_hex = hex2rgb($main_color);
    $main_color_hex = implode(",",$main_color_hex);
    $hover_color = adjustBrightness($main_color, -30); ?>
    
    .cb_free_space .post_content .solution_carousel .title a:hover,.cb_free_space .post_content .solution_carousel .category_button,.solution_carousel .category_button,.cb_free_space .post_content .solution_category_button a:hover,.solution_category_button a:hover { color:<?php echo esc_html($main_color); ?>; }
    .solution_category_button li.current a { background-color:<?php echo esc_html($main_color); ?>; }
    .solution_category_button li.current a, .solution_category_button a:hover { border-color:<?php echo esc_html($main_color); ?>; }
    .cb_free_space .post_content .solution_carousel .category_button:hover { color:<?php echo esc_html($hover_color); ?>; }
    
    .cb_free_space .post_content .product_carousel .title a:hover,.cb_free_space .post_content .product_carousel .category_button,.product_carousel .category_button,.cb_free_space .post_content .product_category_button a:hover,.product_category_button a:hover { color:<?php echo esc_html($main_color); ?>; }
    .product_category_button li.current a { background-color:<?php echo esc_html($main_color); ?>; }
    .product_category_button li.current a, .product_category_button a:hover { border-color:<?php echo esc_html($main_color); ?>; }
    .cb_free_space .post_content .product_carousel .category_button:hover { color:<?php echo esc_html($hover_color); ?>; }
    
<?php }
add_action('tcd_head_css', 'custom_head_css');

以下のようにメインカラーがボタンに設定されました。

トップページのカスタム投稿タイプ一覧(カラー設定反映済み)

表示上は問題がなくなりました。

トップページとアーカイブページ用のJavaScript(jQuery)

しかし、この時点でカテゴリーボタンを押すと「お知らせ」一覧のような動きをしないことが分かります。

それは、カスタム投稿用のJavaScript(jQuery)が足りないからです。

テンプレートパーツ「footer_custom_script.php」を作る

親テーマの「functions」フォルダーの「footer_script.php」でカスタム投稿タイプ「お知らせ」の一覧は制御されています。

「footer_script.php」をもとに、カスタム投稿タイプ「製品情報」用のスクリプトをまとめたphpを作ります。

<?php if(is_post_type_archive('product') || is_tax('product_category') || is_front_page()) { ?>

<script>
<?php
     // 共通のスクリプト --------------------------------------------------------------------------
       global $post;
       $options = get_design_plus_option();
?>
<?php
     // トップページ ------------------------------
     if(is_front_page()) {
?>
(function($) {
  
let product_carousel_cat_all;
  <?php
       $product_category_list = get_terms( 'product_category', array('hide_empty' => true ) );
       $category_total = count($product_category_list);
       if ( $product_category_list && ! is_wp_error( $product_category_list ) && ($category_total > 1) ) {
         foreach ( $product_category_list as $cat ):
           $cat_id = $cat->term_id;
  ?>
  let product_carousel_cat_<?php echo esc_attr($cat_id); ?>;
  <?php
         endforeach;
       };
  ?>

  function init_product_carousel(){

  if( $('#product_carousel_cat_all').length ){
    if(product_carousel_cat_all != undefined){
      product_carousel_cat_all.destroy();
    }
    product_carousel_cat_all = new Swiper("#product_carousel_cat_all", {
      loop: false,
      centeredSlides: false,
      slidesPerView: "auto",
      grabCursor: true,
      scrollbar: {
        el: "#product_carousel_scrollbar",
        hide: false,
        draggable: true,
        dragSize: 120,
      },
      freeMode: {
        enabled: true,
        sticky: false,
        momentumBounce: false,
      },
      observer: true,
      observeParents: true,
      breakpoints: {
        800: {
          scrollbar: {
            dragSize: 200,
          },
        }
      }
    });
  };
  <?php
       // カテゴリー別記事一覧
       if ( $product_category_list && ! is_wp_error( $product_category_list ) && ($category_total > 1) ) {
         foreach ( $product_category_list as $cat ):
           $cat_id = $cat->term_id;
  ?>
  if( $('#product_carousel_cat_<?php echo esc_attr($cat_id); ?>').length ){
    if(product_carousel_cat_<?php echo esc_attr($cat_id); ?> != undefined){
      product_carousel_cat_<?php echo esc_attr($cat_id); ?>.destroy();
    }
    product_carousel_cat_<?php echo esc_attr($cat_id); ?> = new Swiper("#product_carousel_cat_<?php echo esc_attr($cat_id); ?>", {
      loop: false,
      centeredSlides: false,
      slidesPerView: "auto",
      grabCursor: true,
      scrollbar: {
        el: "#product_carousel_scrollbar_cat_<?php echo esc_attr($cat_id); ?>",
        hide: false,
        draggable: true,
        dragSize: 120,
      },
      freeMode: {
        enabled: true,
        sticky: false,
        momentumBounce: false,
      },
      observer: true,
      observeParents: true,
      breakpoints: {
        800: {
          scrollbar: {
            dragSize: 200,
          },
        }
      }
    });
  };
  <?php
         endforeach;
       };
  ?>

  }; // END init_product_carousel();
  init_product_carousel();

  <?php
       // カテゴリーソートボタン
       if ( $product_category_list && ! is_wp_error( $product_category_list ) && ($category_total > 1) ) {
  ?>
  $('.product_category_button a').on('click',function(e) {
    e.preventDefault();
    e.stopPropagation();
    $(this).parent().siblings().removeClass('current');
    $(this).parent().addClass('current');
    var product_category_id = $(this).data('category-id');
    if(product_category_id){
      $('.index_product_list').removeClass('active');
      $('#' + product_category_id).addClass('active');
      init_product_carousel();
    }
  });
  	<?php }; ?>
          
})(jQuery);

<?php }; // トップページ ------------------------
?>

<?php
     // 製品情報アーカイブ ------------------------------
     if(is_post_type_archive('product') || is_tax('product_category') || is_front_page()) {
?>
(function($) {

  if( $('.product_category_button').length ){
    let product_category_button = new Swiper(".product_category_button", {
      loop: false,
      centeredSlides: false,
      slidesPerView: "auto",
      grabCursor: true,
      freeMode: {
        enabled: true,
        sticky: false,
        momentumBounce: false,
      },
    });
  };

})(jQuery);
<?php
     };
     // 製品情報アーカイブとカテゴリーページ
     if(is_post_type_archive('product') || is_tax('product_category')) {
       $ajax_item = 'get_product_items';
?>
(function($) {

  <?php // カテゴリーソートボタン ------------------------ ?>
  $('.product_category_button a').on('click',function(e) {
    e.preventDefault();
    e.stopPropagation();
    $(this).parent().siblings().removeClass('current');
    $(this).parent().addClass('current');
    var product_category_id = $(this).data('category-id');
    if(product_category_id){
      $('.product_list').find('.item').removeClass('animate').removeAttr('style');
      $('.ajax_post_list_wrap').removeClass('active');
      $(product_category_id).addClass('active');
      $(product_category_id).find(".item").each(function(i){
        $(this).delay(300).queue(function(next) {
          $(this).addClass('animate');
          next();
        });
      });
    }
  });

  <?php
       // AJAXを使って記事をロードする ------------------------
       if(is_mobile()){
        $post_num = get_theme_mod('product_mobile_number',6);
      } else {
        $post_num = get_theme_mod('product_pc_number',6);
      }
  ?>
  var offsetPost = '',
      catid = '',
      flag = false;

  $(document).on("click", ".product-more", function() {
    offsetPost = $(this).data('offset-post');
    catid = $(this).data('catid');
    current_button = $(this);
    if (!flag) {
      entry_loading = current_button.closest('.ajax_post_list_wrap').find('.entry-loading');
      product_list = current_button.closest('.ajax_post_list_wrap').find('.product_list');
      current_button.addClass("is-hide");
      entry_loading.addClass("is-show");
      flag = true;
      $.ajax({
        type: "POST",
        url: "<?php echo admin_url( 'admin-ajax.php' ); ?>",
        data: {
          action: '<?php echo esc_attr($ajax_item); ?>',
          offset_post_num: offsetPost,
          post_cat_id: catid
        },
        dataType: 'json'
      }).done(function(data, textStatus, jqXHR) {
        if (data.html) {
          product_list.append(data.html);
          $(".ajax_item",product_list).each(function(i) {
            $(this).css('opacity','0').show();
            $(this).delay(300).queue(function(next) {
              $(this).addClass('animate').fadeIn();
              $(this).removeClass('ajax_item');
              next();
            });
          });
        }
        entry_loading.removeClass("is-show");
        if (data.remain) {
          current_button.removeClass("is-hide");
        }
        offsetPost += <?php echo esc_attr($post_num); ?>;
        current_button.attr('data-offset-post',offsetPost);
        current_button.data('offset-post',offsetPost);
        flag = false;
      }).fail(function(jqXHR, textStatus, errorThrown) {
        entry_loading.removeClass("is-show");

      });
    }
  });

})(jQuery);

<?php }; ?>
</script>
<?php } ?>

親テーマの「footer_script.php」のコードが美しくないので、こちらも美しくコード化できていません。

フッターの最後にスクリプトを配置できるように「footer.php」でget_template_part(‘template-parts/footer_custom_script’);を使って読み込みます。

get_template_part()は名称だけでphpを読み込みます。「.php」は必要ありません。

//省略

<?php wp_footer(); ?>
<?php
     // load script -----------------------------------------------------------
    if(
       $options['show_loading'] && is_front_page() && $options['loading_display_page'] == 'type1' && $options['loading_display_time'] == 'type1' && !isset($_COOKIE['first_visit']) ||
       $options['show_loading'] && is_front_page() && $options['loading_display_page'] == 'type1' && $options['loading_display_time'] == 'type2' ||
       $options['show_loading'] && $options['loading_display_page'] == 'type2' && $options['loading_display_time'] == 'type1' && !isset($_COOKIE['first_visit']) ||
       $options['show_loading'] && $options['loading_display_page'] == 'type2' && $options['loading_display_time'] == 'type2'
    ){
       show_loading_screen();
     } else {
       no_loading_screen();
     };

     // カスタムスクリプト--------------------------------------------
     if($options['footer_script_code']) {
       echo $options['footer_script_code'];
     };
     if(is_single() || is_page()) {
       global $post;
       $footer_custom_script = get_post_meta($post->ID, 'footer_custom_script', true);
       if($footer_custom_script) {
         echo $footer_custom_script;
       };
     };
?>
<?php
//カスタム投稿を制御するjavascript
get_template_part('template-parts/footer_custom_script');
?>

</body>
</html>

これで、カスタム投稿タイプ「製品情報」のカテゴリーボタンが機能するようになりました。

アーカイブ用のphpファイル

カスタム投稿のアーカイブはカテゴリーをサポートするので「archive-product.php」と「taxonomy-product_category.php」が必要です。

カスタム投稿タイプを処理するphpの名称は以下のように決まっています。

  • single-product.php:カスタム投稿タイプ「product」のシングルページを作成するphp
  • archive-product.php:カスタム投稿タイプ「product」のアーカイブページを作成するphp
  • taxonomy-product_category.php:カスタム投稿タイプのカテゴリー「product_category」のアーカイブを作成するphp

決まった名称を付けることでWordPressがphpに制御を渡してくれます。

また、アーカイブはajaxで読み込まれるので「ajax-product-item.php」を作ります。

アーカイブ用のphpファイル
  • archive-product.php
  • taxonomy-product_category.php
  • ajax-product-item.php

それぞれ、親テーマの「archive-news.php」「taxonomy-news_category.php」「ajax-news-item.php」の「news」を「product」に一括置換すれば、基本はできあがります。

「archive-product.php」と「taxonomy-product_category.php」を作る

「archive-product.php」「taxonomy-product_category.php」は以下のようになります。

<?php
     get_header();
     $options = get_design_plus_option();
//カスタマイザーの情報を設置
     $title = get_option('product_headline_txt');
     $sub_title = get_option('product_sub_txt');
     $desc = get_option('product_desc_pc_txt');
     $desc_mobile = get_option('product_desc_mobile_txt');
?>

//省略

<section id="archive_product">

 <?php
//アイキャッチは表示
      $show_image = 'display';

//カスタマイザーの表示数を設置
      if(is_mobile()){
        $post_num = get_theme_mod('product_mobile_number',6);
      } else {
        $post_num = get_theme_mod('product_pc_number',6);
      }
      $args = array( 'post_type' => 'product', 'posts_per_page' => $post_num );
      $post_list = new wp_query($args);
      $all_post_count = $post_list->found_posts;
      if($post_list->have_posts()):
 ?>

//省略

<div class="ajax_post_list_wrap" id="ajax_post_cat_<?php echo esc_attr($cat_id); ?>">
  <div class="product_list ajax_post_list">
   <?php
        while ( $post_list->have_posts() ) : $post_list->the_post();
          if($show_image == 'display'){
            if(has_post_thumbnail()) {
              $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'size2' );
            } elseif($options['no_image']) {
              $image = wp_get_attachment_image_src( $options['no_image'], 'full' );
            } else {
              $image = array();

//アイキャッチの大きさをブログと同様に
              $image[0] = get_bloginfo('template_url') . "/img/no_image2.gif";
              $image[1] = '770';
              $image[2] = '520';
            }
          }
   ?>

//省略

<?php if($all_post_count > $post_num) { ?>

//念のため「entry-more」を「product-more」に変更 ※変更しなくても大丈夫だと思いますが…
  <div class="product-more" data-catid="" data-offset-post="<?php echo esc_attr($post_num); ?>">
   <span class="design_button"><?php _e( 'Load more', 'tcd-genesis' ); ?></span>
  </div>
  <div class="entry-loading"><?php _e( 'LOADING...', 'tcd-genesis' ); ?></div>
  <?php }; ?>
 </div><!-- END .ajax_post_list_wrap -->

//以下省略

その他の変更は以下の3つです。

  1. カスタマイザーの情報設定
  2. ポストタイプの設定
  3. アイキャッチの大きさを変更

まず、以下のコードで、カスタマイザーの情報を設定します。

$title = get_option('product_headline_txt');
$sub_title = get_option('product_sub_txt');
$desc = get_option('product_desc_pc_txt');
$desc_mobile = get_option('product_desc_mobile_txt');

表示数の設定はget_theme_mod()を使用して6を初期設定しています。

if(is_mobile()){
   $post_num = get_theme_mod('product_mobile_number',6);
} else {
   $post_num = get_theme_mod('product_pc_number',6);
}

ポストタイプの設定wp_query($args)$argsに設定します。

アイキャッチの大きさを変更するのは以下の部分です。

$image[0] = get_bloginfo('template_url') . "/img/no_image2.gif";
$image[1] = '770';
$image[2] = '520';

私はロードボタンのクラスを「entry-more」から「product-more」に変更しましたが、変更しなくても問題ありません。

その場合は「footer_script.php」も対応させてください。(191行目を変更)

「ajax-product-item.php」を作る

「ajax-product-item.php」はアーカイブ画面で指定した表示数を超えて存在するデータを読み込みます。

<?php
     $options = get_design_plus_option();

     if(is_mobile()){
        $post_num = get_theme_mod('product_mobile_number',6);
     } else {
        $post_num = get_theme_mod('product_pc_number',6);
     }

     $def_offset = $post_num;
     $offset = isset( $_POST['offset_post_num'] ) ? $_POST['offset_post_num'] : $def_offset;
     $post_cat_id = isset( $_POST['post_cat_id'] ) ? $_POST['post_cat_id'] : '';
     $next_load_num = $post_num;
     $posts_per_page = $next_load_num;

     if($post_cat_id){
       $all_query = new WP_Query( array('post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => -1, 'tax_query' => array( array( 'taxonomy' => 'product_category', 'field' => 'term_id', 'terms' => $post_cat_id ) )) );
       $all_post_count = $all_query->found_posts;
       $args = array( 'post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => $posts_per_page, 'offset' => $offset, 'tax_query' => array( array( 'taxonomy' => 'product_category', 'field' => 'term_id', 'terms' => $post_cat_id ) ) );
     } else {
       $all_query = new WP_Query( array('post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => -1) );
       $all_post_count = $all_query->found_posts;
       $args = array( 'post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => $posts_per_page, 'offset' => $offset );
     }

//以下省略

「ajax-product-item.php」にもカスタマイザーの表示数を設置します。

「ajax-product-item.php」を起動させるためには以下のコードを「functions.php」に記載します。

// AJAXで記事取得 ------------------------------------------------------------------------

// 製品情報
function ajax_get_product_items() {
  if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) return;
  if ( isset( $_POST['offset_post_num'], $_POST['post_cat_id'] ) ) {
    get_template_part('ajax-product-item');
    exit;
  }
}
add_action( 'wp_ajax_get_product_items', 'ajax_get_product_items' );
add_action( 'wp_ajax_nopriv_get_product_items', 'ajax_get_product_items' );

実際にアーカイブページを表示してみましょう。

製品ページを5個登録し、表示数を3にするとアーカイブページは「もっと見る」ボタンが表示されます。

カスタム投稿タイプアーカイブページ

「もっと見る」ボタンをクリックすると…

カスタム投稿タイプアーカイブページ・全表示

全て表示されました。

カスタム投稿タイプ・カテゴリーアーカイブ

カテゴリーアーカイブも問題無く表示されています。

カテゴリーボタンも正常に機能しています。

パンくずリストにカスタム投稿タイプを追加

親テーマの「template-parts」→「breadcrumb.php」にカスタム投稿タイプのルートを追加します。

<?php
     $options = get_design_plus_option();
     
	 $options['product_label'] = get_option('product_label_txt');
     
     global $post, $blog_label;
?>
<div id="bread_crumb" class="inview">
 <ul itemscope itemtype="https://schema.org/BreadcrumbList">
 <?php
     // お知らせアーカイブ -----------------------
     if(is_post_type_archive('news')) {
 ?>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem" class="home"><a itemprop="item" href="<?php echo esc_url(home_url('/')); ?>"><span itemprop="name"><?php _e('Home', 'tcd-genesis'); ?></span></a><meta itemprop="position" content="1"></li>
 <li class="last" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><span itemprop="name"><?php echo esc_html($options['news_label']); ?></span><meta itemprop="position" content="2"></li>
 <?php
     // お知らせカテゴリー -----------------------
     } elseif(is_tax('news_category')) {
       $category_title = single_cat_title('', false);
 ?>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem" class="home"><a itemprop="item" href="<?php echo esc_url(home_url('/')); ?>"><span itemprop="name"><?php _e('Home', 'tcd-genesis'); ?></span></a><meta itemprop="position" content="1"></li>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><a itemprop="item" href="<?php echo esc_url(get_post_type_archive_link('news')); ?>"><span itemprop="name"><?php echo esc_html($options['news_label']); ?></span></a><meta itemprop="position" content="2"></li>
 <li class="last" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><span itemprop="name"><?php echo esc_html($category_title); ?></span><meta itemprop="position" content="3"></li>
 <?php
     // お知らせ詳細 -----------------------
     } elseif(is_singular('news')) {
       $category = wp_get_post_terms( $post->ID, 'news_category' , array( 'orderby' => 'term_order' ));
 ?>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem" class="home"><a itemprop="item" href="<?php echo esc_url(home_url('/')); ?>"><span itemprop="name"><?php _e('Home', 'tcd-genesis'); ?></span></a><meta itemprop="position" content="1"></li>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><a itemprop="item" href="<?php echo esc_url(get_post_type_archive_link('news')); ?>"><span itemprop="name"><?php echo esc_html($options['news_label']); ?></span></a><meta itemprop="position" content="2"></li>
 <?php if ( $category && ! is_wp_error($category) ) { ?>
 <li class="category" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
  <?php
       $count=1;
       foreach ($category as $cat) {
  ?>
  <a itemprop="item" href="<?php echo esc_url(get_category_link($cat->term_id)); ?>"><span itemprop="name"><?php echo esc_html($cat->name); ?></span></a>
  <?php $count++; } ?>
  <meta itemprop="position" content="3">
 </li>
 <?php }; ?>
 <li class="last" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><span itemprop="name"><?php the_title_attribute(); ?></span><meta itemprop="position" content="<?php if ( $category ) { echo '4'; } else { echo '3'; }; ?>"></li>
 <?php
     // 製品情報アーカイブ -----------------------
     } elseif(is_post_type_archive('product')) {
 ?>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem" class="home"><a itemprop="item" href="<?php echo esc_url(home_url('/')); ?>"><span itemprop="name"><?php _e('Home', 'tcd-genesis'); ?></span></a><meta itemprop="position" content="1"></li>
 <li class="last" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><span itemprop="name"><?php echo esc_html($options['product_label']); ?></span><meta itemprop="position" content="2"></li>
 <?php
     // 製品情報カテゴリー -----------------------
     } elseif(is_tax('product_category')) {
       $category_title = single_cat_title('', false);
 ?>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem" class="home"><a itemprop="item" href="<?php echo esc_url(home_url('/')); ?>"><span itemprop="name"><?php _e('Home', 'tcd-genesis'); ?></span></a><meta itemprop="position" content="1"></li>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><a itemprop="item" href="<?php echo esc_url(get_post_type_archive_link('product')); ?>"><span itemprop="name"><?php echo esc_html($options['product_label']); ?></span></a><meta itemprop="position" content="2"></li>
 <li class="last" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><span itemprop="name"><?php echo esc_html($category_title); ?></span><meta itemprop="position" content="3"></li>
 <?php
     // 製品情報詳細 -----------------------
     } elseif(is_singular('product')) {
       $category = wp_get_post_terms( $post->ID, 'product_category' , array( 'orderby' => 'term_order' ));
 ?>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem" class="home"><a itemprop="item" href="<?php echo esc_url(home_url('/')); ?>"><span itemprop="name"><?php _e('Home', 'tcd-genesis'); ?></span></a><meta itemprop="position" content="1"></li>
 <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><a itemprop="item" href="<?php echo esc_url(get_post_type_archive_link('product')); ?>"><span itemprop="name"><?php echo esc_html($options['product_label']); ?></span></a><meta itemprop="position" content="2"></li>
 <?php if ( $category && ! is_wp_error($category) ) { ?>
 <li class="category" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
  <?php
       $count=1;
       foreach ($category as $cat) {
  ?>
  <a itemprop="item" href="<?php echo esc_url(get_category_link($cat->term_id)); ?>"><span itemprop="name"><?php echo esc_html($cat->name); ?></span></a>
  <?php $count++; } ?>
  <meta itemprop="position" content="3">
 </li>
 <?php }; ?>
 <li class="last" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><span itemprop="name"><?php the_title_attribute(); ?></span><meta itemprop="position" content="<?php if ( $category ) { echo '4'; } else { echo '3'; }; ?>"></li>
 <?php
     // サービスアーカイブ -----------------------
     
//以下省略

「お知らせ」と同様のルートを「製品情報」にも追加するだけです。

注意していただきたいのは冒頭の$options[‘product_label’] = get_option(‘product_label_txt’);によってカスタマイザーの情報を設置していることです。

こうすることで、既存のカスタム投稿タイプと同様に処理することができます。

カスタム投稿を追加する場合、パンくずリストの表示に苦労するテーマもありますが、「GENESIS」は比較的簡単でした。

カスタム投稿タイプ記事ページのフロントエンド

カスタム投稿タイプ「製品情報」のシングルページ(記事ページ)は2種類サポートします。

基本フォーマットは固定ページ、サブフォーマットはカスタム投稿タイプ「サービス」のヘッド部分を使用してレイアウトします。

注:製品記事ページはカテゴリー別の設定が必要ですが、このページでは詳細には触れていませんので、ご了承ください。

固定ページタイプ(デフォルトテンプレート)

「single-product.php」を作る

「single-product.php」は「page.php」のファイル名を変更したものです。

<?php
     get_header();
     $options = get_design_plus_option();
     $hide_sidebar = get_post_meta($post->ID, 'hide_sidebar', true) ?  get_post_meta($post->ID, 'hide_sidebar', true) : 'no';
     $hide_breadcrumb = get_post_meta($post->ID, 'hide_breadcrumb', true) ?  get_post_meta($post->ID, 'hide_breadcrumb', true) : 'no';
     $headline = get_post_meta($post->ID, 'header_headline', true) ?  get_post_meta($post->ID, 'header_headline', true) : get_the_title();
     $sub_title = get_post_meta($post->ID, 'header_sub_title', true);
     $catch = get_post_meta($post->ID, 'header_catch', true);
     $desc = get_post_meta($post->ID, 'header_desc', true);
     $desc_mobile = get_post_meta($post->ID, 'header_desc_mobile', true);
     $image = wp_get_attachment_image_src(get_post_meta($post->ID, 'header_image', true), 'full');
?>
<?php if($hide_breadcrumb == 'no'){ get_template_part('template-parts/breadcrumb'); }; ?>


<div id="page_header"<?php if($image){ echo ' class="show_image"'; }; if(!$catch && !$desc && !$image){ echo ' class="large_height"'; }; ?>>
 <div class="design_header inview">
  <div class="title_area no_desc">
   <?php if($headline){ ?>
   <h1 class="large_headline"><span><?php echo wp_kses_post(nl2br($headline)); ?></span></h1>
   <?php }; ?>
   <?php if($sub_title){ ?>
   <p class="sub_title colored"><span><?php echo esc_html($sub_title); ?></span></p>
   <?php }; ?>
  </div>
 </div>
 <?php if($catch || $desc){ ?>
 <div class="desc_area inview slide_up_animation">
  <?php if($catch){ ?>
  <h2 class="catch rich_font"><span><?php echo wp_kses_post(nl2br($catch)); ?></span></h2>
  <?php }; ?>
  <?php if($desc){ ?>
  <div class="desc<?php if($desc_mobile){ echo ' pc'; }; ?>"><?php echo wp_kses_post(nl2br($desc)); ?></div>
  <?php if($desc_mobile){ ?>
  <div class="desc mobile"><?php echo wp_kses_post(nl2br($desc_mobile)); ?></div>
  <?php }; ?>
  <?php }; ?>
 </div>
 <?php }; ?>
 <?php if($image) { ?>
 <div class="image">
  <div class="overlay"></div>
  <img src="<?php echo esc_attr($image[0]); ?>" alt="" width="<?php echo esc_attr($image[1]); ?>" height="<?php echo esc_attr($image[2]); ?>">
 </div>
 <?php }; ?>
</div>

<?php if($hide_sidebar == 'yes'){ ?>

<article id="page_contents">

 <div class="post_content"><?php the_content(); if ( ! post_password_required() ) { custom_wp_link_pages(); } ?></div>

</article><!-- END #page_contents -->

<?php } else { ?>

<div id="main_content">

 <div id="main_col">

  <article id="article">

   <div class="post_content clearfix">
    <?php
         the_content();
         if ( ! post_password_required() ) {
           custom_wp_link_pages();
         }
    ?>
   </div>

 </div><!-- END #main_col -->

 <?php get_sidebar(); ?>

</div><!-- END #main_contents -->

<?php }; ?>

<?php get_footer(); ?>

カテゴリーをサポートするので「page.php」の内容を変更しないといけないのですが、この記事では、カスタム投稿タイプを追加する内容にしぼっていますので、割愛します。

「page.php」はWordPressのメインループ(以下コード)が省いてありますので、取得できないデータがあるかもしれません。

//メインループ
if ( have_posts() ) : while ( have_posts() ) : the_post();
//処理
<?php endwhile; endif; ?>

取得できないデータがある場合、次で紹介するサービスタイプページの「single-type2.php」と同様、メインループは追加した方がよいでしょう。

サービスページタイプ(タイプ2 テンプレート)

「single-type2.php」を作る

サービスページタイプを処理する「single-type2.php」のコードは以下です。

<?php
/*
Template Name:タイプ2 テンプレート
Template Post Type: product
*/
     get_header();
     $options = get_design_plus_option();
     $hide_sidebar = get_post_meta($post->ID, 'hide_sidebar_type2', true) ?  get_post_meta($post->ID, 'hide_sidebar_type2', true) : 'no';
     $hide_breadcrumb = get_post_meta($post->ID, 'hide_breadcrumb_type2', true) ?  get_post_meta($post->ID, 'hide_breadcrumb_type2', true) : 'no';

     if ( have_posts() ) : while ( have_posts() ) : the_post();
       $cat_id = '';
       $category = wp_get_post_terms( $post->ID, 'service_category' , array( 'orderby' => 'term_order' ));
       if ( $category && ! is_wp_error($category) ) {
         foreach ( $category as $cat ) :
           $cat_name = $cat->name;
           $cat_id = $cat->term_id;
           $cat_url = get_term_link($cat_id,'service_category');
           break;
         endforeach;
       };
       $term_meta = get_option( 'taxonomy_' . $cat_id, array() );
       $sub_title = !empty($term_meta['sub_title']) ? $term_meta['sub_title'] : '';
       $single_service_overlay_color = hex2rgb($options['single_service_overlay_color']);
       $single_service_overlay_color = implode(",",$single_service_overlay_color);
?>

<div id="single_service_header" class="inview">

 <h1 class="title single_title entry-title"><span><?php the_title(); ?></span></h1>

 <?php if ( $category && ! is_wp_error($category) && $sub_title) { ?>
 <div class="category">
  <?php if ( $category && ! is_wp_error($category) ) { ?>
  <h2 class="large_headline"><span><?php echo wp_kses_post(nl2br($cat_name)); ?></span></h2>
  <?php }; ?>
  <?php if($sub_title){ ?>
  <p class="sub_title"><span><?php echo wp_kses_post(nl2br($sub_title)); ?></span></p>
  <?php }; ?>
 </div>
 <?php }; ?>

 <?php
      if(has_post_thumbnail()) {
        $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
 ?>
 <img class="image" src="<?php echo esc_attr($image[0]); ?>" width="<?php echo esc_attr($image[1]); ?>" height="<?php echo esc_attr($image[2]); ?>" />
 <?php }; ?>

 <div class="overlay" style="background:rgba(<?php echo esc_attr($single_service_overlay_color); ?>,<?php echo esc_attr($options['single_service_overlay_opacity']); ?>);"></div>

</div>

<?php if($hide_breadcrumb == 'no'){ get_template_part('template-parts/breadcrumb'); }; ?>

<?php if($hide_sidebar == 'yes'){ ?>

<article id="page_contents">

 <div class="post_content"><?php the_content(); if ( ! post_password_required() ) { custom_wp_link_pages(); } ?></div>

</article><!-- END #page_contents -->

<?php } else { ?>

<div id="main_content">

 <div id="main_col">

  <article id="article">

   <div class="post_content clearfix">
    <?php
         the_content();
         if ( ! post_password_required() ) {
           custom_wp_link_pages();
         }
    ?>
   </div>

 </div><!-- END #main_col -->

 <?php get_sidebar(); ?>

</div><!-- END #main_contents -->

<?php }; ?>




<?php endwhile; endif; ?>

<?php get_footer(); ?>

パンくずリストとサイドバーの有無をカスタムフィールドの値で判定しています。

コンテンツの処理は、固定ページと同様ブロックエディタ対応のページなので、シンプルにしてあります。

テンプレートのタイプを選択させる方法

/*
Template Name:タイプ2 テンプレート
Template Post Type: product
*/

先頭にTemplate NameTemplate Post Typeを入れると、管理画面でテンプレートを選択できるようになります。

次にカスタム投稿タイプのデザインを制御するbodyタグとhead内CSSについて説明します。

bodyクラスを追加する

親テーマではbodyタグに様々なクラスを追加してレイアウトを制御しています。

追加したカスタム投稿についても、以下のコードを「functions.php」に追加して、レイアウトを制御します。

制御しているのは4つです。

  1. グローバルナビの種類
  2. パンくずリストの有無
  3. サイドバーの有無
  4. ボディーの幅
// bodyにclassを追加を変更 --------------------------------------------------------------------------------
function remove_body_classes() {
	remove_filter( 'body_class','tcd_body_classes' );
}
add_action('after_setup_theme', 'remove_body_classes');

function tcd_body_classes_child($classes) {
    global $wp_query, $post;
    $options = get_design_plus_option();

    if(is_mobile()){ $classes[] = 'mobile_device'; }

    if( (is_search() && isset($_GET['s']) && empty($_GET['s'])) || (is_search() && !have_posts()) ){ $classes[] = 'search-no-results'; };

    $classes[] = esc_attr($options['megamenu_color_type']);

    if($options['show_header_message'] == 'display') { $classes[] = 'show_header_message'; }

    if(is_singular('post') && $options['single_blog_content_width'] == 'type2') { $classes[] = 'short_content_width'; }
    if(is_singular('news') && $options['single_news_content_width'] == 'type2') { $classes[] = 'short_content_width'; }
    if(is_singular('service') && $options['single_service_content_width'] == 'type2') { $classes[] = 'short_content_width'; }

    if($options['blog_show_date'] == 'hide') { $classes[] = 'hide_blog_date'; }

    if( is_front_page() && $options['index_slider_image']) { $classes[] = 'header_slider_layout_' . esc_attr($options['index_slider_layout']); }

    if(
       $options['show_loading'] && is_front_page() && $options['loading_display_page'] == 'type1' && $options['loading_display_time'] == 'type1' && !isset($_COOKIE['first_visit']) ||
       $options['show_loading'] && is_front_page() && $options['loading_display_page'] == 'type1' && $options['loading_display_time'] == 'type2' ||
       $options['show_loading'] && $options['loading_display_page'] == 'type2' && $options['loading_display_time'] == 'type1' && !isset($_COOKIE['first_visit']) ||
       $options['show_loading'] && $options['loading_display_page'] == 'type2' && $options['loading_display_time'] == 'type2'
    ){
      $classes[] = 'use_loading_screen';
      $classes[] = 'loading_animation_' . esc_attr($options['loading_animation_type']);
    };

    //サービスページタイプはグローバルナビを透過
    if(is_page_template('single-type2.php') || is_singular('service') || (is_front_page() && $options['index_slider_image'] && $options['index_slider_layout'] == 'type3') ) { $classes[] = 'header_type2'; };
    
    //カスタム投稿のbodyクラスを追加
    if( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'hide_sidebar', true) == 'no') ) { $classes[] = 'show_sidebar'; } elseif( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'hide_sidebar', true) != 'no') ) { $classes[] = 'hide_sidebar'; };
    if( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'hide_sidebar_type2', true) == 'no') ) { $classes[] = 'show_sidebar'; } elseif( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'hide_sidebar_type2', true) != 'no') ) { $classes[] = 'hide_sidebar'; };
    
    if( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'hide_breadcrumb', true) == 'yes')) { $classes[] = 'hide_breadcrumb'; };
    if( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'hide_breadcrumb_type2', true) == 'yes')) { $classes[] = 'hide_breadcrumb'; };
    
    if( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'page_width_type2', true) == 'type2') ) { $classes[] = 'short_content_width'; } elseif( is_singular( array( 'solution', 'product' ) ) && (get_post_meta($post->ID, 'page_width_type2', true) != 'type2')) { $classes[] = 'normal_content_width'; };
    if( is_singular( array( 'product' ) ) && (get_post_meta($post->ID, 'page_width_t2_type2', true) == 'type2') ) { $classes[] = 'short_content_width'; } elseif( is_singular( array( 'solution', 'product' ) ) && (get_post_meta($post->ID, 'page_width_t2_type2', true) != 'type2')) { $classes[] = 'normal_content_width'; };
    
    if( is_page() && (get_post_meta($post->ID, 'hide_sidebar', true) == 'no') ) { $classes[] = 'show_sidebar'; } elseif( is_page() && (get_post_meta($post->ID, 'hide_sidebar', true) != 'no') ) { $classes[] = 'hide_sidebar'; };
    if( is_page() && (get_post_meta($post->ID, 'hide_breadcrumb', true) == 'yes') && !is_page_template('page-tcd-lp.php')) { $classes[] = 'hide_breadcrumb'; };
    if( is_page() && (get_post_meta($post->ID, 'page_width_type2', true) == 'type2') ) { $classes[] = 'short_content_width'; } elseif(is_page() && (get_post_meta($post->ID, 'page_width_type2', true) != 'type2')) { $classes[] = 'normal_content_width'; };
    if( is_page_template('page-tcd-lp.php') && (get_post_meta($post->ID, 'hide_header_message', true) == 'yes') ) { $classes[] = 'hide_header_message'; };
    if( is_page_template('page-tcd-lp.php') && (get_post_meta($post->ID, 'hide_page_header_bar', true) == 'yes') ) { $classes[] = 'hide_page_header_bar'; };
    if( is_page_template('page-tcd-lp.php') && (get_post_meta($post->ID, 'hide_page_header', true) == 'yes') ) { $classes[] = 'hide_page_header'; } elseif(is_page_template('page-tcd-lp.php') && (get_post_meta($post->ID, 'hide_page_header', true) != 'yes')) { $classes[] = 'show_page_header'; };
    if( is_page_template('page-tcd-lp.php') && (get_post_meta($post->ID, 'hide_page_header_logo', true) == 'yes') ) { $classes[] = 'hide_logo'; };
    if( is_page_template('page-tcd-lp.php') && (get_post_meta($post->ID, 'page_hide_footer', true) == 'yes') ) { $classes[] = 'hide_footer'; };
    if( is_page_template('page-tcd-lp.php') && (get_post_meta($post->ID, 'page_width', true) == 'small') ) { $classes[] = 'short_content'; };

    if(is_archive()) {
      global $wp_query;
      if($wp_query->max_num_pages == 1) {
        $classes[] = 'no_page_nav';
      }
    }

    if( is_single() && (!comments_open() && !pings_open()) ) { $classes[] = 'no_comment_form'; };

    if ( is_mobile() && ($options['footer_bar_type'] != 'type1') ) { $classes[] = 'show_footer_bar'; };

    return array_unique($classes);
};
add_filter('body_class','tcd_body_classes_child');

注意点は以下の2点です。

  1. 親テーマの同関数(tcd_body_classes)を無効化します。
  2. カスタム投稿のスラッグは複数のカスタム投稿を追加出来るように配列にします。

親テーマのadd_filterは以下のコードで無効化しています。

function remove_body_classes() {
	remove_filter( 'body_class','tcd_body_classes' );
}
add_action('after_setup_theme', 'remove_body_classes');

カスタム投稿タイプのバックエンド

フロントエンドは簡単にイメージできますが、バックエンドはかなり複雑です。

固定ページタイプ

固定ページタイプでは「ヘッダー」の設定をサポートしています。

サービスページタイプ

サービスページタイプは基本的にはカスタム投稿タイプ「サービス」と同様なので、「ヘッダー」設定はありません。

「GENESIS」の固定ページのバックエンドは以下のカスタムフィールドをサポートしています。

固定ページのカスタムフィールド
  • ページの設定
  • 会員コンテンツの誘導
  • SEO
  • カスタムCSS・スクリプト

これらを全て、カスタム投稿タイプでもサポートします。

まず、必要な「functions.php」の処理と親テーマの「functions」フォルダーのphpファイルをみていきます。

ページの設定についてはとても複雑ですので、次の章にまとめます。

「会員登録への誘導コンテンツ」を追加

会員登録への誘導コンテンツのメタボックスは親テーマ「functions」→「password_form.php」で設定されています。

サポートしているのは固定ページと投稿ページなので、カスタム投稿も追加します。

※この機能はカスタム投稿ではあまり使わないかもしれませんので、サポートしなくてもよい機能です。そのため、編集画面の表示を確認したのみになっています。

以下が、修正した「password_form.php」の冒頭です。

<?php

// 固定ページでも「抜粋」を使用可能にする
//add_post_type_support( 'page', 'excerpt' );

// 初期状態で「抜粋」ボックスを編集画面に表示する
function tcd_default_hidden_meta_boxes_child( $hidden ) {

	$key = array_search( 'postexcerpt', $hidden );

	if ( $key ) { 
		unset( $hidden[ $key ] );
	}

	return $hidden;

}
add_filter( 'default_hidden_meta_boxes', 'tcd_default_hidden_meta_boxes_child' );

// メタボックスを追加
function pw_meta_box_child() {

	// 投稿編集画面に「会員登録への誘導文」を選択するためのメタボックスを追加
	add_meta_box(
		'select_pw_meta_box', // ID of meta box
		__( 'Contents to encourage member registration', 'tcd-genesis' ), // label
		'display_select_pw_meta_box_child', // callback function
		array( 'post', 'page', 'product' ), // post type
		'normal', // context
		'low'// priority
	);
}
add_action( 'add_meta_boxes', 'pw_meta_box_child' );

//以下省略

基本的には、カスタム投稿タイプ「product」を「メタボックスを追加」で有効化しているだけです。

親テーマでrequireされたphpの処理を変更する場合は内在する全ての関数名を変更します。

// password_formのフックを変更、カスタム投稿タイプに適用  --------------------------------------------------------------------------------
function remove_parent_password_form() {
	remove_filter( 'default_hidden_meta_boxes', 'tcd_default_hidden_meta_boxes' );
	remove_action( 'add_meta_boxes', 'pw_meta_box' );
	remove_action( 'save_post', 'save_select_pw_meta_box' );
	remove_filter( 'protected_title_format', 'tcd_protected_title_format', 10, 2 );
	remove_filter( 'the_excerpt', 'tcd_the_excerpt' );
	remove_filter( 'the_password_form', 'tcd_password_form' );
}
add_action('after_setup_theme', 'remove_parent_password_form');

function custom_excerpt_add(){
    add_post_type_support( 'page', 'excerpt' );
    add_post_type_support( 'product', 'excerpt' );
}
add_action('after_setup_theme' , 'custom_excerpt_add' );

require get_stylesheet_directory() . '/functions/password_form.php';

「password_form.php」では、なぜか固定ページの抜粋を有効にしています。(「password_form.php」でやらなくてもいいのでは?)

そこで、「functions.php」に。カスタム投稿タイプ「製品用法」の抜粋を有効化する処理も追加しました。

その後、require get_stylesheet_directory() . ‘/functions/password_form.php’;で子テーマのファイルを読み込みます。

「SEO」を追加

SEO設定は「titleタグ」と「meta description」の変更をサポートしています。

親テーマ「functions」→「seo.php」で設定されています。

全てのカスタム投稿は同じロジックで処理されるので、「seo.php」を変更してカスタム投稿タイプ「product」のカスタマイザー情報を設置します。

TCDテーマオプションで設定された項目にカスタマイザー情報を逐次追加します。

以下が「seo.php」の冒頭です。

function seo_meta_box_child() {
  $options = get_design_plus_option();
  
  $options['product_archive_meta_title'] = get_option('product_title_txt');
  $options['product_archive_meta_description'] = get_option('product_desc_txt');
  $options['product_label'] = get_option('product_label_txt');

  $post_types = array ('post', 'page', 'news', 'service', 'product');
  add_meta_box(
    'show_seo_meta_box_child',//ID of meta box
    __('SEO', 'tcd-genesis'),//label
    'show_seo_meta_box_child',//callback function
    $post_types,// post type
    'normal',// context
    'low'// priority
  );
}
add_action('add_meta_boxes', 'seo_meta_box_child', 998);

//以下省略

$options = get_design_plus_option();で取得されたTCDテーマオプション情報にはカスタム投稿タイプ「product」の情報がありません。

そこで、マスタマイザーで取得した情報を、他のカスタム投稿の配列名に合わせて設定します。

全ての$options = get_design_plus_option();の次に以下のステートメントに追加します。

$options['product_archive_meta_title'] = get_option('product_title_txt');
$options['product_archive_meta_description'] = get_option('product_desc_txt');
$options['product_label'] = get_option('product_label_txt');

処理するポストタイプに「product」を追加します。

$post_types = array ('post', 'page', 'news', 'service', 'product');

例によって全ての関数名を変更します。

以下を「functions.php」に設置し、変更した子テーマの「seo.php」を読み込みます。

// seo.phpのフックを変更、カスタム投稿タイプに適用  --------------------------------------------------------------------------------
function remove_parent_seo_title() {
	remove_action('add_meta_boxes', 'seo_meta_box', 998);
	remove_action('save_post', 'save_seo_meta_box');
	remove_filter( 'pre_get_document_title', 'seo_title', 10, 2 );
}
add_action('after_setup_theme', 'remove_parent_seo_title');

require get_stylesheet_directory() . '/functions/seo.php';

SEOディスクリプションの設定は「header.php」で行います。

<?php $options = get_design_plus_option(); ?>
<!DOCTYPE html>
<html class="pc" <?php language_attributes(); ?>>
<?php if($options['use_ogp']) { ?>
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<?php } else { ?>
<head>
<?php }; ?>
<meta charset="<?php bloginfo('charset'); ?>">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width">
<meta name="description" content="<?php seo_description_child(); ?>">
<?php if(is_attachment() && (get_option( 'blog_public' ) != 0)) { ?>
<meta name='robots' content='noindex, nofollow' />
<?php }; ?>
<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>">
<?php wp_head(); ?>
</head>

//以下省略

<meta name=”description” content=の箇所で「seo.php」で変更した関数名を使います。

OGPについて

OGP設定は親テーマ「functions」→「ogp.php」で設定されています。

これについては「functions.php」に以下を追加するだけで対応できます。

// ogp.phpのフックを変更、カスタム投稿タイプに適用 -----------------------------------------------------------------------
function remove_parent_ogp() {
 // 親テーマでフックしているアクションを削除
 remove_action( 'wp_head', 'ogp', 1 );
}
add_action( 'init', 'remove_parent_ogp', 20 );

function ogp_child() {
	global $post;
  $options = get_design_plus_option();

  $og_type = (!is_front_page() && is_singular()) ? 'article' : 'website';
  $og_url = ( ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  $og_title = is_singular() ? strip_tags( wp_get_document_title() ) : seo_title_child('');
  $og_description = get_seo_description_child();
  $twitter_card_size = ( $options['twitter_cards_size'] ) ? $options['twitter_cards_size'] : 'summary';
?>
<meta property="og:type" content="<?php echo $og_type; ?>">
<meta property="og:url" content="<?php echo esc_url( $og_url ); ?>">
<meta property="og:title" content="<?php echo $og_title; ?>">
<meta property="og:description" content="<?php echo $og_description; ?>">
<meta property="og:site_name" content="<?php echo get_bloginfo( 'name' ); ?>">
<meta property="og:image" content="<?php og_image(0); ?>">
<meta property="og:image:secure_url" content="<?php og_image(0); ?>"> 
<meta property="og:image:width" content="<?php og_image(1); ?>"> 
<meta property="og:image:height" content="<?php og_image(2); ?>">
<?php /*if ( $options['fb:app_id'] ) { ?>
<meta property="fb:admins" content="<?php echo esc_attr( $options['fb_admin_id'] ); ?>">
<?php } */ ?>
<?php if ( $options['fb_app_id'] ) { ?>
<meta property="fb:app_id" content="<?php echo esc_attr( $options['fb_app_id'] ); ?>">
<?php } ?>
<?php if ( $options['use_twitter_card'] ) { ?>
<meta name="twitter:card" content="<?php echo $twitter_card_size; ?>">
<?php if ( $options['twitter_account_name'] ) { ?>
<meta name="twitter:site" content="@<?php echo esc_attr( $options['twitter_account_name'] ); ?>">
<meta name="twitter:creator" content="@<?php echo esc_attr( $options['twitter_account_name'] ); ?>">
<?php } ?>
<meta name="twitter:title" content="<?php echo $og_title; ?>">
<meta property="twitter:description" content="<?php echo $og_description; ?>">
<?php if ( is_singular() ) { ?>
<meta name="twitter:image:src" content="<?php twitter_image(); ?>">
<?php } }
}
add_action('wp_head','ogp_child',3);

$og_description = get_seo_description_child();で「header.php」と同様に、「seo.php」で変更した関数名を使います。

「カスタムCSS・スクリプト」を追加

「カスタムCSS・スクリプト」は親テーマ「functions」→「custom_script.php」で設定されています。

全ての関数名を変更し、ポストタイプに「product」を指定するだけで、子テーマ用の「custom_script.php」ができあがります。

<?php

function custom_script_meta_box_child() {
  $options = get_design_plus_option();
  $post_types = array ('product');
  add_meta_box(
    'custom_script',//ID of meta box
    __('Custom CSS and script for this page', 'tcd-genesis'),//label
    'show_custom_script_meta_box',//callback function
    $post_types,// post type
    'normal',// context
    'low'// priority
  );
}
add_action('add_meta_boxes', 'custom_script_meta_box_child', 999);

function show_custom_script_meta_box_child() {
  global $post;

  $custom_script = get_post_meta($post->ID, 'custom_script', true);
  $footer_custom_script = get_post_meta($post->ID, 'footer_custom_script', true);
  $custom_css = get_post_meta($post->ID, 'custom_css', true);

  echo '<input type="hidden" name="custom_script_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';

//以下省略

「functions.php」でrequireします。

// 編集画面カスタムCSS・スクリプト --------------------------------------------------------------------------------
require get_stylesheet_directory() . '/functions/custom_script.php';

カスタム投稿タイプ「ページの設定」の制御

固定ページタイプのページ設定カスタムフィールド

固定ページタイプのページ設定(サイドバーあり)

サードバーを「表示しない」にするとギャラリーが設定できるようになります。

固定ページタイプのページ設定(サイドバーなし)

サードバーを「表示しない」にすると「コンテンツの横幅」の設定項目が消えていることにも注意してください。

これらの制御は「admin」→「js」→「my_script.js」で行われています。

サービスページタイプのテンプレートに変更する場合は、ブロックエディタの右サイドバー→テンプレートの「デフォルトテンプレート」をクリック→「タイプ2テンプレート」を選択します。

固定ページタイプ」のテンプレートが「デフォルトテンプレート」
「サービスページタイプ」のテンプレートが「タイプ2 テンプレート」

サービスページタイプのページ設定カスタムフィールド

サービスページタイプのページ設定(サイドバーあり)

サービスタイプには「ヘッダー」設定はありません。

固定ページタイプと同様、サードバーを「表示しない」にするとギャラリーが設定できるようになります。

サービスページタイプのページ設定(サイドバーなし)

以上のカスタムフィールド制御は全て管理画面用のJavaScriptで行います。

カスタム投稿タイプの編集画面を制御するJavaScript

親テーマでは「admin」→「js」→「my_script.js」に制御スクリプトがあります。

カスタム投稿タイプ「製品情報」の管理画面用のJavaScriptは、同一ロジックで、CSSセレクターがかぶらないようにします。(固定ページの編集画面に、スクリプトが影響しないようにするため)

ファイル名称を「custom_script.js」として作成します。

jQuery(document).ready(function($) {

  // 固定ページテンプレートで表示メタボックス切替
  function type2_custom_template() {
    $('.normal_template_option_custom').hide();
    $('.tp2_template_option_custom').show();
    /*$('#gallery_content_short_code_custom').removeClass('deactive');
    $('#page_width_type2_option_custom').hide();*/
    if ($('#hide_sidebar_yes_type2').prop("checked")) {
      $('#gallery_content_short_code_custom').removeClass('deactive');
    } else {
      $('#gallery_content_short_code_custom').addClass('deactive');
    }
    if ($('#hide_sidebar_no_type2').prop("checked")) {
      $('#page_width_type2_option_type2').show();
    }
    if ($('#hide_sidebar_yes_type2').prop("checked")) {
      $('#page_width_type2_option_type2').hide();
    }
  }
  function default_custom_template() {  
    $('.normal_template_option_custom').show();
    $('.tp2_template_option_custom').hide();
    if ($('#hide_sidebar_yes_custom').prop("checked")) {
      $('#gallery_content_short_code_custom').removeClass('deactive');
    } else {
      $('#gallery_content_short_code_custom').addClass('deactive');
    }
    if ($('#hide_sidebar_no_custom').prop("checked")) {
      $('#page_width_type2_option_custom').show();
    }
    if ($('#hide_sidebar_yes_custom').prop("checked")) {
      $('#page_width_type2_option_custom').hide();
    }
  }
  $('select#hidden_page_template_custom').each(function(){
    if ( $(this).val() == 'single-type2.php' ) {
		type2_custom_template();
    } else {
		default_custom_template();
	}
  });
  $(document).on('change', 'select#page_template, .editor-page-attributes__template select' , function(){
	if ( $(this).val() == 'single-type2.php' ) {
		type2_custom_template();
    } else {
		default_custom_template();
	}
  }).trigger('change');

  // ブロックエディタ用
  if(wp.data !== undefined ){
	  
    const { select, subscribe } = wp.data;
    class PageTemplateSwitcher_child {
      constructor() {
        this.template = null;
      }
      init() {
        subscribe( () => {
          const newTemplate = select( 'core/editor' ).getEditedPostAttribute( 'template' );
          if (newTemplate !== undefined && this.template === null) {
            this.template = newTemplate;
          }
          if ( newTemplate !== undefined && newTemplate !== this.template ) {
            this.template = newTemplate;
            this.changeTemplate_child();
          }
        });
      }
      changeTemplate_child() {
        if ( this.template == 'single-type2.php' ) {
            type2_custom_template();
        } else {
            default_custom_template();
		}
      }
    }
    new PageTemplateSwitcher_child().init();
  }
  
  
  // 固定ページのギャラリー用ショートコード
  $(document).on('click', '#hide_sidebar_no_type2', function(event){
    if ($(this).prop("checked")) {
      $('#gallery_content_short_code_custom').addClass('deactive');
      $('#page_width_type2_option_type2').show();
    };
  });
  $(document).on('click', '#hide_sidebar_yes_type2', function(event){
    if ($(this).prop("checked")) {
      $('#gallery_content_short_code_custom').removeClass('deactive');
      $('#page_width_type2_option_type2').hide();
    };
  });
  
  $(document).on('click', '#hide_sidebar_no_custom', function(event){
    if ($(this).prop("checked")) {
      $('#gallery_content_short_code_custom').addClass('deactive');
      $('#page_width_type2_option_custom').show();
    };
  });
  $(document).on('click', '#hide_sidebar_yes_custom', function(event){
    if ($(this).prop("checked")) {
      $('#gallery_content_short_code_custom').removeClass('deactive');
      $('#page_width_type2_option_custom').hide();
    };
  });

});

もとの「my_script.js」のスクリプトは以下です。

 // 固定ページテンプレートで表示メタボックス切替
  function show_lp_meta_box() {
    $('.normal_template_option').hide();
    $('.lp_template_option').show();
    $('#gallery_content_short_code').removeClass('deactive');
    $('#page_width_type2_option').hide();
  }
  function normal_template() {
    $('.normal_template_option').show();
    $('.lp_template_option').hide();
    if ($('#hide_sidebar_yes').prop("checked")) {
      $('#gallery_content_short_code').removeClass('deactive');
    } else {
      $('#gallery_content_short_code').addClass('deactive');
    }
    if ($('#hide_sidebar_no').prop("checked")) {
      $('#page_width_type2_option').show();
    }
    if ($('#hide_sidebar_yes').prop("checked")) {
      $('#page_width_type2_option').hide();
    }
  }
  $('select#hidden_page_template').each(function(){
    if ( $(this).val() == 'page-tcd-lp.php' ) {
      show_lp_meta_box();
    } else {
      normal_template();
    }
  });
  $(document).on('change', 'select#page_template, .editor-page-attributes__template select', function(){
    if ( $(this).val() == 'page-tcd-lp.php' ) {
      show_lp_meta_box();
    } else {
      normal_template();
    }
  }).trigger('change');

  // ブロックエディタ用
  if(wp.data !== undefined ){
    const { select, subscribe } = wp.data;
    class PageTemplateSwitcher {
      constructor() {
        this.template = null;
      }
      init() {
        subscribe( () => {
          const newTemplate = select( 'core/editor' ).getEditedPostAttribute( 'template' );
          if (newTemplate !== undefined && this.template === null) {
            this.template = newTemplate;
          }
          if ( newTemplate !== undefined && newTemplate !== this.template ) {
            this.template = newTemplate;
            this.changeTemplate();
          }
        });
      }
      changeTemplate() {
        if ( this.template == 'page-tcd-lp.php' ) {
          show_lp_meta_box();
        } else {
          normal_template();
        }
      }
    }
    new PageTemplateSwitcher().init();
  }


  // 固定ページのギャラリー用ショートコード
  $(document).on('click', '#hide_sidebar_no', function(event){
    if ($(this).prop("checked")) {
      $('#gallery_content_short_code').addClass('deactive');
      $('#page_width_type2_option').show();
    };
  });
  $(document).on('click', '#hide_sidebar_yes', function(event){
    if ($(this).prop("checked")) {
      $('#gallery_content_short_code').removeClass('deactive');
      $('#page_width_type2_option').hide();
    };
  });

このスクリプトは固定ページのテンプレート切り替えを制御しています。

比較するとCSSセレクターを変更していることが分かっていただけるでしょう。

「custom_script.js」は「functions.php」で読み込みます。

// 管理画面用スクリプト --------------------------------------------------------------------------
function admin_scripts_child() {
	//wp_deregister_script( 'my_script' );
  wp_enqueue_script('custom_child_script', get_stylesheet_directory_uri().'/admin/js/custom_script.js', '', '1.1.7', true);
}
add_action('admin_print_scripts', 'admin_scripts_child',100);

add_action(‘admin_print_scripts’, ‘admin_scripts_child’,100);の「100」はフックの順位をテスト段階で遅くしたためです。無くても大丈夫です。

add_action(‘admin_print_scripts’, ‘admin_scripts_child’,100); のように番号を設定するとフックの順位を指定できます。

カスタム投稿タイプ編集画面の「ページ設定」を作成する

親テーマの「functions」→「page_cf.php」を元にカスタム投稿タイプ用のカスタムフィールドを作成します。

「custom_cf.php」という名称にしました。

このファイルは親テーマとロジックは同じですが、CSSセレクターを変更したため、大きな変更を加えています。そのため、全コードを掲載しておきます。

<?php

/* フォーム用 画像フィールド出力 */
function mlcf_media_form_child($cf_key, $label) {
	global $post;
	if (empty($cf_key)) return false;
	if (empty($label)) $label = $cf_key;

	$media_id = get_post_meta($post->ID, $cf_key, true);
?>
 <div class="image_box cf">
  <div class="cf cf_media_field hide-if-no-js <?php echo esc_attr($cf_key); ?>">
    <input type="hidden" class="cf_media_id" name="<?php echo esc_attr($cf_key); ?>" id="<?php echo esc_attr($cf_key); ?>" value="<?php echo esc_attr($media_id); ?>" />
    <div class="preview_field"><?php if ($media_id) the_mlcf_image_child($post->ID, $cf_key); ?></div>
    <div class="buttton_area">
     <input type="button" class="cfmf-select-img button" value="<?php _e('Select Image', 'tcd-genesis'); ?>" />
     <input type="button" class="cfmf-delete-img button<?php if (!$media_id) echo ' hidden'; ?>" value="<?php _e('Remove Image', 'tcd-genesis'); ?>" />
    </div>
  </div>
 </div>
<?php
}




/* 画像フィールドで選択された画像をimgタグで出力 */
function the_mlcf_image_child($post_id, $cf_key, $image_size = 'medium') {
	echo get_mlcf_image_child($post_id, $cf_key, $image_size);
}

/* 画像フィールドで選択された画像をimgタグで返す */
function get_mlcf_image_child($post_id, $cf_key, $image_size = 'medium') {
	global $post;
	if (empty($cf_key)) return false;
	if (empty($post_id)) $post_id = $post->ID;

	$media_id = get_post_meta($post_id, $cf_key, true);
	if ($media_id) {
		return wp_get_attachment_image($media_id, $image_size, $image_size);
	}

	return false;
}

/* 画像フィールドで選択された画像urlを返す */
function get_mlcf_image_url_child($post_id, $cf_key, $image_size = 'medium') {
	global $post;
	if (empty($cf_key)) return false;
	if (empty($post_id)) $post_id = $post->ID;

	$media_id = get_post_meta($post_id, $cf_key, true);
	if ($media_id) {
		$img = wp_get_attachment_image_src($media_id, $image_size);
		if (!empty($img[0])) {
			return $img[0];
		}
	}

	return false;
}

/* 画像フィールドで選択されたメディアのURLを出力 */
function the_mlcf_media_url_child($post_id, $cf_key) {
	echo get_mlcf_media_url_child($post_id, $cf_key);
}

/* 画像フィールドで選択されたメディアのURLを返す */
function get_mlcf_media_url_child($post_id, $cf_key) {
	global $post;
	if (empty($cf_key)) return false;
	if (empty($post_id)) $post_id = $post->ID;

	$media_id = get_post_meta($post_id, $cf_key, true);
	if ($media_id) {
		return wp_get_attachment_url($media_id);
	}

	return false;
}


// ヘッダーの設定 -------------------------------------------------------

function page_header_meta_box_child() {
  $post_types = array ('solution', 'product');
  add_meta_box(
    'tcd_meta_box1',//ID of meta box
    __('Page setting', 'tcd-genesis'),//label
    'show_page_header_meta_box_child',//callback function
    $post_types,// post type
    'normal',// context
    'high'// priority
  );
}
add_action('add_meta_boxes', 'page_header_meta_box_child');

function show_page_header_meta_box_child() {

  global $post, $font_type_options, $content_direction_options;

  $header_headline = get_post_meta($post->ID, 'header_headline', true);
  $header_sub_title = get_post_meta($post->ID, 'header_sub_title', true);
  $header_catch = get_post_meta($post->ID, 'header_catch', true);
  $header_desc = get_post_meta($post->ID, 'header_desc', true);
  $header_desc_mobile = get_post_meta($post->ID, 'header_desc_mobile', true);
  $header_overlay_color = get_post_meta($post->ID, 'header_overlay_color', true) ?  get_post_meta($post->ID, 'header_overlay_color', true) : '#000000';
  $header_overlay_color_opacity = get_post_meta($post->ID, 'header_overlay_color_opacity', true) ?  get_post_meta($post->ID, 'header_overlay_color_opacity', true) : '0.3';
  if($header_overlay_color_opacity == 'zero'){
    $header_overlay_color_opacity = '0';
  }

  // 表示設定
  $hide_page_header = get_post_meta($post->ID, 'hide_page_header', true) ?  get_post_meta($post->ID, 'hide_page_header', true) : 'no';
  $page_hide_footer = get_post_meta($post->ID, 'page_hide_footer', true) ?  get_post_meta($post->ID, 'page_hide_footer', true) : 'no';
  $hide_sidebar = get_post_meta($post->ID, 'hide_sidebar', true) ?  get_post_meta($post->ID, 'hide_sidebar', true) : 'no';
  $hide_sidebar_type2 = get_post_meta($post->ID, 'hide_sidebar_type2', true) ?  get_post_meta($post->ID, 'hide_sidebar_type2', true) : 'no';
  $hide_breadcrumb = get_post_meta($post->ID, 'hide_breadcrumb', true) ?  get_post_meta($post->ID, 'hide_breadcrumb', true) : 'no';
  $hide_breadcrumb_type2 = get_post_meta($post->ID, 'hide_breadcrumb_type2', true) ?  get_post_meta($post->ID, 'hide_breadcrumb_type2', true) : 'no';
  $hide_page_header_logo = get_post_meta($post->ID, 'hide_page_header_logo', true) ?  get_post_meta($post->ID, 'hide_page_header_logo', true) : 'no';

  $hide_page_header_bar = get_post_meta($post->ID, 'hide_page_header_bar', true);
  if(empty($hide_page_header_bar)){
    $hide_page_header_bar = 'yes';
  }

  $hide_header_message = get_post_meta($post->ID, 'hide_header_message', true);
  if(empty($hide_header_message)){
    $hide_header_message = 'yes';
  }

  $page_width = get_post_meta($post->ID, 'page_width', true);
  if(empty($page_width)){
    $page_width = 'normal';
  }
  $page_width_type2 = get_post_meta($post->ID, 'page_width_type2', true);
  if(empty($page_width_type2)){
    $page_width_type2 = 'type1';
  }
  $page_width_t2_type2 = get_post_meta($post->ID, 'page_width_t2_type2', true);
  if(empty($page_width_t2_type2)){
    $page_width_t2_type2 = 'type1';
  }
  


  // ギャラリー
  $gallery_catch = get_post_meta($post->ID, 'gallery_catch', true);
  $gallery_desc = get_post_meta($post->ID, 'gallery_desc', true);
  $gallery_desc_mobile = get_post_meta($post->ID, 'gallery_desc_mobile', true);
  $gallery_image = get_post_meta($post->ID, 'gallery_image', true);

  // FAQ
  $faq_list = get_post_meta($post->ID, 'faq_list', true);


  echo '<input type="hidden" name="page_header_custom_fields_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';

  //入力欄 ***************************************************************************************************************************************************************************************
?>

<?php
     // WP5.0対策として隠しフィールドを用意 選択されているページテンプレートによってLPページ用入力欄を表示・非表示する
     if ( count( get_page_templates( $post ) ) > 0 && get_option( 'page_for_posts' ) != $post->ID ) :
       $template = ! empty( $post->page_template ) ? $post->page_template : false;
?>
<select name="hidden_page_template_custom" id="hidden_page_template_custom" style="display:none;">
 <option value="default">Default Template</option>
 <?php page_template_dropdown( $template, 'solution' ); ?>
</select>
<?php endif; ?>

<div class="tcd_custom_field_wrap">

  <?php // 基本設定 --------------------------------------------------- ?>
  <div class="theme_option_field cf theme_option_field_ac" id="basic_page_setting">
   <h3 class="theme_option_headline"><?php _e( 'Display setting', 'tcd-genesis' ); ?></h3>
   <div class="theme_option_field_ac_content">

    <div class="cb_image normal_template_option_custom">
     <img src="<?php bloginfo('template_url'); ?>/admin/img/page_base_image.jpg" width="" height="" />
    </div>

    <div class="cb_image tp2_template_option_custom">
     <img src="<?php echo esc_url(get_stylesheet_directory_uri()); ?>/admin/img/type2_image.jpg" alt="" title="" />
    </div>

    <ul class="option_list">
     <li class="tp2_template_option_custom cf" style="border:none;">
      <span class="label"><span class="num tp2_template_option_custom">1</span><?php _e('Breadcrumb link', 'tcd-genesis');  ?></span>
      <div class="standard_radio_button">
       <input type="radio" id="hide_breadcrumb_no_type2" name="hide_breadcrumb_type2" value="no"<?php checked( $hide_breadcrumb_type2, 'no' ); ?>>
       <label for="hide_breadcrumb_no_type2"><?php _e('Display', 'tcd-genesis');  ?></label>
       <input type="radio" id="hide_breadcrumb_yes_type2" name="hide_breadcrumb_type2" value="yes"<?php checked( $hide_breadcrumb_type2, 'yes' ); ?>>
       <label for="hide_breadcrumb_yes_type2"><?php _e('Hide', 'tcd-genesis');  ?></label>
      </div>
     </li>
     <li class="tp2_template_option_custom cf" id="page_width_type2_option_type2">
      <span class="label"><span class="num tp2_template_option_custom">2</span><?php _e('Content width', 'tcd-genesis');  ?></span>
      <div class="standard_radio_button">
       <input type="radio" id="page_width_compact2_t2_type2" name="page_width_t2_type2" value="type2"<?php checked( $page_width_t2_type2, 'type2' ); ?>>
       <label for="page_width_compact2_t2_type2"><?php _e('Compact', 'tcd-genesis');  ?></label>
       <input type="radio" id="page_width_normal2_t2_type2" name="page_width_t2_type2" value="type1"<?php checked( $page_width_t2_type2, 'type1' ); ?>>
       <label for="page_width_normal2_t2_type2"><?php _e('Normal', 'tcd-genesis');  ?></label>
      </div>
     </li>
     <li class="tp2_template_option_custom cf" id="hide_page_header_logo_option">
      <span class="label"><span class="num tp2_template_option_custom">3</span><?php _e('Sidebar', 'tcd-genesis');  ?></span>
      <div class="standard_radio_button">
       <input type="radio" id="hide_sidebar_no_type2" name="hide_sidebar_type2" value="no"<?php checked( $hide_sidebar_type2, 'no' ); ?>>
       <label for="hide_sidebar_no_type2"><?php _e('Display', 'tcd-genesis');  ?></label>
       <input type="radio" id="hide_sidebar_yes_type2" name="hide_sidebar_type2" value="yes"<?php checked( $hide_sidebar_type2, 'yes' ); ?>>
       <label for="hide_sidebar_yes_type2"><?php _e('Hide', 'tcd-genesis');  ?></label>
      </div>
     </li>
     <li class="normal_template_option_custom cf" style="border:none;">
      <span class="label"><span class="num normal_template_option_custom">1</span><?php _e('Breadcrumb link', 'tcd-genesis');  ?></span>
      <div class="standard_radio_button">
       <input type="radio" id="hide_breadcrumb_no" name="hide_breadcrumb" value="no"<?php checked( $hide_breadcrumb, 'no' ); ?>>
       <label for="hide_breadcrumb_no"><?php _e('Display', 'tcd-genesis');  ?></label>
       <input type="radio" id="hide_breadcrumb_yes" name="hide_breadcrumb" value="yes"<?php checked( $hide_breadcrumb, 'yes' ); ?>>
       <label for="hide_breadcrumb_yes"><?php _e('Hide', 'tcd-genesis');  ?></label>
      </div>
     </li>
     <li class="normal_template_option_custom cf" id="page_width_type2_option_custom">
      <span class="label"><span class="num normal_template_option_custom">2</span><?php _e('Content width', 'tcd-genesis');  ?></span>
      <div class="standard_radio_button">
       <input type="radio" id="page_width_compact2" name="page_width_type2" value="type2"<?php checked( $page_width_type2, 'type2' ); ?>>
       <label for="page_width_compact2"><?php _e('Compact', 'tcd-genesis');  ?></label>
       <input type="radio" id="page_width_normal2" name="page_width_type2" value="type1"<?php checked( $page_width_type2, 'type1' ); ?>>
       <label for="page_width_normal2"><?php _e('Normal', 'tcd-genesis');  ?></label>
      </div>
     </li>
     <li class="normal_template_option_custom cf">
      <span class="label"><span class="num normal_template_option_custom">3</span><?php _e('Sidebar', 'tcd-genesis');  ?></span>
      <div class="standard_radio_button">
       <input type="radio" id="hide_sidebar_no_custom" name="hide_sidebar" value="no"<?php checked( $hide_sidebar, 'no' ); ?>>
       <label for="hide_sidebar_no_custom"><?php _e('Display', 'tcd-genesis');  ?></label>
       <input type="radio" id="hide_sidebar_yes_custom" name="hide_sidebar" value="yes"<?php checked( $hide_sidebar, 'yes' ); ?>>
       <label for="hide_sidebar_yes_custom"><?php _e('Hide', 'tcd-genesis');  ?></label>
      </div>
     </li>
    </ul>

    <ul class="button_list cf">
     <li><a class="close_ac_content button-ml" href="#"><?php echo __( 'Close', 'tcd-genesis' ); ?></a></li>
    </ul>
   </div><!-- END .theme_option_field_ac_content -->
  </div><!-- END .theme_option_field -->


  <?php // ページヘッダーの設定 --------------------------------------------------- ?>
  <div class="normal_template_option_custom theme_option_field cf theme_option_field_ac" id="page_header_setting_area">
   <h3 class="theme_option_headline"><?php _e( 'Header', 'tcd-genesis' ); ?></h3>
   <div class="theme_option_field_ac_content">

    <div class="normal_template_option_custom">

     <div class="cb_image">
      <img src="<?php bloginfo('template_url'); ?>/admin/img/page_header_image.jpg" width="" height="" />
     </div>

     <h4 class="theme_option_headline2"><?php _e('Basic settings', 'tcd-genesis');  ?></h4>
     <div class="theme_option_message2">
      <p><?php _e('Page title will be displayed when headline option is blank.', 'tcd-genesis'); ?><br>
     </div>
     <ul class="option_list">
      <li class="cf"><span class="label"><span class="num">1</span><?php _e('Headline', 'tcd-genesis'); ?></span><input class="full_width" type="text" name="header_headline" value="<?php echo esc_attr($header_headline); ?>" /></li>
      <li class="cf"><span class="label"><span class="num">2</span><?php _e('Subheading', 'tcd-genesis'); ?></span><input class="full_width" type="text" name="header_sub_title" value="<?php echo esc_attr($header_sub_title); ?>" /></li>
      <li class="cf"><span class="label"><span class="num">3</span><?php _e('Catchphrase', 'tcd-genesis'); ?></span><textarea class="full_width" cols="50" rows="2" name="header_catch"><?php echo esc_textarea(  $header_catch ); ?></textarea></li>
      <li class="cf"><span class="label"><span class="num">4</span><?php _e('Description', 'tcd-genesis'); ?></span><textarea class="full_width" cols="50" rows="3" name="header_desc"><?php echo esc_textarea(  $header_desc ); ?></textarea></li>
      <li class="cf"><span class="label"><span class="num">4</span><?php _e('Description (mobile)', 'tcd-genesis'); ?></span><textarea placeholder="<?php _e( 'Please indicate if you would like to display a short text for mobile sizes.', 'tcd-genesis' ); ?>" class="full_width" cols="50" rows="3" name="header_desc_mobile"><?php echo esc_textarea(  $header_desc_mobile ); ?></textarea></li>
      <li class="cf">
       <span class="label">
        <span class="num">5</span>
        <?php _e('Image', 'tcd-genesis'); ?>
        <span class="recommend_desc"><?php printf(__('Recommend image size. Width:%1$spx, Height:%2$spx.', 'tcd-genesis'), '1450', '600'); ?></span>
       </span>
       <?php mlcf_media_form_child('header_image', __('Image', 'tcd-genesis')); ?>
      </li>
      <li class="cf"><span class="label"><span class="num">5</span><?php _e('Overlay color of image', 'tcd-genesis'); ?></span><input type="text" name="header_overlay_color" value="<?php echo esc_attr( $header_overlay_color ); ?>" data-default-color="#000000" class="c-color-picker"></li>
      <li class="cf">
       <span class="label"><span class="num">5</span><?php _e('Transparency of overlay', 'tcd-genesis'); ?></span><input class="hankaku" style="width:70px;" type="number" max="1" min="0" step="0.1" name="header_overlay_color_opacity" value="<?php echo esc_attr( $header_overlay_color_opacity ); ?>" />
       <div class="theme_option_message2" style="clear:both; margin:7px 0 0 0;">
        <p><?php _e('Please specify the number of 0 from 0.9. Overlay color will be more transparent as the number is small.', 'tcd-genesis');  ?><br>
        <?php _e('Please enter 0 if you don\'t want to use overlay.', 'tcd-genesis');  ?></p>
       </div>
      </li>
     </ul>

    </div><!-- END #normal_header -->

    <div class="tp2_template_option_custom">

     <div class="cb_image">
      <img src="<?php bloginfo('template_url'); ?>/admin/img/lp_header_image.jpg" width="" height="" />
     </div>

     <h4 class="theme_option_headline2"><?php _e('Basic settings', 'tcd-genesis');  ?></h4>
     <ul class="option_list">
      <li class="cf"><span class="label"><span class="num">1</span><?php _e('Catchphrase', 'tcd-genesis'); ?></span><textarea class="full_width" cols="50" rows="2" name="lp_catch"><?php echo esc_textarea(  $lp_catch ); ?></textarea></li>
      <li class="cf"><span class="label"><span class="num">1</span><?php _e('Catchphrase (mobile)', 'tcd-genesis'); ?></span><textarea placeholder="<?php _e( 'Please indicate if you would like to display a short text for mobile sizes.', 'tcd-genesis' ); ?>" class="full_width" cols="50" rows="2" name="lp_catch_mobile"><?php echo esc_textarea(  $lp_catch_mobile ); ?></textarea></li>
      <li class="cf">
       <span class="label"><span class="num">2</span><?php _e('Font type of catchphrase', 'tcd-genesis');  ?></span>
       <div class="standard_radio_button">
        <?php
             foreach ( $font_type_options as $option ) {
               if(strtoupper(get_locale()) == 'JA'){
                 $label = $option['label'];
               } else {
                 $label = $option['label_en'];
               }
        ?>
        <input id="lp_catch_font_type_<?php echo esc_attr($option['value']); ?>" type="radio" name="lp_catch_font_type" value="<?php echo esc_attr($option['value']); ?>"<?php checked( $lp_catch_font_type, $option['value'] ); ?>>
        <label for="lp_catch_font_type_<?php echo esc_attr($option['value']); ?>"><?php echo esc_html($option['label']); ?></label>
        <?php } ?>
       </div>
      </li>
      <li class="cf">
       <span class="label"><span class="num">3</span><?php _e('Position of catchphrase', 'tcd-genesis');  ?></span>
       <div class="standard_radio_button">
       <div class="standard_radio_button">
        <?php foreach ( $content_direction_options as $option ) { ?>
        <input id="lp_catch_font_direction_<?php echo esc_attr($option['value']); ?>" type="radio" name="lp_catch_font_direction" value="<?php echo esc_attr($option['value']); ?>"<?php checked( $lp_catch_font_direction, $option['value'] ); ?>>
        <label for="lp_catch_font_direction_<?php echo esc_attr($option['value']); ?>"><?php echo esc_html($option['label']); ?></label>
        <?php } ?>
       </div>
       </div>
      </li>
      <li class="cf">
       <span class="label"><span class="num">4</span><?php _e('Font size of catchphrase', 'tcd-genesis'); ?></span>
       <div class="font_size_option">
        <label class="font_size_label number_option">
         <input class="hankaku input_font_size" type="number" name="lp_catch_font_size" value="<?php esc_attr_e( $lp_catch_font_size ); ?>"><span class="icon icon_pc"></span>
        </label>
        <label class="font_size_label number_option">
         <input class="hankaku input_font_size_sp" type="number" name="lp_catch_font_size_sp" value="<?php esc_attr_e( $lp_catch_font_size_sp ); ?>"><span class="icon icon_sp"></span>
        </label>
       </div>
      </li>
      <li class="cf">
       <span class="label">
        <span class="num">5</span>
        <?php _e('Background image', 'tcd-genesis'); ?>
        <span class="recommend_desc"><?php printf(__('Recommend image size. Width:%1$spx, Height:%2$spx.', 'tcd-genesis'), '1450', '600'); ?></span>
       </span>
       <?php mlcf_media_form_child('lp_image', __('Background image', 'tcd-genesis')); ?>
      </li>
      <li class="cf">
       <span class="label">
        <span class="num">5</span>
        <?php _e('Background image (mobile)', 'tcd-genesis'); ?>
        <span class="recommend_desc"><?php printf(__('Recommend image size. Width:%1$spx, Height:%2$spx.', 'tcd-genesis'), '750', '400'); ?></span>
       </span>
       <?php mlcf_media_form_child('lp_image_mobile', __('Small image', 'tcd-genesis')); ?>
      </li>
      <li class="cf"><span class="label"><span class="num">5</span><?php echo tcd_admin_label('overlay_color'); ?></span><input type="text" name="lp_header_overlay_color" value="<?php echo esc_attr( $lp_header_overlay_color ); ?>" data-default-color="#000000" class="c-color-picker"></li>
      <li class="cf">
       <span class="label"><span class="num">5</span><?php _e('Transparency of overlay', 'tcd-genesis'); ?></span><input class="hankaku" style="width:70px;" type="number" max="1" min="0" step="0.1" name="lp_header_overlay_color_opacity" value="<?php echo esc_attr( $lp_header_overlay_color_opacity ); ?>" />
       <div class="theme_option_message2" style="clear:both; margin:7px 0 0 0;">
        <p><?php _e('Please specify the number of 0 from 0.9. Overlay color will be more transparent as the number is small.', 'tcd-genesis');  ?><br>
        <?php _e('Please enter 0 if you don\'t want to use overlay.', 'tcd-genesis');  ?></p>
       </div>
      </li>
     </ul>

    </div><!-- END #lp_header -->

    <ul class="button_list cf">
     <li><a class="close_ac_content button-ml" href="#"><?php echo __( 'Close', 'tcd-genesis' ); ?></a></li>
    </ul>
   </div><!-- END .theme_option_field_ac_content -->
  </div><!-- END .theme_option_field -->
  
<?php //ギャラリーの設定を固定ページのみに限定
//global $post_type;
//if ( 'page' === $post_type ) { ?>
  
  <?php // ギャラリーの設定 --------------------------------------------------- ?>
  <div class="theme_option_field cf theme_option_field_ac" id="gallery_content_short_code_custom">
   <h3 class="theme_option_headline"><?php _e( 'Gallery', 'tcd-genesis' ); ?></h3>
   <div class="theme_option_field_ac_content">

    <div class="cb_image">
     <img src="<?php bloginfo('template_url'); ?>/admin/img/sc_gallery.jpg?2.0" width="" height="" />
    </div>

    <div class="theme_option_message2">
     <p><?php _e('Please copy and paste the short code below where you want to display gallery.', 'tcd-genesis'); ?></p>
     <p><?php _e( 'Short code', 'tcd-genesis' ); ?> : <input style="background:#fff; width:200px;" type="text" value="[sc_gallery]" readonly></p>
    </div>

    <ul class="option_list">
     <li class="cf"><span class="label"><span class="num">1</span><?php _e('Catchphrase', 'tcd-genesis'); ?></span><textarea class="full_width" cols="50" rows="2" name="gallery_catch"><?php echo esc_textarea(  $gallery_catch ); ?></textarea></li>
     <li class="cf"><span class="label"><span class="num">2</span><?php _e('Description', 'tcd-genesis'); ?></span><textarea class="full_width" cols="50" rows="5" name="gallery_desc"><?php echo esc_textarea(  $gallery_desc ); ?></textarea></li>
     <li class="cf"><span class="label"><span class="num">2</span><?php _e('Description (mobile)', 'tcd-genesis'); ?></span><textarea placeholder="<?php _e( 'Please indicate if you would like to display a short text for mobile sizes.', 'tcd-genesis' ); ?>" class="full_width" cols="50" rows="5" name="gallery_desc_mobile"><?php echo esc_textarea(  $gallery_desc_mobile ); ?></textarea></li>
     <li class="cf">
      <span class="label">
       <span class="num">3</span>
       <?php _e('Image', 'tcd-genesis'); ?>
       <span class="recommend_desc"><?php printf(__('Recommend image size. Width:%1$spx, Height:%2$spx.', 'tcd-genesis'), '190', '190'); ?></span>
       <span class="recommend_desc"><?php _e('You can register multiple image by clicking images in media library.', 'tcd-genesis'); ?></span>
      </span>
<?php
     $display = 'none';
     $image_ids = explode( ',', $gallery_image );
?>
<div class="multi-media-uploader">
 <ul>
  <?php
       if ( $gallery_image && !empty($image_ids) ) {
         $display = 'inline-block';
         foreach ( $image_ids as $image_id ) {
           if ( $image_attributes = wp_get_attachment_image_src( $image_id, 'thumbnail' ) ) {
  ?>
  <li data-attechment-id="<?php echo $image_id; ?>">
   <img src="<?php echo $image_attributes[0]; ?>" />
   <span class="delete-img"></span>
  </li>
  <?php

          }
        }
      }
  ?>
 </ul>
 <a id="gallery_image" href="#" class="js-multi-media-upload-button button">
  <?php _e( 'Select Image', 'tcd-genesis' ); ?>
 </a>
 <input type="hidden" class="attechments-ids <?php echo $name; ?>" name="gallery_image" id="gallery_image" value="<?php echo esc_attr( implode( ',', $image_ids ) ); ?>" />
 <a href="#" class="js-multi-media-remove-button button" style="display:<?php echo $display; ?>;">
  <?php _e( 'Delete all images', 'tcd-genesis' ); ?>
 </a>
</div>
     </li>
    </ul>

    <ul class="button_list cf">
     <li><a class="close_ac_content button-ml" href="#"><?php echo __( 'Close', 'tcd-genesis' ); ?></a></li>
    </ul>
   </div><!-- END .theme_option_field_ac_content -->
  </div><!-- END .theme_option_field -->

<?php //} //-- END 'page' === $post_type ?>

  <?php // FAQの設定 --------------------------------------------------- ?>
  <div id="page_faq_option" class="theme_option_field cf theme_option_field_ac">
   <h3 class="theme_option_headline"><?php _e( 'FAQ', 'tcd-genesis' ); ?></h3>
   <div class="theme_option_field_ac_content">

    <div class="cb_image">
     <img src="<?php bloginfo('template_url'); ?>/admin/img/sc_faq.jpg?4.0" width="" height="" />
    </div>

    <div class="theme_option_message2">
     <p><?php _e('Please copy and paste the short code below where you want to display FAQ list.', 'tcd-genesis'); ?></p>
     <p><?php _e( 'Short code', 'tcd-genesis' ); ?> : <input style="background:#fff; width:200px;" type="text" value="[sc_faq]" readonly></p>
    </div>

    <?php // リスト ------------------------------------------------------------------------- ?>
    <h4 class="theme_option_headline2"><?php _e( 'FAQ list', 'tcd-genesis' ); ?></h4>
    <?php //繰り返しフィールド ----- ?>
    <div class="repeater-wrapper">
     <div class="repeater sortable" data-delete-confirm="<?php echo tcd_admin_label('delete'); ?>">
       <?php
           if ( $faq_list ) :
             foreach ( $faq_list as $key => $value ) :
       ?>
       <div class="sub_box repeater-item repeater-item-<?php echo $key; ?>">
        <h4 class="theme_option_subbox_headline"><?php echo esc_html( ! empty( $faq_list[$key]['question'] ) ? $faq_list[$key]['question'] : tcd_admin_label('new_item') ); ?></h4>
        <div class="sub_box_content">
         <h4 class="theme_option_headline2"><?php _e( 'Question', 'tcd-genesis' ); ?></h4>
         <p><input class="repeater-label full_width" type="text" name="faq_list[<?php echo esc_attr( $key ); ?>][question]" value="<?php echo esc_attr( isset( $faq_list[$key]['question'] ) ? $faq_list[$key]['question'] : '' ); ?>" /></p>
         <h4 class="theme_option_headline2"><?php _e( 'Answer', 'tcd-genesis' ); ?></h4>
         <textarea class="full_width" cols="50" rows="5" name="faq_list[<?php echo esc_attr( $key ); ?>][answer]"><?php echo esc_attr( isset( $faq_list[$key]['answer'] ) ? $faq_list[$key]['answer'] : '' ); ?></textarea>
         <p class="delete-row right-align"><a href="#" class="button button-secondary button-delete-row"><?php echo tcd_admin_label('delete_item'); ?></a></p>
        </div><!-- END .sub_box_content -->
       </div><!-- END .sub_box -->
       <?php
             endforeach;
           endif;
           $key = 'addindex';
           ob_start();
       ?>
       <div class="sub_box repeater-item repeater-item-<?php echo $key; ?>">
        <h4 class="theme_option_subbox_headline"><?php echo esc_html( ! empty( $faq_list[$key]['question'] ) ? $faq_list[$key]['question'] : tcd_admin_label('new_item') ); ?></h4>
        <div class="sub_box_content">
         <h4 class="theme_option_headline2"><?php _e( 'Question', 'tcd-genesis' ); ?></h4>
         <p><input class="repeater-label full_width" type="text" name="faq_list[<?php echo esc_attr( $key ); ?>][question]" value="<?php echo esc_attr( isset( $faq_list[$key]['question'] ) ? $faq_list[$key]['question'] : '' ); ?>" /></p>
         <h4 class="theme_option_headline2"><?php _e( 'Answer', 'tcd-genesis' ); ?></h4>
         <textarea class="full_width" cols="50" rows="5" name="faq_list[<?php echo esc_attr( $key ); ?>][answer]"><?php echo esc_attr( isset( $faq_list[$key]['answer'] ) ? $faq_list[$key]['answer'] : '' ); ?></textarea>
         <p class="delete-row right-align"><a href="#" class="button button-secondary button-delete-row"><?php echo tcd_admin_label('delete_item'); ?></a></p>
        </div><!-- END .sub_box_content -->
       </div><!-- END .sub_box -->
       <?php
           $clone = ob_get_clean();
       ?>
       </div><!-- END .repeater -->
     <a href="#" class="button button-secondary button-add-row" data-clone="<?php echo esc_attr( $clone ); ?>"><?php echo tcd_admin_label('add_item'); ?></a>
    </div><!-- END .repeater-wrapper -->
    <?php //繰り返しフィールドここまで ----- ?>

    <ul class="button_list cf">
      <li><a class="close_ac_content button-ml" href="#"><?php echo tcd_admin_label('close'); ?></a></li>
    </ul>
   </div><!-- END .theme_option_field_ac_content -->
  </div><!-- END .theme_option_field -->


</div><!-- END .tcd_custom_field_wrap -->

<?php
}

function save_page_header_meta_box_child( $post_id ) {

  // verify nonce
  if (!isset($_POST['page_header_custom_fields_meta_box_nonce']) || !wp_verify_nonce($_POST['page_header_custom_fields_meta_box_nonce'], basename(__FILE__))) {
    return $post_id;
  }

  // check autosave
  if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
    return $post_id;
  }

  // check permissions
  if ('page' == $_POST['post_type']) {
    if (!current_user_can('edit_page', $post_id)) {
      return $post_id;
    }
  } elseif (!current_user_can('edit_post', $post_id)) {
      return $post_id;
  }

  // save or delete
  $cf_keys = array(
    'header_headline','header_sub_title','header_catch','header_desc','header_desc_mobile','header_image','header_overlay_color','header_overlay_color_opacity',
    'hide_page_header_bar','hide_page_header','page_hide_footer','hide_header_message','page_width','page_width_type2','page_width_t2_type2','hide_sidebar','hide_sidebar_type2','hide_page_header_logo','hide_breadcrumb','hide_breadcrumb_type2',
    'gallery_image','gallery_catch','gallery_desc','gallery_desc_mobile'
  );
  foreach ($cf_keys as $cf_key) {

    $old = get_post_meta($post_id, $cf_key, true);

    if (isset($_POST[$cf_key])) {
      $new = $_POST[$cf_key];
    } else {
      $new = '';
    }

    if($cf_key == 'header_overlay_color_opacity'){
      if ( $new == '0' ) {
        $new = 'zero';
      }
    }
    if($cf_key == 'lp_header_overlay_color_opacity'){
      if ( $new == '0' ) {
        $new = 'zero';
      }
    }

    if ($new && $new != $old) {
      update_post_meta($post_id, $cf_key, $new);
    } elseif ('' == $new && $old) {
      delete_post_meta($post_id, $cf_key, $old);
    }

  }

  // repeater save or delete
  $cf_keys = array('faq_list');
  foreach ( $cf_keys as $cf_key ) {
    $old = get_post_meta( $post_id, $cf_key, true );

    if ( isset( $_POST[$cf_key] ) && is_array( $_POST[$cf_key] ) ) {
      $new = array_values( $_POST[$cf_key] );
    } else {
      $new = false;
    }

    if ( $new && $new != $old ) {
      update_post_meta( $post_id, $cf_key, $new );
    } elseif ( ! $new && $old ) {
      delete_post_meta( $post_id, $cf_key, $old );
    }
  }

}
add_action('save_post', 'save_page_header_meta_box_child');



?>

合わせて以下の画像を作成し、子テーマ「admin」→「img」に配置します。(名称:type2_image.jpg)

Screenshot

「custom_cf.php」は「functions.php」で読み込みます。

// 編集画面カスタムフィールドをカスタム投稿タイプに適用 --------------------------------------------------------------------------------
require get_stylesheet_directory() . '/functions/custom_cf.php';

ここまで来れば、もう一歩です。その他の設定は以下の2つです。

ギャラリーカスタムフィールドのメッセージを変更

編集画面のグレーアウトしたボタンのメッセージを変更します。

編集画面のグレーアウトしたボタン

ギャラリーカスタムフィールドが使えるのはカスタム投稿タイプの際はサイドバーを表示しない時のみなので、表示する文章が固定ページのままだと変です。

そこで非アクティブの場合のメッセージを変更します。

// カスタム投稿用ギャラリーショートコード
function css_inline_code_admin_style_child() {
  echo "<style type='text/css'>\n";
  echo "#gallery_content_short_code_custom.deactive { pointer-events:none; }\n";
  echo "#gallery_content_short_code_custom.deactive .theme_option_headline:after { content:'" . __( 'Available only when selecting hide sidebar', 'tcd-genesis-child' ) . "'; width:calc(100% - 40px); height:100%; position:absolute; top:0; left:0; background:rgba(0,0,0,0.6); color:#fff; font-size:12px; text-align:center; line-height:1.4; display:flex; flex-wrap:wrap; justify-content:center; align-items:center; padding:0 20px; }\n";
  echo "</style>\n";
}
add_action('admin_print_styles', 'css_inline_code_admin_style_child');

poファイルに「Available only when selecting hide sidebar」を追加します。

対訳は「表示設定よりサイドバーを表示しないに設定にした場合にのみご利用いただけます」としました。

head内CSSの設置

固定ページタイプのカスタム投稿でも画像のオーバーレイを設定する機能があります。

編集画面のオーバレイ設定

これは<head></head>の間にCSSを設定して制御しています。

// カスタム投稿ページのヘッドCSS -----------------------------------------------------------------------
function custom_type2_head_css(){
	$options = get_design_plus_option();
    global $post;
    
    if(is_singular('product')) {
		$overlay_opacity = get_post_meta($post->ID, 'header_overlay_color_opacity', true) ?  get_post_meta($post->ID, 'header_overlay_color_opacity', true) : '0.3';
		if($overlay_opacity == 'zero'){
			$overlay_opacity = '0';
		}
		if($overlay_opacity != '0'){
			$overlay_color = get_post_meta($post->ID, 'header_overlay_color', true) ?  get_post_meta($post->ID, 'header_overlay_color', true) : '#000000';
			$overlay_color = hex2rgb($overlay_color);
			$overlay_color = implode(",",$overlay_color);
			?>
			#page_header .overlay { background-color:rgba(<?php echo esc_attr($overlay_color); ?>,<?php echo esc_attr($overlay_opacity); ?>); }
		<?php
		};
	} 
}
add_action('tcd_head_css_current_page', 'custom_type2_head_css');

親テーマの「functions」→「head.php」でdo_action( ‘tcd_head_css_current_page’ );を用意しているので、そこにフックします。

まとめ

このページではWordPressテーマ/GENESIS(TCD103)にカスタム投稿タイプを追加する方法を紹介いたしました。

実現するためには冒頭で述べたように以下のノウハウが必要です。

このページで主に学べること
  • 子テーマの作り方
  • 添付ファイルの無効化方法
  • functions.phpでカスタム投稿を定義する方法
  • カスタム投稿のアーカイブページ、タクソノミーページ、シングルページのphp名称
  • カスタマイザーの設定方法
  • ショートコードの作り方
  • テンプレートを選択可能にする方法
  • テンプレートパーツの読み込み方
  • bodyクラスの活用方法
  • カスタムフィールドの作り方
  • 管理画面用のCSSやJavaScriputの読み込み方
  • 親テーマで「require」されたphpの変更方法
  • フックの取り消し方
  • フックの対象を見つける方法

このページを実践できれば、上記のノウハウを身につけることができます。

これで、テーマカスタマイズの基本が分かってくると思います。

WordPressテーマ/GENESIS(TCD103)のカスタマイズはJavaScript依存が強いので難易度が高いです。

しかし、このページをお読みいただければ、カスタム投稿タイプの追加は簡単にできるようになるのではと、期待しています。

実践に即した解説をいたしましたので、まだ、WordPressテーマ/GENESIS(TCD103)をお持ちでない場合は、是非、購入して記事のノウハウを試してください。

5万円をこえる金額高めのテーマですが、取得できるノウハウは、このテーマに限定されるものではありませんので、対価としては安いと考えることもできます。

それに、WordPressテーマ/GENESIS(TCD103)を思う存分使いこなすことができると思います。

最後にWordPressテーマ/GENESIS(TCD103)購入ページへのリンクを記載しておきます。

【PR】「Theme3」では、企業サイトのWordPressテーマに「 ワードプレステーマTCD 」をオススメしています。
WordPressテーマ「GENESIS」の詳細をTCDのページで見る

ブロックエディタ対応
カスタム投稿タイプ「お知らせ」「サービス(事業案内)」
SEO機能(metaタグ、OGP、高速化)
他、機能多数。

ご購入は以下のバナーリンクページの購入ボタンをクリックしてください。

プロモーション

戦略的WEBサイト構築方法

戦略的WEBサイト構築方法
WEB担当者にオススメ

WEBサイトをビジネス戦略のPDCAサイクルに組み込むための考え方と、サイトを内製化する方法を分かりやすく解説します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

2 × 4 =

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

ABOUT US
lin記事を書いている人
はじめまして。「lin」です。クリエイティブディレクター兼グラフィックデザイナーとして活動しています。おかげさまで、キャリア25年以上になりました。「Theme3」は、私が企画デザイン事務所スラッシュディーの仕事で得たノウハウを公開します。
※以下は私が活動している企業情報にリンクしています。