Blog

WordPressのデフォルトの検索をカスタマイズする

Posted by admin at 8:17 日時 2011/06/29

公式フォーラムに上がってた質問から、WordPressのデフォルトの検索をカスタマイズする方法を調べてみました。WordPressにはSQLクエリをカスタマイズするためのフィルターフックが用意されているので、それを使います。

たとえば、検索対象にスラッグ(post_name)を含めるというカスタマイズを考えてみます。何もカスタマイズしていない状態で「hello-world」(インストール時に作られるHello World!という投稿のスラッグ)で検索した場合、このようなクエリが発行されます。

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND (((wp_posts.post_title LIKE ‘%hello-world%’) OR (wp_posts.post_content LIKE ‘%hello-world%’))) AND wp_posts.post_type IN (‘post’, ‘page’, ‘attachment’) AND (wp_posts.post_status = ‘publish’ OR wp_posts.post_author = 1 AND wp_posts.post_status = ‘private’) ORDER BY wp_posts.post_date DESC LIMIT 0, 10

デフォルトでは、投稿のタイトル(wp_posts.post_type)と本文(wp_posts.post_content)のみが検索対象になっているのが分かります。このクエリを改造して、スラッグ(wp_posts.post_name)も検索対象に追加します。そのコードが以下です。

function post_name_search_where( $where, $obj ) {  global $wpdb;  if ( $obj->is_search ) {  $where = preg_replace(  "/\(\s*$wpdb->posts\.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",  "($wpdb->posts.post_title LIKE $1) OR ($wpdb->posts.post_name LIKE $1)", $where );  }  return $where;  }  add_filter( 'posts_where', 'post_name_search_where', 10, 2 );

正規表現で(wp_posts.post_title LIKE ‘%hello-world%’)という部分を探してきて、(wp_posts.post_title LIKE ‘%hello-world%’) OR (wp_posts.post_name LIKE ‘%hello-world%’)に置き換えています。if文でこの置換は検索時にしか有効にならないようにしています。

このコードはwp_postsテーブルの中で検索対象を追加する場合で、カスタムフィールドなど、別のテーブルを検索対象にする場合はposts_joinフィルターも併用する必要があります。詳しくはCodexのCustom Queriesのページを参考にしてください。

この記事を作成するに当たって、 @jim0912 さんに色々情報をいただきました。ありがとうございます。


Share this entry