WordPress 3 のタクソノミークエリをショートコードで使える文法を考えてみた

かねて使っている自作のショートコードで、投稿の一覧を出力するというものがあるのだが、そのショートコードの中でタクソノミークエリを使いたくなったので、その方法を考えてみた。

タクソノミークエリは、query_postsとかに食わせる文法で、タクソノミーで振り分ける時の文法。

使い方は、

$args = array(
	'tax_query' => array(
		'relation' => 'AND',
		array(
			'taxonomy' => 'movie_janner',
			'field' => 'slug',
			'terms' => array( 'action', 'commedy' ),
		),
		array(
			'taxonomy' => 'actor',
			'field' => 'id',
			'terms' => array( 103, 115, 206 ),
			'operator' => 'NOT IN',
		)
	)
)
query_posts( $args );

てな感じで使う。

これをショートコードの引数としてショートコード関数に渡し、タクソノミークエリを生成するというのが狙い。

ショートコードの中ではホワイトスペースと=が要注意キャラクタだ。
なので、これらを使わずにタクソノミーANDとか使う文法を考えていたら次のようなものに落ち着いた。

AND(movie_janner->slug(action,comedy)&actor->id(103,115,206);operator->NOT_IN)

解析するコードは以下の用な感じでどうか。

$str = 'AND(movie_janner->slug(action,comedy)&actor->id(103,115,206);operator->NOT_IN)';
$str = str_replace('->', '=>', $str);
if (preg_match('/^(.*?)\x28(.*?)\x29$/', $str, $matches)) {
 $args = array('relation'=>$matches[1]);
 foreach(explode('&',$matches[2]) as $t) {
  if ($t) {
   $a = array();
   foreach( explode(';',$t) as $p) {
    $p = explode('=>',$p);
    if (preg_match('/^(.*?)\x28(.*?)\x29$/', $p[1], $m)) {
     $a['taxonomy'] = $p[0];
     $a['field'] = $m[1];
     $a['terms'] = explode(',',$m[2]);
    }
    else {
     $a[$p[0]] = ($p[0] == 'operator') ? str_replace('_', ' ', $p[1]) : $p[1]; // amendment maybe needed in the future
    }
   }
   $args[] = $a;
  }
 }
}

echo('<pre>');
print_r($a);
echo('</pre>');

Leave a Reply