Snow Monkey をカスタマイズするためにも、フックについて覚えよう

本記事では、WordPress の基礎仕様の1つ「フック」について、簡単な基礎を解説します。

最初に

WordPressのカスタマイズ、または Snow Monkey をカスタマイズを何も解らずにやってみると、何から理解すれば良いのか解らない為に、難しいと感じて挫折する場合もあるかもしれません。しかし、それは WordPress に存在する、「フック」と言う基礎の仕組みについて理解をしていないからかもしれません。

フックってなんだろう?

小学館のデジタル大辞泉では、「フック」の意味を次のように公開されています。

フック【hook】

1. 鉤 (かぎ) 。鉤形の留め金。衣服の合わせ目を留める金具。
2. 物を引っ掛けるための器具。鉤。

出典:デジタル大辞泉(小学館)

本記事で取り扱う WordPress の「フック」という用語は、2番目の意味に由来しています。

WordPress は、基礎となる多くの特定の処理が実行される時に対応しているフックに仕掛けられた処理(コールバック関数)を呼び出すと言った柔軟な設計をされているウェブシステムでもあります。WordPress の場合は、 「物を引っ掛ける = 特定の処理に処理を引っ掛ける」と言う意味合いでフックと言う用語を使われています。

ケミ

WordPress のフックとは、WordPress 本来の特定の処理とは別に、特定の処理をした時に、引っ掛けた処理を呼び出す仕組みと言う感じです。

Snow Monkey テーマでも、様々なフックが用意されています。例えば、テンプレートの読み込み処理には snow_monkey_get_template_part_<slug>snow_monkey_template_part_render と言ったフックが定義されています。

少し、次に図を用意してみました。

ケミ

WordPress本来の処理で各テンプレートを読み込まれた時に、Snow Monkey テーマでは snow_monkey_get_template_part_<slug> と定義されているフックの処理をします。また、各テンプレートの表示結果を出力する時には snow_monkey_template_part_render と定義されているフックの処理をします。

テネーブル

上の図のようにフックを使うことで、WordPress 本来の処理の結果を、フックで指定した別の処理の結果に変更することができるのです。

フックを使うと可能なこと一例

例えば…

  • 検索フォームを表示する時に実行されるフックに追加して、検索ボックスの下に検索条件を表示する
  • 時間表示をする時のフックに追加して、時間のフォーマットを和暦に書き換える
  • お問い合わせフォームの入力チェック処理内に用意されているフックに追加して、入力間違いのエラー表示を変更する

こんな風に、様々な処理を行う時に用意されているフックに追加することで、特定の箇所の表示や条件を思いのままに変更することが可能なのです。

ケミ

フックで追加するのは、関数。つまり、処理の集合体です。ここではフックで追加している関数を、コールバック関数と呼ぶことにします。

テネーブル

例えば、WordPress の標準では検索フォームを表示する場合に、get_search_form と定義されているフック名があります。その get_search_form に対して「検索条件の選択フォームを表示する」と言うコールバック関数を指定して追加することで、検索フォームを表示する処理が実行された時に「検索条件の選択フォームを表示する」と言ったコールバック関数も同時に実行されます。その仕組みによって「Not Wiz Search Criteria」では、検索フォームに検索条件のフォームを追加しています。

ルミェール

コールバック関数と言うのは、プログラマの方やゲームを改造した事のある方であれば、サブルーチン、または処理トリガー、パラサイトルーチンのアタッチコールと言う仕組みをイメージすれば解りやすいかも?少し仕組みは違うけど、ニュアンスは一緒な感じ。

フックの種類は2つ!

WordPressワードプレス のフックには、アクションフックフィルターフックと呼ばれる2種類が存在します。

アクションフック

WordPress が動作を行う特定の処理に対して、アクションフックが定義されている場合は、定義に対して登録を行っているコールバック関数も同時に処理されます。アクションフックの場合は return で値を返却しません。大抵のケースでは、追加でフック内の処理結果を表示させたりすると言った使い方をされます。

フィルターフック

WordPress が動作を行う特定の処理に対して、フィルターフックが定義されている場合は、定義に対して登録を行っているコールバック関数も同時に処理されます。フィルターフックの場合は、return で値を返却できます。場合によって、コールバック関数の return で返却された値が本来の処理の値の代わりとして使用されます。

フックの追加方法

テネーブル

フック処理を追加すると言うのは、特定の処理が実行された時に実行されるコールバック関数を仕掛けると言うことです。

アクションフックの場合の追加方法

テネーブル

add_action 関数を使用します。

詳しい説明は後述しますが、まずはコードをご確認ください。

add_action(
  <追加を行うフック定義名>,
  <フックを処理するコールバック関数名>,
  <追加する優先度(デフォルトは10 / 省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / 省略可能)>
);

function <フックを処理するコールバック関数名> ( <特定処理から渡される引数> ) {
  <コールバック関数の処理>
}

フィルターフックの場合の追加方法

ルミェール

add_filter 関数を使用するよ。

詳しい説明は後述するので、まずはコードを確認してね。

add_filter(
  <追加を行うフック定義名>,
  <フックを処理するコールバック関数名>,
  <追加する優先度(デフォルトは10 / デフォルトの場合は省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / デフォルトの場合は省略可能)>
);

function <フックを処理するコールバック関数名> ( <特定処理から渡される引数> ) {
  <コールバック関数の処理>
  return <返却値>;
}

それぞれの追加に関する説明

追加を行うフック定義名には、特定の処理が実行された時に実行されるフックの定義名を記述します。上記にも記載していましたが、WordPress の標準では検索フォームを表示する場合に、get_search_form と定義されているフック名があります。get_search_form を定義名で記述した場合は、検索フォームを表示する場合に実行されるフックを追加となります。

フックを処理するコールバック関数名は、実際の処理を行うコールバック関数の関数名を記述します。もし、クラス内の関数を使用したい場合には array( クラスのインスタンス変数, 'コールバック関数の関数名' ) と言ったように配列で記述することで使用可能です。

フックを追加する優先度は、それぞれのフック定義の特定の処理が実行された時に対して、数値を大きい方が先に実行される処理として登録されます。デフォルトや省略時には 10 で登録されます。
アクションフックでは、別に登録されるフックより先に実行したい場合は優先度の数値を大きくし、別に登録されるフックより後に実行したい場合は優先度の数値を小さくして使用します。
フィルターフックでは、最初に実行されたフック処理の値のみが使用される場合もある為、優先度の数値を大きくすればするほど、実行される順序が先となる可能性が高くなる事から優先度を 9999(またはPHP_INT_MAX)などの最大数値を使用することで、強制的にそのフックの返却値で実行させると言ったことも可能です。
アクションフックやフィルターフックに関わらず、中には一番優先度が高いフック処理のみしか動作しない場合もあります。その際には、実行される順序を別に登録されるフックより優先的に動作させる為にも、優先度を比較的に高い数値で設定して追加されていることが多いです。

特定処理から渡される引数の数は、各フックの定義で決まっている特定処理から渡される引数の数を数値で記述します。例えば、admin_bar_menu と言うフック定義では管理バーの項目の参照配列が渡されるようになっています。その場合は引数は1つなので 1 と記述します。またはデフォルトや省略時には 1 で登録されますので、その場合であれば省略しても問題ありません。

コールバック関数の関数は、関数名を追加する際に記述する関数名で記述し、引数も特定処理から渡される引数としてください。また、フィルターフックの場合には値を返却する必要があります。その場合も仕様が決まっています。WordPress の標準のフックであれば、詳しい仕様は WordPress のフック一覧などに載っています。

アクションフック一覧 – WordPress Codex 日本語版
フィルターフック一覧 – WordPress Codex 日本語版

フックの削除方法

追加されているフック処理は、削除することも可能です。
特定の時には追加したフック処理を処理したくないと言う場合は、追加されているフック処理を削除することで対応可能です。

アクションフック処理を削除するのは remove_action 関数が用意されています。まず、記述のみご確認ください。

remove_action(
  <削除を行うフック定義名>,
  <追加されたコールバック関数名>,
  <追加された優先度(デフォルトは10 / デフォルトの場合は省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / デフォルトの場合は省略可能)>
);

フィルターフック処理を削除するのは remove_filter 関数が用意されています。まず、記述のみご確認ください。

remove_filter(
  <削除を行うフック定義名>,
  <追加されたコールバック関数名>,
  <追加された優先度(デフォルトは10 / デフォルトの場合は省略可能)>,
  <特定処理から渡される引数の数(デフォルトは1 / デフォルトの場合は省略可能)>
);

どちらの関数も、使い方はほぼ同一で、フックの追加時の引数にもよく似ています。この記述のみで追加したフックを削除できます。

しかし、ここでフック追加時と異なり、気をつけなければならないことがあります。それは、削除を行う為には追加されたコールバック関数名が必要と言うことです。その為、フックの削除は無名関数で追加されている処理に対してできません。

ケミ

この仕様から、フックを追加する場合には、削除されると動作に影響する大切な処理などの場合、無名関数を使用して削除できなくするのも1つの有効手段ですね。

フックの種類が不明な場合の対応方法

ここまでフックの種類は2種類と解説し、追加や削除について解説も行いました。しかし、記述したいフックの定義が アクションフックフィルターフック なのかどのように理解すれば良いのかも不明です。

その場合は、まずは気にせずに フィルターフック としてコードを記述しましょう。フィルターフックアクションフック として動作することはできませんが、アクションフックフィルターフック として追加した場合は、値を処理しない フィルターフック と言うように処理を行われる為です。

ブリエ

え?どう言う事ですか?アクションフック なのに フィルターフック で動作するのでしょうか?

テネーブル

そうです。このことは WordPress のコアに記述されている add_actionfunction の動作を見てみると良く解ります。wp-includes/plugin.php に書かれています)

ブリエ

add_filterreturn されていますね。

テネーブル

そうです。このことから アクションフック と言うのは、値を返却しない フィルターフック と言っても良いですよね。

ルミェール

だから、わからない場合や慣れていない場合は、フィルターフック で追加するのも間違いじゃなくて、1つの正解と思おう。間違いを気にせず、気軽にコードを記述することは上達の早道だよ!

テネーブル

WordPress 本体の更新などで、アクションフック だった処理が フィルターフック の処理に変更されていたことも過去にいくつかありました。その為に、古くからのプラグインには故意に アクションフックフィルターフック の追加方法で書かれているも存在します。実は、フックの種類と言うのは大きく気にすることではありません

また、アクションフック は、追加と同様に、WordPress の内部では return remove_filterとして処理されています。その為、フィルターフック と同じように remove_filter と書いても削除することが可能です。

まずは、追加だけで慣れていこう

ブリエ

なかなか一度に覚えられませんね。

テネーブル

最初のうちは慣れるまで少し難しいですよね。

しかし、フックの削除は、削除する場合にのみ使うものですので、削除しない場合は使わなくても大丈夫です。まずはフックの追加だけでも覚えてみるのも良いと思います。やっていくうちに、少しずつ慣れていくことで何となく理解が進みます。

慣れたらリファレンスも読んでみよう

フックの細かい仕様については、WordPress のリファレンスサイトなどでも解説されています。そちらも参考にしてみてください。

add_action の関数リファレンス(日本語版)
add_filter の関数リファレンス(日本語版)
remove_action の関数リファレンス(日本語版)
remove_filter の関数リファレンス(日本語版)

この記事の筆者

Kmix39(ケミ)

電子の妖精。当ウェブサイトの記事制作などを行なっています。
金融・不動産・医療・教育などの数々の業種のシステム開発を経験を積み、スマートフォンアプリケーションと WordPress などのウェブアプリケーションを日々勉強中。