MENU CLOSE

【WordPress】
Smart Custom Fieldsを
コード定義で管理する

WordPress
WordPress

Smart Custom Fieldsとは?

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_authoradd_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_authoradd_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しか使っていないくらい、このプラグインには本当にお世話になっています。
コードを工夫すれば、プルダウンなど選択式のカスタムフィールドに動的に値を設定したりいろいろとカスタマイズできます。とてもおすすめです。

記事一覧

RELATED

PhotoSwipe
inoue
inoue
TIPS

PhotoSwipeを使って画像をポップアップ表示する【Swiper(v7)との連携あり】

Transients API
inoue
inoue
TIPS

【WordPress】Transients APIを使ってデータをキャッシュする方法

Flatpickr
inoue
inoue
TIPS

Flatpickrで日時入力をカレンダー表示にする

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【実践編】見出しの文言を変更できるようにする

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【デザインオプション編】テーマに新しい機能を加える方法

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【準備編】カスタマイズに必要な前提知識について

NEW POSTS

svg-audiovisualizerAudioVisualizer [ howler.js + SVG ]
inoue
inoue
TRY

【howler.js】ストリーミング音源からオーディオビジュアライザーを作る

Simple GA Ranking
inoue
inoue
TRY

Simple GA Ranking[ver2.1.6]が表示されないので調べてみた

Sass @import → @use
inoue
inoue
TRY

【Sass】@importを@useに置き換えてみる《FLOCSS対応》

Stripe Payment Links
inoue
inoue
TRY

コーディング一切不要のStripe Payment Linksで決済機能を試してみる

BASE Partners
inoue
inoue
COLUMN

【BASE Partners】有料テーマの無償提供特典について

BACKGROUND VIDEO
inoue
inoue
TIPS

動画をWebページの背景に埋め込む時のテクニック

ブログ記事一覧
  • HOME
  • TIPS
  • 【WordPress】Smart Custom Fieldsをコード定義で管理する