サイト内検索の結果から特定の記事を除外する方法

全般

今回はWordPressでサイト内検索を行った際、検索結果から特定のカテゴリーやタグを含む記事や固定ページを除外する方法を紹介したい。

この設定を行うことで、プロフィールや雑記帳のような重要度が低い記事までもが表示されてしまう現象を防ぐことができる

WordPressのサイト内検索がなんでも調べてしまう問題

WordPressには、Webサイト内のコンテンツを調べてくれる機能がある。

しかし、デフォルトの状態ではサイト内のすべての記事を表示してしまう欠点が存在する。

例えば、検索フォームに「私」と打って検索をかけてみよう。もちろん「あ」とか「い」でもなんでもいい。そして、結果を見てみるとどうだろうか?

投稿した記事からプロフィールやプライバシーポリシーなどの固定記事まで、なんでもかんでも表示されているはずだ。

このように、WordPressの検索の仕組みはかなり精度が低く、本来は検索結果に表示する必要のないページまですべて表示してしまう。

これをなんとかしたいのだ。

PHPコードで簡単修正!

さて、それではこの問題の解決に取り組みたい。

WordPressではfunctions.php」ファイルに簡単なPHPコードを入力するだけで、検索結果の表示をあるていど自由にコントロールすることが可能だ。

今回、解説に使用しているWordPressテーマはCocoonである。

ダウンロードはこちらから行うことができる。

テーマのための関数 (functions.php)」ファイルを編集する画面の開きかたも解説しておきたい。

まず管理者画面を開き、左側のサイドバー内にある「外観」にマウスカーソルを合わせ展開したら「テーマエディター」をクリックする。

テーマの編集」画面に入ったらおそらく「スタイルシート (style.css)」が表示されているはずなので、右側のテーマファイルのバーから「テーマのための関数 (functions.php)」をクリックしよう。

この画像が画面に表示されているだろうか?

また、現在開いているfunctions.phpファイルが子テーマのものであるかどうかも確認しよう

子テーマであれば画像のようなダイアログが表示される

事前確認:WordPressのIDって何?

このカスタマイズでは、「カテゴリID」「タグID」「記事ID」の三つを使用する

これらが何か、どこに表示されているのかを手短に説明する。

カテゴリIDが書かれている場所

とりあえず、WordPressを導入したときに最初から存在している「Uncategorized」を例に説明する。

まずは、管理者画面に入り、左側のサイドバーから「投稿」にカーソルを合わせて「カテゴリー」をクリックする。

「カテゴリー」画面に入ったら、右側に登録されているカテゴリーの一覧が表示されるので、カーソルを合わせてみよう。そしたら、このように「編集 | クイック編集 | 表示」と表示されるはずだ。

このうちの「編集」をクリックしよう。

そして、「カテゴリーの編集」画面に入ったらブラウザの上に表示されているURLに注目してほしい。

上の画像の矢印の場所がわかっただろうか?

あなたのドメイン名/wp-admin/term.php?taxonomy=category&tag_ID=1&post_type=post&wp_http_referer=%2Fwp-admin%2Fedit-tags.php%3Ftaxonomy%3Dcategory

そう、カテゴリー編集画面のURLの中にある「category&tag_ID=1」の「1」がカテゴリーIDとなっている。

他のカテゴリーのIDも同様にしてすぐ見つけることができる。

タグIDが書かれている場所

上に書いたカテゴリーIDの見つけ方と変わらない。

ただし、「post_tag&tag_ID=数字」となっているので注意。

こちらも「ID=」に続く数字がタグIDとなる。

記事IDが書かれている場所

記事のIDが書いてある場所は簡単に見つけることができる。

投稿・固定記事のIDが知りたい場合は、いつも通り管理者画面から記事の一覧ページに入ってほしい。そして、非表示にしたい記事を探し「編集」を押してその記事の編集画面に入ろう。

そして、先ほどカテゴリーIDの確認方法で説明したように、ブラウザのリンクに注目しよう。

あなたのドメイン名/wp-admin/post.php?post=1&action=edit

これは、「Hello world!」の編集画面のURLである。赤で強調した「post=1」の「1」が記事IDになる。

おそらく、Cocoonを含め最近のWordPressテーマは、記事の編集画面に入らなくとも投稿した記事の一覧画面に記事IDが表示されているものが多いはずだ。

このため、記事IDは比較的簡単に知ることができる。


以上でIDの説明を終える。

以降は、サイト内検索の制御をカスタマイズするPHPコードの解説をやっていく。

特定のカテゴリの投稿記事を表示したくないとき

あるカテゴリに属している記事をすべて表示したくない場合は、このPHPコードを使おう。

PHPコード
// 検索結果から特定のカテゴリを除外するコード
function mycus_search_filter_cat_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $cat_id = array( '検索結果から除外したいカテゴリのID' );
        $query->set( 'category__not_in', $cat_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_cat_func' );

上記のコードで除外したいカテゴリを指定することができる。

使用例

例えば、「A」というカテゴリのIDが「10」だとする。

PHPコード
// 検索結果から特定のカテゴリを除外するコード
function mycus_search_filter_cat_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $cat_id = array( '10' );
        $query->set( 'category__not_in', $cat_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_cat_func' );

上のコードのように入力しよう。


「A」と「B」のふたつのカテゴリを同時に除外したいとする。カテゴリIDはそれぞれ「10」と「20」だ

PHPコード
// 検索結果から特定のカテゴリを除外するコード
function mycus_search_filter_cat_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $cat_id = array( '10', '20' );
        $query->set( 'category__not_in', $cat_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_cat_func' );

このように、複数のカテゴリを除外するときは「‘(アポストロフィー)」で括り「,(コンマ)」記号で繋いだらよい。

注意点

カテゴリを除外するコードに親カテゴリのIDを入力しても、その親カテゴリに属する子カテゴリは何の問題もなく表示される

このため、このコードを使ってひとつのカテゴリ全体を非表示にしたい場合は、子カテゴリや孫カテゴリのIDもひとつひとつ入力する必要がある

特定のタグが付いた投稿記事を表示したくないとき

あるタグが付いた記事を検索結果に表示したくない場合は、このPHPコードを使おう。

PHPコード
// 検索結果から特定のタグを除外するコード
function mycus_search_filter_tag_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $tag_id = array( '検索結果から除外したいタグのID' );
        $query->set( 'tag__not_in', $tag_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_tag_func' );

上記のコードで除外したいタグを指定することができる。

使用例

例えば、「C」というタグのIDが「30」だとする。

PHPコード
// 検索結果から特定のタグを除外するコード
function mycus_search_filter_tag_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $tag_id = array( '30' );
        $query->set( 'tag__not_in', $tag_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_tag_func' );

上のように入力しよう。


「C」と「D」というふたつのタグが付いた記事を検索結果から除外したいとする。タグIDはそれぞれ「30」と「40」だ

PHPコード
// 検索結果から特定のタグを除外するコード
function mycus_search_filter_tag_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $tag_id = array( '30', '40' );
        $query->set( 'tag__not_in', $tag_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_tag_func' );

このように、「‘(アポストロフィー)」で括ったタグIDを「,(コンマ)」で区切って並べたらよい。

注意点

このコードでは、指定したタグが付いている記事はすべて非表示になる

つまり、タグを複数付けている記事が存在する場合は気を付けなければならない。

固定記事を表示したくないとき

規約やポリシー、お問い合わせ、プロフィール、サイト概要などの固定ページを検索結果に表示したくない場合は、このコードを入力しよう。

PHPコード
function mycus_search_filter_post_only_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $query->set( 'post_type', 'post' );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_post_only_func' );

上記のコードで固定記事がサイト内検索に表示されることを防ぐことができる。

なおPHPコードが読める人は理解できると思うが、このコードはすべての固定記事を除外しているのではなく、投稿記事のみに制限する仕組みになっている。

ただ、結局は同じ結果になるので気にしなくてよい。

特定の投稿・固定記事を表示したくないとき

全部の固定記事を非表示にしたいわけではない、またはある特定の投稿記事だけを非表示にしたい。

そんなときはこのコードを使おう。

PHPコード
// 検索結果から個別に記事を除外するコード
function mycus_search_filter_each_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $post_id = array( '検索結果から除外したい記事のID' );
        $query->set( 'post__not_in', $post_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_each_func' );

上記のコードを使うことで、除外したい記事を個別に設定することができる。

使用例

それでは試しにやってみよう。

WordPressを導入したときにあらかじめ最初に投稿されている「Hello world!」を非表示にしたいとする。記事IDはもちろん「1」だ

PHPコード
// 検索結果から個別に記事を除外するコード
function mycus_search_filter_each_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $post_id = array( '1' );
        $query->set( 'post__not_in', $post_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_each_func' );

上のように入力しよう。


ついでに、固定記事の「Sample Page」も非表示にしてみたい。こちらも同じく最初から投稿済みになっている記事だ。

「Hello world!」と「Sample Page」、記事IDはそれぞれ「1」と「2」だ

PHPコード
// 検索結果から個別に記事を除外するコード
function mycus_search_filter_each_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $post_id = array( '1', '2' );
        $query->set( 'post__not_in', $post_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_each_func' );

こちらも記事のIDを「‘(アポストロフィー)」で括って、それを「,(コンマ)」で区切って並べていくだけとなる。

解説

投稿記事も固定記事もIDは共通して順番に割り振られていくので、投稿記事専用のIDや固定記事専用のIDというものは存在しない。

ただ、同時に別に付与される属性によって、「post(投稿記事)」か「page(固定記事)」かに区別される。

PHPコードまとめ

さて、ここまでサイト内検索の結果を制御するPHPコードを見て、ピンと来た人もいるかもしれない。

カテゴリとタグと記事のコードは、下のようにひとつにまとめることができる。

PHPコード
// 検索結果からカテゴリ・タグ・特定の記事を除外するコード
function mycus_search_filter_func( $query ) {
    if ( $query->is_search() && $query->is_main_query() && ! $query->is_admin() ) {
        $cat_id = array( '検索結果から除外したいカテゴリのID' );
        $tag_id = array( '検索結果から除外したいタグのID' );
        $post_id = array( '検索結果から除外したい記事のID' );
        $query->set( 'category__not_in', $cat_id );
        $query->set( 'tag__not_in', $tag_id );
        $query->set( 'post__not_in', $post_id );
    }
    return $query;
}
add_filter( 'pre_get_posts', 'mycus_search_filter_func' );

使い方は簡単で、先ほど個別に説明したやり方と変わらない。それぞれ除外したいもののIDを入力していけばよい。

最後に

今回説明したカスタマイズはとても単純なものなので、おそらくなにか別のコードやプラグインと競合することはないだろう。

ただしPHPファイルを編集するので、場合によってはエラーを引き起こしWebサイトが真っ白になってしまう可能性も無いとは言えない。

そのときは一度コピペしたコードを消し、なにか手違いが起きてないか冷静に確認することを心掛けてほしい。


今回は、プラグインを使用せずにWordPressのサイト内検索を制御する方法を解説した。

きっかけは検索周りをテストしていると固定ページも結果に表示されていることに気が付いたので、それが気になったのだ。そして、ついでにカテゴリやタグ、そして記事を個別に制御する方法も考えたいなと思った。

PHPコード自体はいくつかのWebサイトを参考にしてみたものの、どうにもタグの除外は間違ったコードが出回っていたのでそれを自分でなんとかする必要があった。結局、「not_in」のクエリで統一したほうがぱっと見わかりやすいことに気が付き、コードの修正にそこそこ時間がかかってしまった。

結果的には満足のいく仕上がりになった。また、プラグインを使用しないのでWebサイトの肥大化も抑えることができたと思う。

この記事が役に立てば嬉しい。