最近ブログに書こうと思ってるネタが溜まってばかりで、じゃあ古いネタから潰すかと思ってこの記事だ。

Jetpackを導入した記事」の頃に書こうと思ったネタだから、ネタ帳の更新日時が11月上旬だったのも頷ける。

あーそんな頃から溜まってるんだあ、あははは……いや笑えない。

ということで、今回は多機能プラグイン「Jetpack」のアクセス解析機能を「特定のページのみ」などの条件に応じて無効化する方法を探求してみた。

なぜそんなことをするのか

俺はサイトやブログを弄るとき、いわゆる「本番サーバー」上でテストしている。それはテストではなくぶっつけ本番という。

本当はローカルにテスト用のサーバーを構築すればいいのだが。というかそうすべきだが。

で、テスト用のページを各種取り揃えているのだが、テストのためそこに繰り返しアクセスしたときに、無駄にアクセスカウンターが回ってしまうのは避けたい。

いわゆる「管理者のアクセスは除外」ってことをしたい。

それで、アクセスカウンター(外部サービスから画像を読み込んでいる)は簡単に無効化できたが、WordPressプラグインを使っているアクセス解析だとまた違った対策が必要となる。

つまり、解析用のJavaScriptをプラグイン側が読み込むのを止めなければならない。

もしくは除外機能を使うか。

「SlimStat」プラグインには除外機能が充実しているが、残念ながらJetpackには除外機能が見当たらない。

管理者のアクセスだけは(有無を言わさず)除外されるが。

調べてみても「アクセス解析機能だけを」、「特定のページだけで」無効化する方法が見つからなかった。

それならば、自力でなんとかするほかあるまい……と、俺は再びプラグインのソースコードを紐解くのだった。

wp_footer() からアクションを除去

アクセス解析のためのコードはHTMLのフッター部分に挿入されているので、だいたいの当たりをつけて探す。

幸いなことに、俺もだんだんプラグインのソースを読むのに慣れてきたので、プラグインディレクトリ内をgrepし、該当の関数が wp_footer アクションにフックされていることを突き止めた。

ということで、これを remove_action() する。

なお、 wp_footer() 関数より前に remove_action() すること。

<?php
if ( $nocount && function_exists('stats_footer') ) remove_action( 'wp_footer', 'stats_footer', 101 );
wp_footer();
?>

こんな感じでOK。

$nocount 変数には、アクセス解析を無効にしたい場合は true 、そうでない場合は false を代入しておく。

なお、念のため function_exists() により関数の存在チェック(=プラグインの有効化チェック)をしているが、本当に必要かどうかは知らない。

アクセス解析を無効にする条件の判定については、例えばこんな感じ。

<?php
if ( is_singular() ) {
    $post_meta = get_post_meta(get_the_ID());
    if ( isset($post_meta['nocount'][0]) ) {
        $nocount = true;
    }
} else {
    $nocount = false;
}
?>

特定のページ(記事、固定ページ)を除外するには、除外したい投稿に「nocount」などというキーでカスタムフィールドを作っておき、上のコードの3行目のように取得し、4行目のように判定すればよい。

管理者によるアクセスを除外するのは、Jetpackでは標準でそうなるので、条件分岐関数 is_super_admin() などは必要ない。

……なんだ、思ったより簡単じゃないか。

wp_head() からもアクションを除去

罠だった。

なんと、これだけでは無効化できていなかったのだ。

実際にページのソースを見てみると、フッター付近のコードは消えたが、かわりにHTMLソースの末尾、なんと </html> よりも後にコードを挿入しているではないか!

もちろんHTMLの文法違反だが、Webブラウザは寛大なので、ちゃんと動いてくれる。

Webブラウザの親切につけ込んで、なんという悪事を……

という冗談は置いといて、おそらくテーマファイルに wp_footer() を書き忘れてるうっかりさんのための救済措置なのだろうが。

テーマ作者ならそんな初歩的なミスくらい自分で対処すればいいじゃん……

むしろ、知識があってカスタマイズしようとする人の邪魔をプラグインがするなんて、けしからん。

と思ったのは俺だけだろうか。

じゃあ、あんなところにコードを挿入する奴は誰だ!? と探してみると、見つかった。

その関数は shutdown アクションにフックされている。

ところが、まだ終わりではなかった。

フックされている関数を辿ってみると、これは wp_head アクションにフックされた関数によってフックされていたのだ。

えっと、どういうことかというと、「 shutdown アクションに関数Aをフックする」という関数Bが wp_head アクションにフックされている――なんだそれ?

いったい誰がこんなややこしいことを考えたんだ。

……と愚痴を言っても仕方ないので、面倒事は根本から断つことにする。

<?php
if ( function_exists('stats_add_shutdown_action') ) remove_action( 'wp_head', 'stats_add_shutdown_action' );
wp_head();
?>

このように、 wp_head アクションから remove_action() する。

こちらも、 wp_head() 関数よりも先に remove_action() すること。

なお、こちらのコードについては条件の判定は不要だ。ゴミを取るだけだから。

ちなみに、以上のコードをテーマ関数ファイル(functions.php)に書きたいと思う人がいるかもしれないが、テーマ関数の実行時点では上記の方法で「特定の条件」を判定できないようなので、コードには工夫が必要になる。

まとめ

wp_footerwp_head の両方のアクションフックから関数を remove_action() する。

Jetpackが予想以上に親切「すぎる」おかげで手間取ってしまったが、最終的に希望通りのことを実現できたし、結果オーライだ!

結果オーライじゃなかったら記事にしない可能性が濃厚だけど。

ということで、Jetpackプラグインのアクセス解析機能を制御したい場合にはぜひ参考にしてね!