Search Meterが集計する検索キーワードをWebサイト上に表示する。空白文字対策もしてみる

  • 更新日:
  • 公開日:

WordPressのサイト内検索を解析してくれるプラグイン「Search Meter」には、集計したデータをWebサイトに表示するテンプレートタグが2つ用意されています。

コレを使用し、集計された検索キーワードをWebサイトに表示してみます。

Search Meterが集計する検索キーワードを表示する

テンプレートタグはsm_list_popular_searches()sm_list_recent_searches()です。両者とも「最近検索に引っ掛かったキーワードを5つ、リンク付きのリスト型で表示する」点は同じですが、前者のsm_list_popular_searches()はこれを人気順に並べて表示します。以下のようにテンプレートに貼り付けると、

<h1>すごい人気の検索キーワード</h1>
<?php my_sm_list_popular_searches(); ?>

リスト型で出力されます。

<h1>すごい人気の検索キーワード</h1>
<ul>
    <li><a href="検索結果へのリンク">検索ワード1</a></li>
    <li><a href="検索結果へのリンク">検索ワード2</a></li>
    <li><a href="検索結果へのリンク">検索ワード3</a></li>
    <li><a href="検索結果へのリンク">検索ワード4</a></li>
    <li><a href="検索結果へのリンク">検索ワード5</a></li>
</ul>

このテンプレートタグには3つ引数があって、第一引数、第二引数にはリスト型(ulタグ)を囲む前後のラッパー要素を指定、第三引数で検索ワードの表示数を指定できます。例えばこのように引数に渡すと、

<h1>やばい人気の検索キーワード</h1>
<?php my_sm_list_popular_searches( '<div>', '</div>', 3 ); ?>

出力結果はこうなります。第一、第二引数で渡したdivタグで囲まれ、第三引数で渡した数だけ表示されるようになりました。

<h1>やばい人気の検索キーワード</h1>
<div>
    <ul>
        <li><a href="検索結果へのリンク">検索ワード1</a></li>
        <li><a href="検索結果へのリンク">検索ワード2</a></li>
        <li><a href="検索結果へのリンク">検索ワード3</a></li>
    </ul>
</div>

sm_list_recent_searches()も引数は同様のようですね。

あと、もしSearch Meterを無効化、アンインストールした場合この関数が使えなくなりエラーが起きます。その時のために関数が定義済みか判定する関数を使って回避しておきます。

//こうすればプラグインが無効化されてもエラーが起きないので安心
if (function_exists('sm_list_popular_searches')) {
    sm_list_popular_searches();
}

空白の検索結果が順位に含まれているとキーワードが空欄になる問題

と、ここまではプラグインの作者様の記事『Search Meter: a WordPress plugin « Semicolon』を参考にしました。しかし実際に使ってみて気になったのですが、WordPressの検索機能は空白でも検索結果を出せるためSearch Meterが集計してしまうんですね。例えば人気順に空白の検索が含まれていたらこんな風になります。

やばい人気の検索キーワード</h1>
<div>
    <ul>
        <li><a href="検索結果へのリンク">検索ワード1</a></li>
        <li><a href="検索結果へのリンク"></a></li> <!-- ここが空欄 -->
        <li><a href="検索結果へのリンク">検索ワード3</a></li>
    </ul>
</div>

空白による検索が上位に食い込んでいるとリンクのテキストが空欄になってしまうんですね。これでは不格好になりますが、修正できるようなフックは関数に仕込まれていませんでした。なので、関数をコピーして少し修正し、名前を変えて使うことにしました。

function my_sm_list_popular_searches($before = '', $after = '', $count = 5) {
// List the most popular searches in the last month in decreasing order of popularity.
    global $wpdb, $wp_rewrite;
    $count = intval($count);
    $escaped_filter_regex = sm_get_escaped_filter_regex();
    $filter_term = ($escaped_filter_regex == "" ? "" : "AND NOT `terms` REGEXP '{$escaped_filter_regex}'");
    // This is a simpler query than the report query, and may produce
    // slightly different results. This query returns searches if they
    // have ever had any hits, even if the last search yielded no hits.
    // This makes for a more efficient search -- important if this
    // function will be used in a sidebar.
    $results = $wpdb->get_results(
        "SELECT terms, SUM(`count`) AS countsum
 FROM `{$wpdb->prefix}searchmeter`
 WHERE DATE_SUB( CURDATE( ) , INTERVAL 30 DAY ) <= `date`
 AND 0 < `last_hits`
 {$filter_term}
 GROUP BY `terms`
 ORDER BY countsum DESC, `terms` ASC
 LIMIT $count");
    if (count($results)) {
        echo "$before\n<ul>\n";
        $home_url_slash = get_settings('home') . '/';
        foreach ($results as $result) {
            if ( $result->terms ) {
                echo '<li><a href="'. $home_url_slash . sm_get_relative_search_url($result->terms) . '">'. htmlspecialchars($result->terms) .'</a></li>'."\n";
            }
        }
        echo "</ul>\n$after\n";
    }
}

修正した箇所は25~27行目で、検索ワードが空欄だった場合に表示しない処理をしています。関数名は「sm_list_popular_searches」に「my」を付けて「my_sm_list_popular_searches」としています。これをfunctions.phpに貼り付けて同じように使用できます。(Search Meterを無効化したい場合は先にこの関数を削除しておかないとエラーが起きるので注意です)


ただ、これでも少し問題があります。もし空白キーワードがあった場合、第三引数で指定した数から1個減った数でキーワードがリスト表示されてしまうんですね。でもこれ以上修正するとなると大変なのでこの点は妥協することにしました。

書いた人

Symbol Mark

Ryoichi(しつ)

除菌ティッシュを買い込んで使いきれずによく乾かす人。

療養目的で退職し、どうやって生きていくか模索中。最近は勉強目的でLaravelやVue.js弄ったり、趣味で音で遊んでます。

※2019年10月16日現在ブログリニューアル中です。崩れなどが発生していたらすみません。

うぇぶ: @s_ryone