WordPressのカスタムフィールドがかなり便利になっている件(3.5対応)
Posted by admin at 13:48 日時 2012/12/05
おそらく、数年前のWordPressの解説本の知識でいる方にとって、かなりオドロキの進化がなされているのではないかと思うのが、WordPressのカスタムフィールド周りの機能です。
たとえば、ピックアップ商品としてフラグを立てた商品の中から、価格が500円以上のものを最新5件取得して表示する、みたいなコードは、WordPress3.5ではこのように書けます。非常にスッキリしております。
<section> <h1>ピックアップ商品</h1> <ul> <?php // 投稿の取得条件を設定 $args = array( // 'product' 投稿タイプから取得 'post_type' => 'product', // 最新の投稿を5件取得 'posts_per_page' => 5, // カスタムフィールドで絞込み 'meta_query' => array( // 全ての条件を満たす 'relation' => 'AND', // 'is_featured' が '1' のとき array( 'key' => 'is_featured', 'value' => '1', ), // 'price' が 500 以上の時(数字として比較) array( 'key' => 'price', 'value' => 500, 'compare' => '>=', 'type' => 'NUMERIC' ), ), ); // 条件を満たす投稿を取得 $myposts = get_posts($args); // ループ foreach ( $myposts as $post ) : // テンプレートタグをセットアップ setup_postdata( $post ); ?> <li><?php the_title(); ?> <small>&yen;<?php echo $post->price; ?></small></li> <?php endforeach; // テンプレートタグをリセット wp_reset_postdata(); ?> </ul> </section>
キモは meta_query の書き方と、表示する際の $post->price という書き方です。
meta_queryパラメータの値は、 WP_Query::get_posts() の内部で WP_Meta_Query::parse_query_vars() が呼ばれ渡されます。WP_Meta_Queryクラスは3.2から追加されました。上の例のように非常に複雑な条件をわかりやすく記述することができ、高機能ながら全部配列で書くってところがWordPressの利用者層にマッチした仕様じゃないかなぁと思います。詳細はCodexの関数リファレンス/WP_Queryをご参考に。
meta_query の進化はバージョン3.5から WP_User_Query と WP_Comment_Query にも対応したということです。前から内部的には WP_Meta_Query を使ってたんですが、3.5では WP_User_Query のプロパティに $query_vars が追加され、ゲッターとセッターが増えています。WP_Queryと同じですね。
どちらも get_posts, get_users 関数から利用する人が多いと思いますし自分もそうしていますが、なんかこういう変化を見ると、もう直接 new WP_Query, new WP_User_Query して使うほうが推奨される書き方になるのかなぁ?まだここは決めかねております。みなさんはどうしていますか。
もうひとつは $post->price という書き方ですね。WordPressでカスタムフィールドの取得は、このように書くものでした。
get_post_meta( $post->ID, 'meta_key', true);
これがバージョン3.5からは
$post->meta_key
という非常にシンプルな書き方で取得できるようになります。以前はWordPressの投稿データはstdClassだったんですが、3.5からはWP_Postという専用のクラスのインスタンスになります。このWP_PostクラスのなかでPHPのオーバーロードという機能を使っています。でも他の言語のオーバーロードと全然違うのでマジックメソッドと言ったほうが分かりやすい気がします。
これはかなりビッグニュースであると同時に、いいぞもっとやれという感じであります。そりゃこのほうがいいでしょという感じでもあります。個人的には、stdClassに自由にプロパティを追加できるのをいいことに、ループの開始時に
$post->meta_key = get_post_meta( $post->ID, 'meta_key', true);
のようにプロパティにカスタムフィールドの値をセットしてあとで使う、みたいなことをしていたので、ああこれはいいなぁ、でもバージョンアップの際にコード修正しなきゃいかんなぁと思っているところです。こんな風に
WP_Postクラスは今後ぜひサムネイルが取れるようにしていただきたい。wktkしておきます。
ところでWordPressのカスタムフィールドのUIは非常に使いにくい。というか使えない。コイツ↓
そのおかげで Custom Field Template や Advanced Custom Fields, Types, Magic Fields その他のプラグインがあるのですが、データの持ち方をWordPressのカスタムフィールドから拡張しているものもあり、APIもまちまちです。上記の記法が素直に使えるのは Custom Fields Template くらいじゃないかと思います。こういうサードパーティ製のプラグインに頼らず、そこそこ入力しやすいインターフェイスがコアに実装されるのを待っているのですが、なかなか来ないですね。
参考記事
おまけ
つまり”post_date”みたいなキーのカスタムフィールドがあってもそいつは$post->post_dateでは取れないってことですね。 RT @HissyNC: @jim0912 存在しないプロパティが呼ばれたらプロパティ名を__getメソッドに送ります
— Toro_Unit(山の上のとろゆに) (@Toro_Unit) December 5, 2012
@HissyNC @jim0912 $post->{'hoge-hoge'}でハイフン付も一応とってこれました。非推奨かもですけど・・。
— Toro_Unit(山の上のとろゆに) (@Toro_Unit) December 5, 2012
@Toro_Unit @jim0912 その書き方はややこしいので、今後はアンダースコアつなぎで作ればいいってことなのかなぁと。
— Takuro Hishikawa (@HissyNC) December 5, 2012
@Toro_Unit @HissyNC 日本語でも取れるのかしら?W
— まがぞん (@jim0912) December 5, 2012
@HissyNC @jim0912 $post->ほげで取れました・・・・
— Toro_Unit(山の上のとろゆに) (@Toro_Unit) December 5, 2012
@Toro_Unit @HissyNC まじかw
— まがぞん (@jim0912) December 5, 2012