Smart Custom Fields(スマートカスタムフィールズ)はWordPressのカスタムフィールドを使いやすく拡張してくれるプラグインです。
Smart Custom Fields
https://ja.wordpress.org/plugins/smart-custom-fields/
カスタムフィールドの拡張プラグインは有名どころでは他に、
などがあります。
Smart Custom Fieldsの特徴としては、Advanced Custom Fieldsではpro版(有料)でないと使えないループ機能が使える、オプションページが作れる、functions.php
にコードでカスタムフィールドを定義しておける、などがあります。
今回記事としてメモしておきたいのが「コードでカスタムフィールドを定義しておける」という部分なので、それについてを書きます。
Smart Custom Fieldsのそもそもの使い方については、簡単なので公式プラグインページや作者のページを参考にしてみると良いです。
smart-cf-register-fields
というフィルターフックを使ってfunctions.php
内にカスタムフィールドを定義します。
/**
* カスタムフィールドを定義
*
* @param array $settings MW_WP_Form_Setting オブジェクトの配列
* @param string $type 投稿タイプ or ロール
* @param int $id 投稿ID or ユーザーID
* @param string $meta_type post | user
* @return array
*/
function my_add_meta_box( $settings, $type, $id, $meta_type )
{
//ユーザープロフィール画面を判定
switch ($meta_type) {
case 'user':
$settings = add_meta_box_author($settings, $id);
break;
default:
break;
}
//投稿タイプで判定
switch($type) {
//投稿ページ
case 'post':
$settings = add_meta_box_posts($settings, $id);
break;
//固定ページ
case 'page':
$settings = add_meta_box_pages($settings, $id);
break;
default:
break;
}
return $settings;
}
add_filter( 'smart-cf-register-fields', 'my_add_meta_box', 10, 4 );
このフックを使うと、引数が4つ取れるので、それによって管理画面のどのページにどのカスタムフィールドを定義するかを細かくコードで条件分岐することが可能になります。 サンプルで書いたPHPのswitch構文はちょっと・・・って方は各自書き換えてください。
条件分岐内のadd_meta_box_author
やadd_meta_box_posts
などの関数については後述します。
個人的にはこのフィルターフック機能がSmart Custom Fieldsを選んでいる理由のひとつです。
他のプラグインではカスタムフィールドを表示するページを細かく制御できない場合があり、表示させたくないページに全然関係ないフィールドが表示されてしまう、といったことがあります。
例をあげると、「フロントページの子ページのみにカスタムフィールドを追加したい」というように条件が少し複雑になると、プラグインに標準で付いている表示条件ではうまく設定できない場合があります。
これがコードベースだと上記のサンプルコードのようにテンプレート作成と同じく条件分岐すればいいだけなので、とても簡単に設定できます。
例はちょっと極端な条件でしたが、いろんなページでたくさんのカスタムフィールドを扱うサイトの場合になると、必要なページに必要な入力エリアだけを用意してあげるのもWordPressテーマを制作する上で必要なことだと思います。
また、一度コードで定義しておけば同じようなカスタムフィールドは他のテーマへの流用ができるため、今後のテーマ作成が捗ります。
少し脱線しましたが、コードに戻ります。
SEOグループとして「タイトル」「ディスクリプション」「noindex」「OGP画像」のカスタムフィールドを作ってみます。
function add_scf_seo_group(){
//SCF::add_setting( 'ユニークなID', 'メタボックスのタイトル' );
$setting = SCF::add_setting( 'meta_box_seo', 'SEO' );
// $setting->add_group( 'ユニークなID', 繰り返し可能か, カスタムフィールドの配列 );
$setting->add_group('cf_seo_group', false,
[
[
'name' => 'cf_title',
'label' => 'タイトル',
'type' => 'text',
'notes' => '30文字前後'
],
[
'name' => 'cf_description',
'label' => 'ディスクリプション',
'type' => 'textarea',
'rows' => 5,
'notes' => '120文字前後'
],
[
'name' => 'cf_noindex',
'label' => '検索結果に表示させる',
'type' => 'boolean'
],
[
'name' => 'cf_ogp',
'label' => 'OGP画像',
'type' => 'image',
'notes' => '横1200×縦630',
'size' => 'large'
]
]
);
return $setting;
}
管理画面から新規作成する場合は対応するものを選択して入力するだけですが、コードになると配列でオプションを追加していくような書き方になります。
オプションの書き方については、Qiitaにまとめている方がおられるのでそちらの記事を参考にすると良いかと思います。
SmartCustomFieldsのコードでの定義についてのまとめ
https://qiita.com/yousan/items/7cbd56308ecc0e2bb263
書き方は好き嫌いによるところもありますが、1つの役割を持ったフィールドグループごとに関数を分けて書いておくと便利です。例えばサンプルの「SEO」グループにはSEO関連のカスタムフィールドだけ入れておき、それ以外のフィールドは別のグループとして切り分けておきます。そうして細分化しておくとコードベースで管理するメリットが出てきます。
例として「よくある質問」を追加する場合は、シンプルに質問と答えのカスタムフィールドを括ったよくある質問グループを作って、ループをオンにしておけば必要な数だけ追加できる汎用的なカスタムフィールドとなります。またこのコードはグループ名・フィールド名・ラベル名だけ変えれば「お知らせ」など他の用途にすぐに流用できます。
function add_scf_faq_group(){
$setting = SCF::add_setting( 'meta_box_faq', 'よくある質問' );
$setting->add_group('cf_faq_group', true, //trueでループをオン
[
[
'name' => 'cf_faq_question',
'label' => '質問',
'type' => 'textarea',
'rows' => 2
],
[
'name' => 'cf_faq_answer',
'label' => '答え',
'type' => 'textarea',
'rows' => 2
]
]
);
return $setting;
}
//add_scf_faq()を流用して使う
function add_scf_info_group(){
$setting = SCF::add_setting( 'meta_box_info', 'お知らせ' );
$setting->add_group('cf_info_group', true,
[
[
'name' => 'cf_info_title',
'label' => 'タイトル',
'type' => 'textarea',
'rows' => 2
],
[
'name' => 'cf_info_detail',
'label' => '詳細',
'type' => 'textarea',
'rows' => 2
]
]
);
return $setting;
}
管理画面からフィールドグループを作ると最初は簡単で手軽に思いますが、別の環境で同じようなカスタムフィールドを用意したいと思った時にコピーしたいだけなのにデータベースが絡んでくるので、画面を見ながら手動で入力したり、いちいちXMLでインポート・エクスポートしたり、DBごとコピーしたりと作業が大変になります。
その点コードベースで管理されていると、一度作っておけば新しいテーマを作る時には管理画面に入らずともコピペで作れます。開発者的には非常に楽です。本番環境とテスト環境で別のデータベースになっている場合でも対応できます。
各カスタムフィールドの追加関数を作成したら、あとは条件に合わせてフィールドを管理画面に追加していきます。 先ほど飛ばしたadd_meta_box_author
やadd_meta_box_posts
などの関数についてがこちらになります。
//ユーザープロフィール編集画面
function add_meta_box_author($settings, $id){
//プロフィール画像フィールドグループを追加する
$settings[] = add_scf_avatar_group();
//SEOフィールドグループを追加する
$settings[] = add_scf_seo_group();
return $settings;
}
//投稿ページ編集画面
function add_meta_box_posts($settings, $id) {
//関連記事
$settings[] = add_scf_related_post_group();
//SEO
$settings[] = add_scf_seo_group();
return $settings;
}
//固定ページ編集画面
function add_meta_box_pages($settings, $id) {
//SEO
$settings[] = add_scf_seo_group();
//記事取得
$post = get_post($id);
if(!empty($post)){
//親ページID
$parent_id = $post->post_parent;
//フロントページID取得
$frontpage_id = intval(get_option( 'page_on_front' ));
//フロントページの子ページの場合のみ
if($parent_id === $frontpage_id){
//お知らせフィールドグループを追加する
$settings[] = add_scf_info_group();
}
}
return $settings;
}
ユーザープロフィール編集画面にはプロフィール画像のカスタムフィールド(サンプルコードはありません)と、先ほどサンプルで作ったSEOカスタムフィールドを追加しています。
同じ要領で投稿ページ、固定ページにも追加していますが、固定ページには前述で例に示した条件で「フロントページの子ページの場合のみにお知らせカスタムフィールドグループを追加する」として実装してみました。
条件分岐を複雑にした場合、新規作成時に一度「下書き保存」しないとカスタムフィールドが表示されない場合があります。
例えばA・B・Cというカテゴリーがある投稿ページで「カテゴリーがAの時のみカスタムフィールドを追加する」という条件にした場合などです。
新規作成時はカテゴリーが選択されていないので、フィルターフックで設定している条件分岐に当てはまらないので表示されません。その場合はカテゴリを一旦選んで下書き保存し、管理画面をリロードすればフィールドが追加されます。
コード定義できるようになってからSmart Custom Fieldsしか使っていないくらい、このプラグインには本当にお世話になっています。
コードを工夫すれば、プルダウンなど選択式のカスタムフィールドに動的に値を設定したりいろいろとカスタマイズできます。とてもおすすめです。