WordPressはURLパラメータによって記事を抽出することができます。
たとえば、以下のようにURLパラメータだけでpre_get_postsのフィルターフックを書いたときのような処理を行うことが可能です。
記事IDが20の記事を表示する
http://example.jp/?p=20
hogeというタグが追加された記事を表示する
http://example.jp/?tag=hoge
ただ、カスタムフィールドの内容で記事を抽出するmeta_queryやタクソノミーに対するtax_queryなどは、そのままでは行うことができません。
そこでURLパラメータを取得してmeta_queryなどの記事抽出を可能とする仕組みがカスタムクエリです。
カスタムクエリについてはWordPress Codexが詳しいです。
カスタムクエリ – WordPress Codex 日本語版
ADs
たとえば、記事に「’camera’,’f’,’mm’,’ss’,’strobo’,’iso’」というカスタムフィールドがあったとして、その内容によって記事を抽出したい場合を考えてみます。
必要な処理としては
1.カスタムフィールドのキーがURLパラメータとして認識されるようにする
2.そのURLパラメータ有りでアクセスされた場合、meta_queryによる記事抽出を行う。
という2点が必要です。
最低限必要な処理は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//追加したいカスタムクエリ一覧 function query_list(){ $arr = array( 'camera','f','mm','ss','strobo','iso' ); return $arr; } //クエリとして動作するようにする function add_meta_query_vars( $public_query_vars ) { foreach(query_list() as $val){ $public_query_vars[] = $val; } return $public_query_vars; } add_filter( 'query_vars', 'add_meta_query_vars' ); //上記追加したクエリが存在した時の記事抽出 function meta_search_query($query) { if ( is_admin() || ! $query->is_main_query() ) return; foreach(query_list() as $val){ $query_val = $query->get($val); if($query_val){ $query->set('meta_query', array( array( 'key' => $val, 'value' => $query_val ) ) ); } } } add_action( 'pre_get_posts', 'meta_search_query'); |
functions.phpにこのように書いておけば、以下のURLでカスタムフィールドに「camera:canon」「f:2.8」「mm:50」というものを持つ記事の一覧が表示されます。
http://example.jp/?camera=canon&f=2.8&mm=50
このままでも便利に使えるのですが、カスタムクエリを追加した際には以下のような関数やフックも追加しておくとさらに使い勝手が良くなります。
追加したカスタムクエリが含まれたクエリかどうかを判定します。
1 2 3 4 5 6 7 8 9 10 |
//query_list()で定義しておいたクエリが含まれているとtrue function is_meta_query(){ global $wp_query; $query_vars = $wp_query->query_vars; foreach(query_list() as $val){ if(array_key_exists($val,$query_vars)){ return true; } } } |
body_class()関数はそのとき表示されている記事によって様々なクラスを出力してくれる便利な関数ですが、カスタムクエリについてはクラスが付加されるなどの処理は行われません。そのままだと不便なのでクラス追加や削除などを行うといいでしょう。
以下の例はカスタムクエリ有りの場合は「meta」というクラスを追加し、同時に「home」クラスを削除します。
前述の
http://example.jp/?camera=canon&f=2.8&mm=50
のようなURLの場合、扱いとしてはトップページとなります(is_home()はtrueになります)。
ただ、カスタムクエリが含まれた場合はどちらかというとアーカイブとして扱ってほしいことのほうが多いのではないかと思いますので、その点を考慮して「home」を削除しました。
1 2 3 4 5 6 7 8 9 10 |
function meta_body_class($class){ if(is_meta_query()){ $class[] = 'meta'; if(($key = array_search('home', $class)) !== false) { unset($class[$key]); } } return $class; } add_filter('body_class','meta_body_class'); |
カスタムクエリが存在する場合でもis_home()がtrueと判定されますので、読み込まれるテンプレートもhome.php(frontpage.phpやindex.phpの可能性もありますが)となります。
そこをカスタムクエリがある場合はarchive.phpを読むように変更します。
1 2 3 4 5 6 7 8 9 10 |
function custom_template($template){ global $wp_query; foreach(query_list() as $val){ if($wp_query->get($val)){ $template = dirname( __FILE__ ) . '/archive.php'; } } return $template; } add_filter( 'home_template', 'custom_template' ); |
※トップページがhome.phpではない場合は「frontpage_template」や「index_template」へのフィルターフックになる場合もあります。
カスタムクエリは使いこなすと複雑な検索を必要とするポータルサイトやカタログサイトなどの構築に大変便利です。
個人レベルでも大規模なサイト構築も夢ではないので、ぜひ挑戦してみてください。
ADs