WordPressをカスタマイズするなら覚えておきたいアクションフックとフィルターフック

Posted under - WordPress

26

WordPressのカスタマイズコードでよく見かける add_filter、add_action という関数。これは WordPressのプラグイン API という仕組みを利用したもの。プラグイン API - アクションフックやフィルターフックについて、大雑把ですがまとめてみました。

WordPress

WordPress を使ってWebサイトを作る時、デフォルトの WordPress の動きを変更したいなーという時が多々あります。WordPress のデフォルトの動き(WordPress Codexでは振る舞いという言い方がされています。)でよく知られてるのは、記事を書くと自動的に <p> タグが入る … とかでしょうか。とにかくそういう WordPress の振る舞いを、何とかしたい場合ってありますよね。

こういった WordPress 独特の振る舞いは、WordPress のコアファイルと呼ばれてるところに書かれています。WordPress は PHP で書かれているので、コアファイルを書き換えることだって可能ですよね。でも、コアファイルを変更すると、アップデートの度に書き換えられてしまうし、変にいじって他の部分に影響が出ても大変です!

ではどうすればいいのかというと、WordPress には、コアファイルをいじらずにデフォルトの振る舞いを変更できる仕組みが、ちゃんと用意されているんです。

アクションフックとフィルターフック 目次

  1. プラグインAPI
  2. アクションフックとフィルターフック
    1. アクションて何?
    2. じゃぁフィルターって何?
    3. それがフックとどう関係があるの?
  3. フィルターフックを具体的に見ていこう
    1. the_content にフックされてる関数
    2. add_filter 関数
    3. 何となく分かったけど … 関数の中身がわからないじゃないの …
    4. フィルターフックのフックを削除したいんだけど …
    5. フィルターフックを使って、振る舞いを追加してみよう
  1. アクションフックとフィルターフックはどう違うの?
    1. アクションフックの一例
    2. アクションフックを使ってみよう
    3. アクションフックのフックは削除もできます

1. プラグインAPI

コアファイルをいじらずに、デフォルトの振る舞いを変更できる仕組みが、プラグイン API と呼ばれるもの。WordPress にはたくさんのプラグインがありますよね。そんなプラグインが使えるのも、このプラグイン API という仕組みが用意されてるからなんですね。

プラグイン … そんなの自分で作れないよー!って思うかもしれませんけど、プラグインを作るとか、そういう話ではありません。WordPress Codex のプラグインの作成を見てみると …

WordPress プラグインは PHP 言語で記述された、プログラムないし 1つ以上の関数の集まりであり…

WordPress Codex

となっています。つまり関数一個でも、プラグインって呼んでます。なのでもっと気軽に、プラグイン API というものを見ていきたいと思います!このプラグイン API を使えば、WordPress のデフォルトの振る舞いを変更することができます。

2. アクションフックとフィルターフック

プラグイン API というのを、もうちょっと具体的に見ていきます。まず、WordPress のプラグイン API は、フック(hook)という仕組みになっています。フック … 留め金とかそういう意味ですね。今はこの「フック」という言葉だけ覚えておいてください。

そしてそのフックには、アクションフックフィルターフックという、ふたつの仕組みが用意されています。

2.1. アクションて何?

アクションって何でしょう?WordPress CodexのプラグインAPI には、次のように書かれています。

アクションは、WordPress で発生する特定のイベント、例えば投稿の公開、テーマの変更、管理画面の表示などによって始動させらせます。

WordPress Codex

ちょっと難しいですね … 一例として以下のような時、アクションが始動されるって書いてあります。

  • データベースのデータの変更
  • メールメッセージの送信
  • ブラウザ画面(管理画面もしくは読者が閲覧する画面)に表示する項目の変更

とにかく、記事を書いて公開(データベースに保存)したり、テーマを変更したり、ログインしたり、管理画面を表示するなどを行ったりすると、アクションが始動される …。というのを頭にいれておいてくださいね!

2.2. じゃぁフィルターって何?

アクションよりも、フィルターの方が分かりやすいかもしれません!まず、WordPress は、ブラウザから記事を投稿したり、コメントを投稿したりすると、データベースに記録されていきます。つまり入力するわけですよね。入力する時、ブラウザとデータベースの間には、WordPress のフィルターがあります。

入力時

入力時のフィルター

それに対して、ブラウザに Webサイトを表示する時は、データベースにあるものを探しだして、それを閲覧者に表示します。つまり出力です。この出力のときにも、WordPress のフィルターがあります。

出力時

出力時のフィルター

WordPress のほとんど入出力は、必ず最低ひとつのフィルターを通過するそうです。

例えば冒頭で紹介した WordPress の振る舞いのひとつ、記事を書くと自動的に <p> タグが付く … というのもフィルターを通ってるからです。データベース内のテキストデータには、<p>タグは記録されてませんが、ブラウザに出力する際に、フィルター(<p> タグをつけるフィルター)を通ってくるので、表示されたデータには <p> タグが付いてくる … ということなんです。

Attention

フィルターを通過という言葉がよく出てきますが、実際はフィルターフック(きっかけ)によって実行される関数を通過するという意味です。適当な表現が見つからないので、フィルターと表現していますが ….。混乱させてすいません…。

2.3. それがフックとどう関係があるの?

ここでフックに戻ります。フックとは留め金という意味、つまり何かをひっかけておくものですね。ちょっと無理矢理な説明ですが、アクションやフィルターをきっかけにして、自分で作った関数(プラグイン)を WordPress に実行させる … アクションやフィルターにひっかけて、実行する … ということです!分かりにくくてすいません XD

3. フィルターフックを具体的に見ていこう

何となく、アクションフック、フィルターフックの仕組みが分かってもらえたと思います。それでは実際にどういう風になっているかを、まずはフィルターフックを例にして、具体的に見ていきます。別にプラグインを作るわけではないので、そんなに難しい話ではありませんよ!

まずはさっきも登場した、the_content() 。記事本文を出力するテンプレートタグです。 どんなフィルター(フィルターというか、フィルターフックをきっかけに実行される関数)を通って出力されているのか、を見てみます。

WordPress のデフォルトのフィルターの多くは、コアファイル wp-includes/default-filters.php の中に書かれています。the_content(フィルターフック)に付いてる関数を見てみると、以下のようになっています。

3.1. the_content にフックされてる関数

add_filter( 'the_content', 'wptexturize'        );
add_filter( 'the_content', 'convert_smilies'    );
add_filter( 'the_content', 'convert_chars'      );
add_filter( 'the_content', 'wpautop'            );
add_filter( 'the_content', 'shortcode_unautop'  );
add_filter( 'the_content', 'prepend_attachment' );

いっぱいあるんですねー。add_filter 関数によって、6つも振る舞いが追加されています。add_filter の見方を簡単に説明すると、the_content というフィルターフック(データベースから読み出されてブラウザに出力するとき)に、 wptexturize(1番目) などの関数を実行(フック)するという感じです。

3.2. add_filter 関数

add_filter という関数が出てきました。この関数によって、フィルターフック(上の例では the_content)に関数をフックさせます。

  • 1. add_filter( $tag, $function_to_add, $priority, $accepted_args )

という風にパラメータを渡して使います。

  • $tag(上の例では the_content)- フックしたいフィルターフック名。必須項目です。
  • $function_to_add(上の例では wptexturize など)- 実際に実行したい、フックしたい関数名です。
  • $priority – 実行する順番を指定したいときにつけるパラメータ。整数で指定します。指定しなければ、加えられた順番、上の例だと wptexturize から順番に実行されます。初期値は 10になってます。
  • $accepted_args – 関数が受け取る引数の数です。初期値は 1になってます。

$priority$accepted_args は必須項目ではないので、省略できます。

3.3. 何となく分かったけど … 関数の中身がわからないじゃないの …

上の例では、the_content(フィルターフック)にいろんな関数が、フックされてるのが分かりました。でも、実際どんな内容の関数が定義されてるのかわからないですよね。

例えば、wpautop という関数が、どんなことをしてるのかは分かりません。それを調べるのに、WordPress のコアファイルのあちこちを探しまわるのも大変です。

そんな時に便利なのが、PHP Cross Reference of WordPress というサイト。ここで関数名を検索すると、WordPress のどのコアファイルの何行目かを教えてくれるので、便利です。例えばさっきの関数 wpautop を検索すると…

検索結果

どこに書いてあるか教えてくれる!

という風に、どのファイルの何行目に書いてあるかを教えてくれます。/wp-includes/formatting.php -> line 175 と教えてもらったので、そこを見に行くと、wpautop 関数がありました!

wpautop という関数の中身を見てみると、記事に自動的に <p> タグをつけている関数なんだーと分かります。流れとしては、add_filter( 'the_content', 'wpautop' ); という 1行で、the_content フィルターフックに、wpautop 関数をフック(きっかけにして関数を実行)して、自動で <p> タグをつけて、最終的にブラウザに出力しているという感じです。

3.4. フィルターフックのフックを削除したいんだけど …

デフォルトで設定されている、フィルターフックやアクションフックで実行されてる振る舞いは、削除することもできます。例えば、記事に自動的に <p> タグを挿入するさっきのフィルターを削除する場合は、remove_filter 関数を使います。

1. 自動で<p>タグを削除する
functions.php
<?php remove_filter ('the_content', 'wpautop'); ?>

上記のように functions.php に書いてしまえば、自動で <p> タグを付ける … というフィルターを削除できます。でも functions.php に書くと、全てに適応されるので、特定のテンプレートファイルだけ – 例えば single.php に書くこともできます。

single.php
<?php remove_filter ('the_content', 'wpautop'); ?>
<?php the_content(); ?>

こうすれば、single.php で記事が出力されるとき(フィルターを通るとき)にだけ、<p> タグが付かなくなります。

3.5. フィルターフックを使って、振る舞いを追加してみよう

ここまでは、デフォルトの WordPress の振る舞いについて、フィルターの部分で見てきました。では今度はフィルターフックを使って、新しく振る舞いを追加してみます。

ex-1. post_class

例えば、index.php などのテンプレートで使われている、post_class() というテンプレートタグ(フィルターフック)に、新しく振る舞いを追加してみましょう。post_class はループの中で使い、その記事が post(投稿)、page(固定ページ)、カスタム投稿などによって、自動的にクラスを付けてくれるテンプレートタグです。

ex-index.php
<div <?php post_class(); ?>>

とすると、例えば以下のように出力されます。

  • 1. <div class="post-6385 post type-post status-publish format-standard hentry category-tech tag-gallery tag-jquery">

いっぱいクラスが付きますねー。tech というカテゴリー内の記事だよcategory-tech)とか、jquery というタグが付いた記事だよtag-jquery)というクラスまで付いてきます。

では、この post_class() に、ループの中で一番最初の記事にだけ、firstpost というクラスを付けてみます。ブログのトップページなどで、最新記事だけ CSS でスタイルを変えたいなーという時には使えますよね。

functions.php に以下を追加
function firstpost_class($class) {
	global $post, $posts;
	if ( is_home() && !is_paged() && ($post == $posts[0]) ) $class[] = 'firstpost';
	return $class;
}
add_filter('post_class', 'firstpost_class');

ここまで読んでくれた人は、もうどういう仕組みか分かりますよね!add_filter 関数で、post_class で出力(ブラウザに表示)する時にフックして(きっかけにして)、定義した first_class 関数を実行するという意味です。

ex-2. the_excerpt

次の例は、記事の抜粋を表示(出力)する the_excerpt()。デフォルトの振る舞いでは、抜粋の最後に、[…] といういらない(?)文字が付いてきちゃいます。なので、この振る舞いを変更したいなーとなるわけです。

いらない文字列 [...]

functions.php に以下を追加
function new_excerpt_more($more) {
	return '';
}
add_filter('excerpt_more', 'new_excerpt_more');

これもさっきのと同じです。定義した関数を、フィルターフックをきっかけにして実行しています。こういう例は、他にもいくつか過去記事:WordPressのfunctions.phpに書いておくといいかもしれないコードいろいろの中で紹介しています。


今回は the_contentpost_classthe_excerpt を例にしてますが、他にもたくさんのフィルターフック(きっかけ)があります。もうちょっとこうしたいんだけどなー … というテンプレートタグがあったら、以下のリンクに掲載されているか確認してみてください。

ここに掲載されているものは、add_filter 関数を使って、振る舞いを追加することができます!

4. アクションフックとフィルターフックはどう違うの?

フィルターフックは、入力、出力の途中に設けられたフィルターを通るときをきっかけにする … という感じでした。ではアクションフックはというと …

アクションは、WordPress で発生する特定のイベント、例えば投稿の公開、テーマの変更、管理画面の表示などによって始動させらせます。

WordPress Codex

ということでした。ちょっと漠然としすぎて分かりにくいので、逆にどんなアクションフックがあるのかを見てみたいと思います。WordPress Codex の、プラグインAPI/アクションフック一覧を見てみると、見覚えのある関数がたくさんあります。

4.1. アクションフックの一例

  • get_header
  • wp_head
  • wp_enqueue_scripts
  • wp_print_styles
  • wp_print_scripts
  • get_sidebar
  • get_search_form
  • get_footer
  • wp_footer
  • wp_print_footer_scripts

上記はほんの一部ですが、get_header や、get_footer は、テンプレートファイルの中で必ず使っている関数ですね。また、wp_headwp_footer も、テンプレートファイルの中で使われています。テンプレートファイルが読み込まれたときなどにも、アクションフック(きっかけ)として使えるということですね!

4.2. アクションフックを使ってみよう

一般的に配布されているプラグインなどを作るときは、ユーザーの行動、例えば投稿の公開、テーマの変更、管理画面の表示などをきっかけにして、関数を実行したいこともあります。でも、普通に WordPress をカスタマイズするくらいなら、あんまり必要ないですね。

逆に wp_headwp_footerwp_print_scripts などのアクションフックの方は、結構使えますね!私がよく functions.php の中に書いている、アクションフックを使った例をいくつかご紹介します。

em-1. wp_print_scripts を使って、Javascript を一元管理
if(!is_admin()){
function register_script(){
  wp_register_script('example1', get_bloginfo('template_directory').'/js/example1.js');
  wp_register_script('example2', get_bloginfo('template_directory').'/js/example2.js');
  wp_register_script('example3', get_bloginfo('template_directory').'/js/example3.js');
}
function add_script(){
  register_script();
  wp_enqueue_script('example1');
  wp_enqueue_script('example2');
    if(is_page('gallery')){
      wp_enqueue_script('example3');
    }
}
add_action('wp_print_scripts','add_script');
}

wp_print_scripts は、<head> 内に、登録した Javascript を出力する直前に実行するアクションフックです。

上記では、wp_register_script で Js ファイルを登録しておいて、wp_enqueue_script で一回整理整頓、最後に wp_print_scripts で出力しています。

管理ページでは必要ないファイルなので、if(!is_admin()) {}で囲んでいます。途中、条件分岐で jsファイルを読み込みたいページを限定したりもできるし、管理がらくちんです。

wp_print_scripts の代わりに、wp_print_footer_scripts を使えば、<head> 内じゃなくて、フッターの方に出力してくれます。

ex-2. wp_print_styles を使って、ページによってCSSを読み込む
function add_my_stylesheet() {
  wp_register_style('gallery', get_bloginfo('template_directory') . '/css/gallery.css');
  if(is_page('gallery')){
    wp_enqueue_style( 'gallery');
  }
}
add_action('wp_print_styles', 'add_my_stylesheet');

これも Javascript の管理と同じ要領で、CSS を管理してます。wp_register_stylewp_enqueue_stylewp_print_styles と、関数がさっきと違うので注意してください。

4.3. アクションフックのフックは削除もできます

フィルターフックのところでも削除がありましたけど、アクションフックのフックも削除できます。フィルターフックのときと、要領は同じです。remove_filter 関数の代わりに、remove_action 関数を使います。

ex-1. WordPressのバージョン表示を削除
remove_action('wp_head','wp_generator');

上記では wp_head にフックされている、wp_generator を削除しています。wp_generator 関数は、WordPress のバージョンを <meta> タグで出力する関数です。

  • 1. <meta name="generator" content="WordPress 3.1.3" />

↑ こんな風に。必要ないから削除しちゃいます。

ex-2. リビジョン機能を無効にする
remove_action('pre_post_update', 'wp_save_post_revision' );

こうすると、リビジョン機能(編集履歴を保存する機能)を無効にします。

5. 最後に

WordPress をカスタマイズするのに、ちょっと便利なプラグイン API – アクションフックやフィルターフックについて、かなり大ざっぱですが見てきました。

プラグイン API を使ったコードは、いろんなブログなどで紹介されています。コピペして使うのも、もちろんアリだと思いますが、こんな風な仕組みで動いてるんだーということが分かると、もっと WordPress のカスタマイズが楽しくなるかも!

プラグイン API と聞くと、プラグインを作る為のもので、ちょっとテーマをいじるくらいなら関係ないかなー … と思ってしまいがち。アクションフック、フィルターフックなどの仕組みも、分かってしまえば簡単なことだけど、文章で読むと難しいですねー。

アクションフックやフィルターフック、覚えれば WordPress をより柔軟にカスタマイズできるようになるので、ぜひ覚えたい仕組みですね!

Comments

Thank you for the comment.