カスタムフィールド

WordPressのカテゴリーに「カスタムフィールド」を設定する

当サイトのテーマShirohanadaはカテゴリー表示の時、全文表示と抜粋表示を切り換える機能を実装している。
この抜粋・全文の表示フラグ、構想当初は「カスタムフィールドで保持して読み書きすればいいだろう」と考えていた。 投稿に対するカスタムフィールドはget_post_meta()などで取得する。多分、なんか楽にできる仕掛けがあるだろう、と。
結果、「カスタムフィールド」ではなく、theme_modで実装しました。その紆余曲折とtheme_modについての記事です。

wp_optionsテーブルがカオス

「カテゴリー カスタムフィールド」なんかでググったところget_options関数を使う例がいくつかみられた。
「これだこれだ、wp_optionsテーブルに入れてget_optionsで取得するのね。さてどういう感じで入れようかね」とコードを書いていたら何か上手く行ったり行かなかったり。
データベースの方はどうなってるんだ?というわけでphpmyadminでwp_optionsテーブルを見ると…
レコード番号が物凄い値になってる…(まあIDの連番がすごい数になってるぐらいは、どうということはないはず)
当サイトのwp_options スクリーンショット

「カスタムフィールド」とは何か?

改めてカスタムフィールドやデータベースについて、WordPress Codexの説明を読む。

WordPress には、投稿者が投稿に「カスタムフィールド」を追加できる機能があります。
WordPress Codex カスタムフィールドの使い方

このカスタムフィールドはpost_metaというテーブルに保存される。post_metaは投稿に対して付加されるので、カテゴリー番号やカテゴリー名でセットすることができないのだ。
WordPress Codexデータベース構造によると…

wp_postmeta
メタデータという各投稿記事特有の情報を格納。カスタムフィールドとして使用するほか、各投稿に情報や設定を付加するようなプラグインが、その情報を当テーブルに追加することがある。
wp_options
管理 > 設定で設定されたオプション設定情報を格納(オプション設定リファレンス参照)。プラグインの設定情報が格納されることも多い。

カスタムフィールドというのは、基本的に「投稿」を拡張する仕組みであって、カテゴリー単位の設定情報とかを保存する仕組みではない。
ならば、まさにwp_optionsを使うところなのだが……
どうも過去に使っていたプラグインの一時データやら設定やらで膨れあがっている。
そうするとテーマが削除されるタイミングをフックして、関係するレコードは削除しなくてはならないなあ……
カテゴリーが増えてきたら、沢山のプラグインと同居したら、きちんとレコードから「ウチのテーマの抜粋表示・全文表示フラグ」を取れるんだろうか、正しく書き込めるだろうか……

theme_modsレコード

wp_optionsテーブルを眺めていたら、mods_twentyelevenやtwelveなるレコードがある。
もしかして、枠線の色を変えたりとかTwenty系テーマのカスタマイズ値はここに格納されているのだろうか?
テーマ名を含むレコードのphp my admin のスクリーンショット

テーマカスタマイズ API
テーマ設定を取得し、ヘッダーにCSSを出力します。 上記のように customize_register アクションでテーマ設定を追加したなら、wp_head アクションで CSS を出力したり、get_theme_mod() / en で設定値を取得するだけです。

正解。これだ。
テーマをカスタマイズしたら、wp_optionsテーブルの
theme_mods_[テーマ名] レコードにキーと値が格納されているので、get_theme_mod(‘Key’, default)で取得してテンプレートやCSS、Javascriptで煮るなる焼くなりしている。

get/set メソッドで簡単に使える

set_theme_mod( $name, $value )
抜粋表示フラグをセットする。
cat_を接頭辞にしてカテゴリー番号を使ってキーを作成する。キーと値との組を引数にしてset関数実行。

$cat_id = "cat_$term_id";
if ( 'yes' === $flag ) {
  set_theme_mod( $cat_id, true );
} else {
  set_theme_mod( $cat_id, false );
}

get_theme_mod( $name, $default )
抜粋表示フラグを取り出す時は、同じくカテゴリー番号からキーを作ってget関数を実行。

$key = 'cat_' . get_query_var( 'cat' );
$is_show_excerpt = get_theme_mod( $key );

シンプル!
theme_modsレコードがない時はWordPressコアの方で上手いことやってくれると思います(未検証)
wp_optionsテーブルのtheme_mods_shirohanadaレコードに格納されている値はこんな感じ。

a:9:
{
  i:0;
  b:0;
  s:81:"https://autumnsky.jp/wp-content/uploads/2016/11/161029-web.jpg";
  s:17:"header_image_data";
  O:8:"stdClass":5:
    {
    s:13:"attachment_id";
    i:15747;
    /* このへんカスタムヘッダー関係の設定値. */
    s:6:"height";
    i:700;
    s:5:"width";
    i:700;
    }
  /* set_theme_mod()でセットした値. */
  s:6:"cat_10";
  b:1;
  s:7:"cat_269";
  b:0;
  s:7:"cat_157";
  b:0;
  s:7:"cat_253";
  b:1;
}

外観のカスタマイズ用ということもあって、かなり大量の要素を扱えるようになっているみたいです。
本来の用途はダッシュボード > 外観 > カスタマイズ で設定した値を簡単に保存・読出するための関数です。
ダッシュボード > 外観 > カスタマイズ スクリーンショット
この画面の左側、カスタマイズ項目を自由に追加するために用意されている関数・クラスです。本来の使い方はテーマカスタマイズ APIを参考にして下さい。私もあまりよく分かっていません。

まとめ

テーマ固有の値を保持したいときは、WordPressのtheme_mod関係の関数を使って簡単にできます。
投稿の抜粋・全文の表示の制御など、プラグインでやることじゃないか?
と思いましたが、しかし、どちらにも対応したテンプレート構造・CSSを用意しないといけないので、Shirohanadaではテーマ側で実装しています。
結局、カスタムフィールドとwp_optionsは使ってませんが、タイトルはあえて「カスタムフィールド」としました。