WordPress Logo WordPress のフック(Hooks)

更新日:2019年07月18日

作成日:2019年01月18日

フック(Hook)とは?

日本語版 Codex の「プラグイン API」によると以下のように書かれています。

WordPress はプラグインを WordPress 本体に “引っ張り込む (hook into)” ためのフックを提供しています。これはつまり、特定のタイミングでプラグインの関数を呼び出したり、それによってプラグインを作動させたりするためのものです。

フックとは WordPress がページを表示する特定のタイミングで何らかの処理を実行するためのイベントトリガー(処理を実行させるきっかけ)と言えます。

フックを使うと WordPress の処理の一部を変更したり、何らかの処理を追加したりすることができます。

例えば、jQuery ならイベントが発生した場合、登録してあるイベントリスナを使って何らかの処理をするように、WordPress では WordPress がページを表示する処理の特定のタイミングでそのフックに登録した関数を使って何らかの処理をすることができます。

WordPress では、予め様々な処理のタイミングでフックが用意されています。このフックに独自の関数を登録しておくと、そのフックのタイミングで WordPress がその関数を呼び出すので、処理を追加したり変更したりすることができるようになっています。

フックには「アクションフック」と「フィルターフック」の2種類があります。

アクションフック

WordPress の特定の処理のタイミングで「何らかのアクション(関数)」を実行するためのフックです。アクションフックに関数をフック(登録)するには add_action() 関数を使います。

詳細:アクションフック

フィルターフック

WordPress がテキスト関連の処理をする際に、そのテキストの内容を変更(フィルター)するためのフックです。言い換えると、WordPress がデフォルトで行うテキスト処理を変更する場合に使用します。フィルターフックに関数をフック(登録)するには add_filter() 関数を使います。

詳細:フィルターフック

参考サイト:

アクションフック

アクションフックは、WordPress の特定のタイミングで「独自の関数」を使って何らかの処理を実行するための仕組みです。

例えば、記事が保存された時、公開された時、ページが初期化された時、プラグインが読み込まれた時などの様々なタイミングで処理を実行することができます。

WordPress には特定のタイミングで独自のアクションを追加するための多数のアクションフックが予め設置(用意)されています。

また、WordPress の関数にはアクションフックを使って特定のタイミングで実行しなければうまく動作しない関数もあります。

アクションフックに対して関数を登録するには、add_action() 関数を使用します。

アクションフックは WordPress コアファイル(やテーマ、プラグイン)が do_action() を呼び出すときにトリガー(実行)されます。

以下は公式サイトの関連ページです。

アクションフックの仕組み

通常は WordPress が予めコアファイルに設置(用意)されているアクションフックを利用することがほとんどだと思いますが、ここでは独自のアクションフックを設置してみます。

アクションフックは do_action() が記述されている場所で実行されるので、この例ではテーマのフッターに以下のような独自のアクションフックを記述します。

<footer>
  <!-- my_footer_action_hook と言う名前のアクションフックを設置 -->
  <?php do_action( 'my_footer_action_hook' ); ?>
</footer>

functions.php に、設置したアクションフックで実行したいアクション(処理=関数)を add_action() を使って登録(フック)します。

add_action() の第一引数には「アクションフックの名前」を、第二引数には「フックするする関数名」を指定します。

また、第二引数に指定した関数(この例の場合は、単純に文字列を出力する関数)を定義します。

これで設置したアクションフックにより、my_footer_echo() が実行されてフッターに「This is my action hook!」と出力されます。

//functions.php
//アクションの登録
add_action( 'my_footer_action_hook', 'my_footer_echo' );
//実行するアクションの定義
function my_footer_echo(){
  echo 'This is my action hook!';
}

第二引数に関数名ではなく、以下のように直接関数を記述して関数名を省略することもできます。(但し、この無名関数を使えるのは remove_action() を使って解除する必要がない場合のみです。)

add_action( 'my_footer_action_hook', function(){
    echo 'This is my action hook!';
});

アクションフックには処理(関数)を複数登録できるので、以下のように2つ登録すると、フッターには「This is my action hook! This is my action hook #2! 」と出力されることになります。

add_action( 'my_footer_action_hook', 'my_footer_echo' );
function my_footer_echo(){
    echo 'This is my action hook!';
}

add_action( 'my_footer_action_hook', 'my_footer_echo2' );
function my_footer_echo2(){
    echo 'This is my action hook #2!';
}

前述の例では、テーマのフッター部分に直接 do_action() を記述しましたが、関数の中に do_action() を記述することもできます。

以下の例は、functions.php に my_footer_echo() と言う関数を定義して、その中に do_action() を記述してアクションフックを設置しています。

my_footer_echo() の中身は、 do_action( 'my_footer_echo' ) のみで、my_footer_echo と言うアクションフックを設置しているだけです。

function my_footer_echo(){
  do_action( 'my_footer_echo' );
}

続いて、functions.php に my_footer_echo アクションフックに登録する関数を定義して、add_action() で登録します。

//アクション関数をフック my_footer_echo に登録
add_action( 'my_footer_echo', 'my_footer_link_top' );
function my_footer_link_top(){ //実行するアクションの定義
  echo '<a href="#">Top</a><br>';
}

//アクション関数をフック my_footer_echo に登録
add_action( 'my_footer_echo', 'my_footer_link_cat' );
function my_footer_link_cat(){ //実行するアクションの定義
  echo '<a href="cat.php">Cat</a><br>';
}

フッターに以下を記述すると、アクションフックにより my_footer_link_top() と my_footer_link_cat() が実行され、リンクが出力されます。

<p><?php my_footer_echo(); ?></p>

<!-- 以下が出力されます。-->
<a href="#">Top</a><br>
<a href="cat.php">Cat</a><br>

WordPress が設置しているアクションフックの例

WordPress が予め設置しているアクションフックは多数あります。そのうちの1つ「wp_head」と言うアクションフックは wp_head() と言うテンプレートタグ(関数)に記述されています。

以下は「wp-includes/general-template.php」に記述されている wp_head() の定義部分です。

定義されているのは、do_action( 'wp_head' ) のみでアクションフックを実行するだけです。

/**
 * Fire the wp_head action. (wp_head アクションを発火させる)
 *
 * See {@see 'wp_head'}.
 *
 * @since 1.2.0
 */
function wp_head() {
  /**
   * Prints scripts or data in the head tag on the front end.
   *
   * @since 1.5.0
   */
  do_action( 'wp_head' );
}

デフォルトで登録されているアクションは wp-includes/default-filters.php で確認することができます。以下は wp_head アクションフックに登録されている一部です。WordPress では、これらのフックを使ってスタイルやスクリプト、タイトルタグ、リンクなどを出力しています。wp_head() が実行されると、これらのアクション(及びユーザーが登録したアクション)が実行されることになります。

// Actions
add_action( 'wp_head', '_wp_render_title_tag',            1     );
add_action( 'wp_head', 'wp_enqueue_scripts',              1     );
add_action( 'wp_head', 'wp_resource_hints',               2     );
add_action( 'wp_head', 'feed_links',                      2     );
add_action( 'wp_head', 'feed_links_extra',                3     );
add_action( 'wp_head', 'rsd_link'                               );
add_action( 'wp_head', 'wlwmanifest_link'                       );
add_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
add_action( 'wp_head', 'locale_stylesheet'                      );
・・・省略・・・

wp-settings.php に記述されている do_action()

WordPress コアの設定ファイルの1つ wp-settings.php には、以下のような do_action() が記述されています。

//wp-settings.php に記述されている do_action() の抜粋
/* Fires once all must-use and network-activated plugins have loaded. */
do_action( 'muplugins_loaded' );
・・・
/* Fires once activated plugins have loaded. */
do_action( 'plugins_loaded' );
・・・
/* Fires before the theme is loaded. */
do_action( 'setup_theme' );
・・・
//Load the functions for the active theme(functions.php の読み込み)
if ( ! wp_installing() || 'wp-activate.php' === $pagenow ) {
  if ( TEMPLATEPATH !== STYLESHEETPATH && file_exists( STYLESHEETPATH . '/functions.php' ) )
    include( STYLESHEETPATH . '/functions.php' );
  if ( file_exists( TEMPLATEPATH . '/functions.php' ) )
    include( TEMPLATEPATH . '/functions.php' );
}
 
/* Fires after the theme is loaded */
do_action( 'after_setup_theme' );
・・・
/*
Fires after WordPress has finished loading but before any headers are sent.
Most of WP is loaded at this stage, and the user is authenticated. 
WP continues to load on the {@see 'init'} hook that follows (e.g. widgets), and many plugins instantiate themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.).
If you wish to plug an action once WP is loaded, use the {@see 'wp_loaded'} hook below.
 */
do_action( 'init' );
・・・
/*  This hook is fired once WP, all plugins, and the theme are fully loaded and instantiated. */
do_action( 'wp_loaded' );

add_action フックに登録

アクションに対して関数を登録します。いろいろな言い方があるようで、以下はどれも同じ意味です。

  • アクション(フック)に関数を追加します。
  • アクションに関数をフックします。
  • アクションをフックします。
  • フックにアクション(関数)を追加します。など

add_action( $hook, $function_to_add, $priority, $accepted_args )

パラメータ
  • $hook(文字列):(必須) 登録するアクションフック名
  • $function_to_add(コールバック):(必須)フックする関数名(アクションが発生した時に呼び出される関数名)。WordPress の関数の名前と重なると(同じ場合)エラーになります。
  • $priority(整数):(オプション)同じフックに複数の関数が登録されている場合の優先順位。数値が小さいほど早く実行され、同じ数値の場合は追加された順に実行される。省略時(初期値)は 10 です。
  • $accepted_args(整数):(オプション)フックした関数が受け入れられる引数の数。フックした関数は、対応する do_action() あるいは apply_filters() が実行される時に、余分に引数を取ることができます。(初期値:1)
戻り値
常に true

add_action() のソース

以下がこの関数の定義部分で、この関数は add_filter() のエイリアスになって、単に add_filter() を実行してその結果(常に true)を返しています。

//wp-includes/plugin.php
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
  return add_filter($tag, $function_to_add, $priority, $accepted_args);
}

add_filter() の定義は以下のようになっています。

まだ、そのフックが存在しない場合は WP_Hook クラスのインスタンスを生成してグローバル変数 $wp_filter に代入し、登録する関数を $wp_filter[ 'フック名' ] に追加しています。

すでにそのフックが存在する場合は、登録する関数を $wp_filter[ 'フック名' ] に追加しています。

//wp-includes/plugin.php
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
  global $wp_filter;
  if ( ! isset( $wp_filter[ $tag ] ) ) {
    $wp_filter[ $tag ] = new WP_Hook();  //$tag はフックの名前
  }
  $wp_filter[ $tag ]->add_filter( $tag, $function_to_add, $priority, $accepted_args );
  return true;
}

do_action() や apply_filters() では、$wp_filter に登録されたフックを実行するようになっています。

別の言い方をすると、グローバル変数 $wp_filter には登録されたアクションやフィルターが入っています。(登録されているアクションとフィルター

書式

以下のような使い方をします。

アクションが発生した際に実行される処理を独自のコールバック関数で定義します。

「優先順位」と「引数の数」はオプションです。

function コールバック関数() {
  //アクションが発生した時の処理
}
add_action( フック名, コールバック関数名, 優先順位, 引数の数 );

以下のように add_action() はコールバック関数の定義の前に記述しても問題ありません。

add_action( フック名, コールバック関数名, 優先順位, 引数の数 );
function コールバック関数() {
  //アクションが発生した時の処理
}

使用例

以下は、add_action() を使って「wp_head」アクションフックに add_google_analytics() と言う独自の関数を登録する例です(functions.php に記述します)。

この関数はユーザーがログインしていない場合のみ Google Analytics のコード(5行目~13行目)を出力する関数です。

「wp_head」にフックしているので <head> 内に出力されます。「wp_footer」にフックすれば </body> 終了タグの前に出力されます。

add_action('wp_head','add_google_analytics');
function add_google_analytics() {
  if( !is_user_logged_in() ) {  //ユーザーがログインしていない場合
  ?>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-xxxxxxxxxxx', 'xxxxxx.com');
    ga('require', 'displayfeatures');
    ga('send', 'pageview');
  </script>
  <?php 
  }
}

以下は wp_enqueue_scripts と言うアクションフックを使って JavaScript ファイルを読み込む例です。

add_action() を使って「wp_enqueue_scripts」アクションフックに add_my_scripts() と言う関数を登録しています。wp_enqueue_script() は、指定したスクリプトを登録し出力用のキューに入れる関数です。

詳細は「CSSやJavaScriptファイルの読み込み」を参照ください。

function add_my_scripts() {
  wp_enqueue_script( 
    'base-script', 
    get_theme_file_uri( '/js/base.js' ), 
    array( 'jquery' ), 
    '20190123', 
    false
  );
}
add_action('wp_enqueue_scripts', 'add_my_scripts');

do_action フックを実行

add_action() で登録されたアクションフックを実行します。

アクションフックは do_action() により実行されます。別の言い方をすると、do_action() が記述されている場所がアクションフックが実行されている場所となります。

do_action( $tag, $arg )

パラメータ
  • $tag(文字列):(必須) 実行したいアクションフックの名前
  • $arg(mixed):(オプション) フックに登録された関数へ渡す引数を文字列または配列で指定。省略時は ''(空)。
戻り値
なし

remove_action フックを削除

特定のアクションフックに登録されている関数を除去します。※フックを除去するには、$function_to_remove と $priority 引数がフックが追加されたときと一致する必要があります(除去に失敗した時に警告は出ません)。

remove_action( $tag, $function_to_remove, $priority, $accepted_args )

パラメータ
  • $tag(文字列):(必須) 除去する関数がフックしているアクションフック
  • $function_to_remove(文字列):(必須) 除去する関数名
  • $priority(整数):(オプション) (関数がフックされる時に定義される)関数の優先度(初期値: 10)
  • $accepted_args (整数):(オプション) 関数が受け入れる引数の数(初期値: 1)
戻り値
関数が除去されたかどうかの真偽値(成功:true/失敗:false)

WordPress では、自動的に head 内に以下のようなタグが出力されます。これらは wp_head アクションフックに登録されている関数により出力されています。

<!-- emoji SVG images(絵文字画像)DNS プリフェッチ -->
<link rel='dns-prefetch' href='//s.w.org' />

<!-- 絵文字を使うための <script> と <style> の出力 -->
<script type="text/javascript">
  window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/11.2.0\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/11.2.0\/svg\/"
  ・・・省略・・・
  ,function(){"complete"===b.readyState&&c.readyCallback()})),g=c.source||{},g.concatemoji?f(g.concatemoji):g.wpemoji&&g.twemoji&&(f(g.twemoji),f(g.wpemoji)))}(window,document,window._wpemojiSettings);
</script>
<style type="text/css">
img.wp-smiley,
img.emoji {
  display: inline !important;
  border: none !important;
  box-shadow: none !important;
  height: 1em !important;
  width: 1em !important;
  margin: 0 .07em !important;
  vertical-align: -0.1em !important;
  background: none !important;
  padding: 0 !important;
}
</style>

<!-- REST API のリンク(URL)の出力 -->
<link rel='https://api.w.org/' href='http://siteurl.com/wp-json/' />

<!-- EditURI:外部ブログ投稿(編集)ツールを使用するのに必要なリンク -->
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://siteurl.com/xmlrpc.php?rsd" />

<!-- wlwmanifest:Windows Live Writer(ブログ投稿ソフト)を使用するのに必要なリンク -->
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://siteurl.com/wp-includes/wlwmanifest.xml" /> 

<!-- WordPress バージョン -->
<meta name="generator" content="WordPress 5.0.3" />

<!-- 短縮形URL(サイトURL/?p=記事番号) ショートリンク -->
<link rel='shortlink' href='http://www.example.com/?p=146' />

<!-- 埋め込み(oEmbed/Embed)機能に必要なリンク -->
<link rel="alternate" type="application/json+oembed" href="http://www.example.com/wp-json/oembed/1.0/embed?url=http...." />
<link rel="alternate" type="text/xml+oembed" href="http://www.example.com/wp-json/oembed/1.0/embed?url=http...format=xml" />
<!-- 以下は body 閉じタグの前 -->
<script type='text/javascript' src='http://www.xxx.com/wp/wp-includes/js/wp-embed.min.js?ver=4.9.8'></script>

これらの機能を使用していない(必要ない)場合には、remove_action を使ってアクションフックを解除することで出力を止めることができます。

// 絵文字の DNS プリフェッチ用リンクを出力しない
add_filter( 'emoji_svg_url', '__return_false' );  //この場合はフィルターフックを利用
  
// 絵文字を使うためのスクリプトとスタイルを出力しない
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');

// REST API URL を出力しない
remove_action('wp_head','rest_output_link_wp_head');

// EditURI を出力しない
remove_action( 'wp_head', 'rsd_link' );

// wlwmanifest を出力しない
remove_action( 'wp_head', 'wlwmanifest_link' );

// WordPress のバージョン情報の出力をしない
remove_action( 'wp_head', 'wp_generator' );

// 短縮形 URL(rel='shortlink')ショートリンクを出力をしない 	
remove_action('wp_head', 'wp_shortlink_wp_head');

// oEmbed 機能に必要なリンクを出力をしない
remove_action('wp_head','rest_output_link_wp_head');
remove_action('wp_head','wp_oembed_add_discovery_links');
remove_action('wp_head','wp_oembed_add_host_js');

// feed 出力をしない.
remove_action( 'wp_head', 'feed_links', 2 );
remove_action( 'wp_head', 'feed_links_extra', 3 );

DNS プリフェッチ用リンクに関しては「head 内に出力される DNS プリフェッチを全て非表示に」も参照ください。

アクションフックの一覧

WordPress のコアファイルにどのようなアクションフックがあるかは「アクションフック一覧」に掲載されていてます(実行順序の大体の目安もわかります)。以下は一例です(実行順序は正確でない可能性があります)。

アクションフックの例
フック名 実行されるタイミング
after_setup_theme 有効なテーマの functions.php ファイルが読み込まれた直後(通常、テーマ設定・オプションを初期化するために使われる)
init WordPress のコアの読み込みが終了し、HTTPヘッダを出力する前
wp_loaded WordPress が完全に読み込まれた後
admin_init 管理画面各ページの最初、ページがレンダリングされる前
pre_get_posts クエリが実行される前(メインクエリを変更
wp WP オブジェクトが設定された後
template_redirect テーマのテンプレートファイルを振り分ける(どのテンプレートを読み込むかを決定する)直前。
wp_enqueue_scripts JavaScript やスタイルシートがキューに入れられた時(CSSやJavaScriptファイルの読み込み
wp_head wp_head() 関数を呼び出したとき
wp_footer wp_footer() 関数 を呼び出したとき
add_meta_boxes 投稿編集画面が読み込まれた際
save_post 投稿や固定ページが作成または更新されたとき
publish_post 投稿が公開された際、または編集されてステータスが「公開済み」に変わった際

また、wp-includes/default-filters.php を見るとどのようなアクションフック(やフィルターフック)があるかを確認することができます。

//default-filters.php 一部抜粋
// Theme
add_action( 'wp_loaded', '_custom_header_background_just_in_time' );
add_action( 'wp_head', '_custom_logo_header_styles' );
add_action( 'plugins_loaded', '_wp_customize_include' );
add_action( 'transition_post_status', '_wp_customize_publish_changeset', 10, 3 );
add_action( 'admin_enqueue_scripts', '_wp_customize_loader_settings' );
add_action( 'delete_attachment', '_delete_attachment_theme_mod' );
add_action( 'transition_post_status', '_wp_keep_alive_customize_changeset_dependent_auto_drafts', 20, 3 );

// Calendar widget cache
add_action( 'save_post', 'delete_get_calendar_cache' );
add_action( 'delete_post', 'delete_get_calendar_cache' );
add_action( 'update_option_start_of_week', 'delete_get_calendar_cache' );
add_action( 'update_option_gmt_offset', 'delete_get_calendar_cache' );

// Author
add_action( 'transition_post_status', '__clear_multi_author_cache' );

// Post
add_action( 'init', 'create_initial_post_types', 0 ); // highest priority
add_action( 'admin_menu', '_add_post_type_submenus' );
add_action( 'before_delete_post', '_reset_front_page_settings_for_post' );
add_action( 'wp_trash_post',      '_reset_front_page_settings_for_post' );
add_action( 'change_locale', 'create_initial_post_types' );

// Post Formats
add_filter( 'request', '_post_format_request' );
add_filter( 'term_link', '_post_format_link', 10, 3 );
add_filter( 'get_post_format', '_post_format_get_term' );
add_filter( 'get_terms', '_post_format_get_terms', 10, 3 );
add_filter( 'wp_get_object_terms', '_post_format_wp_get_object_terms' );

// KSES
add_action( 'init', 'kses_init' );
add_action( 'set_current_user', 'kses_init' );

// Script Loader
add_action( 'wp_default_scripts', 'wp_default_scripts' );
add_action( 'wp_enqueue_scripts', 'wp_localize_jquery_ui_datepicker', 1000 );
add_action( 'admin_enqueue_scripts', 'wp_localize_jquery_ui_datepicker', 1000 );
add_action( 'admin_print_scripts-index.php', 'wp_localize_community_events' );
add_filter( 'wp_print_scripts', 'wp_just_in_time_script_localization' );
add_filter( 'print_scripts_array', 'wp_prototype_before_jquery' );
add_filter( 'customize_controls_print_styles', 'wp_resource_hints', 1 );

add_action( 'wp_default_styles', 'wp_default_styles' );
add_filter( 'style_loader_src', 'wp_style_loader_src', 10, 2 );

// Taxonomy
add_action( 'init', 'create_initial_taxonomies', 0 ); // highest priority
add_action( 'change_locale', 'create_initial_taxonomies' );

// Canonical
add_action( 'template_redirect', 'redirect_canonical' );
add_action( 'template_redirect', 'wp_redirect_admin_locations', 1000 );

// Shortcodes
add_filter( 'the_content', 'do_shortcode', 11 ); 

wp-includes フォルダ内で「do_action」や「apply_filters」で検索してみるとどのファイルにどのフックがあるかなどがわかります。

以下のサイトでは過去のバージョンごとの全てのフックや非推奨になったフックなどが掲載されています。

フィルターフック

フィルターフックは WordPress の処理の途中で、出力する内容をカスタマイズしたい場合に使われる仕組みのことで、データがデータベースへ追加されたりブラウザに出力される前に、データが通過(フィルタリング)する関数を指定して、データをカスタマイズすることができます。

フィルターフックは必ず「値(データ)を受け渡しする」という点で機能的にアクションフックと異なります(アクションフックでも参照のためにデータの受け渡しがある場合もありますが)。

WordPress には多数のフィルターフックが用意されていて、ほとんどの入力と出力は最低ひとつのフィルターを通過するようになっています。

フィルターフックは、apply_filters() 関数を使って適用され、言い換えると、WordPress ではほとんどの値が apply_filters() 関数を経由して出力されます。

フィルターフックに関数を登録するには、add_filter() 関数を使用します。

フィルターフックを利用するおおまかな手順は以下になります。

  1. functions.php にデータをフィルタリング(カスタマイズ)する関数を作成
  2. add_filter() を使って作成した関数をフィルターフックに登録(WordPress のフィルタにフック)

以下は公式サイトの関連ページです。

フィルターフックの仕組み

通常は WordPress が予めコアファイルに設置(用意)されているフィルターフックを利用することがほとんどだと思いますが、ここでは独自のフィルターフックを設置してみます

この例では、文字列を引数に取り、その文字列に「My text: 」を先頭に追加して返す関数 my_template_tag() を作成し、その関数でフィルターフックを利用できるようにします。

フィルターフックは、apply_filters() を使って適用されるので、以下のように文字列 $text を返す際に apply_filters() を使って返す文字列を変更できるような仕掛けを作っておきます。(3行目)

apply_filters() の第一引数には「フィルターフック名」を指定するので、ここでは独自のフィルターフックとして「my_filter_hook」を指定します。

第二引数には「(第一引数で指定した)フィルタフックに登録された関数が変更できる値」を指定するので、ここでは「My text: 」を先頭に追加した文字列「$text」を指定します。

function my_template_tag($text) {
  $text = "My text: " . $text;
  return apply_filters( 'my_filter_hook', $text );
}

この時点で、コンテンツ中で以下のように記述すると「My text: test」と出力されます。

まだ、設置したフィルターフック「my_filter_hook」にコールバック関数(フィルターが適用される際に実行される関数)を登録していないので、出力される値は元の関数で定義したままの状態です。

<p><?php echo my_template_tag("test"); ?></p>
<!-- My text: test と出力される -->

次にコールバック関数 my_filter_callback() を作成し、add_filter() を使ってこの関数を登録します。

my_filter_callback() は受け取った文字列を strtoupper() で大文字に変換し、先頭に「Hello ! 」と言う文字列を追加して返す関数です。

add_filter() は第一引数には「フィルターフック名」を指定し、第二引数には「フィルターが適用される時に呼び出される関数名」を指定します。

また、add_filter() で登録するコールバック関数は、フィルターフックを設置した元の関数の引数と戻り値が同じ型でなければなりません。

function my_filter_callback($text) {
  return "Hello ! ". strtoupper($text);
}
add_filter('my_filter_hook', 'my_filter_callback');

この時点で、コンテンツ中で my_template_tag() を記述するとフィルターフックが適用されて「Hello ! MY TEXT: TEST」と出力さ、出力される値が変更されています。

<p><?php echo my_template_tag("test"); ?></p>
<!-- Hello ! MY TEXT: TEST と出力される -->

この例では、独自に作成した関数にフィルターを適用して出力を変更しているので、ほとんど意味はありませんが、フィルターを使用すれば、WordPress のコアファイルを変更することなく、その出力をカスタマイズすることができます。

デフォルトで設置されているフィルターフックの利用例は「title タグのカスタマイズ」を参照ください。

add_filter フックに登録

指定したフィルターフックに、関数を登録します。

add_filter( $tag, $function_to_add, $priority, $accepted_args )

パラメータ
  • $tag(文字列):(必須) 登録するフィルターフックの名前
  • $function_to_add(コールバック):(必須)フックする関数名(フィルターが適用されたときに呼び出される関数名)。WordPress の関数の名前と重なると(同じ場合)エラーになります。
  • $priority(整数):(オプション)同じフックに複数の関数が登録されている場合の優先順位。数値が小さいほど早く実行され、同じ数値の場合は追加された順に実行される。省略時(初期値)は 10 です。
  • $accepted_args(整数):(オプション)フックした関数が受け入れられる引数の数。フィルターフックに登録された関数は、 対応する apply_filters() の実行時に渡される追加の引数を受け取ることができます。(初期値:1)
戻り値
フィルターフックに関数を登録できると true を、そうでなければ false を返します。

以下が add_filter() の書式です。

フィルターが適用される際に実行される処理を独自のコールバック関数で定義します。

「優先順位(デフォルトは10)」と「引数の数(デフォルトは1)」はオプションで、必要に応じて指定します。

コールバック関数では、引数で受け取った値($value)を加工して返す場合が多いですが、変更後の値を返せばよいので $value である必要はありません。

function コールバック関数($value) {
  //フィルターが適用される際の処理
  return $value;  //引数に受け取った値($value)を加工して返すか変更後の値を返す
}
add_filter( フック名, コールバック関数名, 優先順位, 引数の数 );

また、add_filter() は以下のようにコールバック関数の定義の前に記述しても問題ありません。

add_filter( フック名, コールバック関数名, 優先順位, 引数の数 );
function コールバック関数($value) {
  //フィルターが適用される際の処理
  return $value;  
}

例えば、the_title フィルターに登録するコールバック関数は引数に「タイトルの文字列」と「投稿 ID」を受け取ることができます。

function コールバック関数( $title, $id ) {
  //$title を加工して返す
  return $title;
}
add_filter( 'the_title',  コールバック関数名, 10, 2 );

投稿 ID($id)を利用しない場合は引数に受け取る $id を省略できます。引数は1(デフォルト)になるので add_filter() の引数のオプションは省略できます。

優先順位もデフォルトの10であれば省略可能です。優先順位はコールバック関数の実行されるタイミングになるので、他の登録されている関数の優先順位等を考慮して指定する必要があります。

function コールバック関数( $title ) {
  //$title を加工して返す
  return $title;
}
add_filter( 'the_title',  コールバック関数名, 10 );

以下は関連項目へのリンクです。

抜粋の最後の文字列を変更する例

本文から抜粋されたテキストの最後の文字列を変更するには excerpt_more フィルターを利用します。

function new_excerpt_more($more) {
  return '...';  //変更する文字を返す
}
add_filter('excerpt_more', 'new_excerpt_more');

head 内に出力される DNS プリフェッチを全て非表示にする例

以下は WordPress により自動的に head 内に出力される DNS プリフェッチ(特定のホスト名の名前解決を強制)を全て非表示にする(出力させない)例です。「Remove the new dns-prefetch code」からの引用です。

wp_resource_hints() 関数に設置されている wp_resource_hints フィルタを使って、$hints(URLs)と $relation_type を引数に取り、変更後の $hints(URLs)を返しています。

array_diff() は配列を比較して差分を返す PHP 関数です。

wp_resource_hints()は、プリフェッチ、プリレンダリング、事前接続(プリコネクト)のためのリソースヒントをブラウザに出力する関数です。その中のプリフェッチ(dns-prefetch)のみ出力しないようにしているようです。

※DNS プリフェッチは予め DNS による名前解決を行っておく仕組みなので有用な場合も多く、無効にするかどうかはサイトの内容により判断する必要があります。ここではフィルタの例として掲載しています。

function remove_dns_prefetch( $hints, $relation_type ) {
  if ( 'dns-prefetch' === $relation_type ) {
    return array_diff( wp_dependencies_unique_hosts(), $hints );
  }
  return $hints;
}
add_filter( 'wp_resource_hints', 'remove_dns_prefetch', 10, 2 );

apply_filters フックを適用

フィルターフックに追加(登録)された関数を呼び出します。この関数により、フィルターフック $tag に登録されたコールバック関数が呼び出されます。

apply_filters( $tag, $value, $var ... )

パラメータ
  • $tag(文字列):(必須) フィルターフック名
  • $value(mixed):(必須) $tag に登録されたフィルター関数が変更できる値
  • $var(mixed):(オプション) フィルター関数へ渡す追加の変数(複数指定可)。これは関数の中で使えるが値が返されることはない。
戻り値
(mixed) $value に全てのフィルター関数を適用した結果。※戻り値の型は、$value の型(文字列や配列など)と同じでなければなりません。

remove_filter フックを削除

特定のフィルターフックに登録されている関数を除去します。※フックを除去するには、$function_to_remove と $priority 引数がフックが追加されたときと一致する必要があります(除去に失敗した時に警告は出ません)。

remove_filter( $tag, $function_to_remove, $priority )

パラメータ
  • $tag(文字列):(必須) 除去する関数がフックしているフィルターフック
  • $function_to_remove(文字列):(必須) 除去する関数名
  • $priority(整数):(オプション) (関数がフックされる時に定義される)関数の優先度(初期値: 10)
戻り値
関数が除去されたかどうかの真偽値(成功:true/失敗:false)

以下は、the_content フィルターフックから自動整形する関数(wpautop)を解除する例です。本文を自動整形する機能を解除します。

remove_filter( 'the_content', 'wpautop' );

フィルターフックの一覧

WordPress のコアファイルにどのようなフィルターフックがあるかは「フィルターフック一覧」に掲載されています。以下は一例です。

フィルターフックの例
フック名 説明(実行されるタイミング)
wp_title wp_title 関数が生成したページ名がブラウザに送信される前
the_title 画面を表示する前にデータベースから取得した投稿タイトルに適用
body_class body要素のクラスを出力する前
get_the_excerpt get_the_excerpt 関数で取得した投稿の抜粋に適用
the_excerpt 画面を表示する前にデータベースから取得した記事の抜粋に適用
excerpt_more 抜粋の後に来る "more(続きを読む)" 文字列の長さを定義
the_content データベースから取得した投稿コンテンツを画面に出力する前に適用
single_post_title wp_title 関数および single_post_title 関数でブログページタイトルを生成する際に投稿タイトルに適用
wp_list_categories wp_list_categories 関数で生成されたカテゴリーリスト(HTML リスト)に適用
single_cat_title wp_title 関数および single_cat_title 関数内でカテゴリーページのタイトルに利用するカテゴリー名に適用
the_tags 画面を表示する前に、データベースから取得したタグに適用
the_date the_date 関数が生成したフォーマット済みの投稿年月日に適用
the_time the_time 関数が生成したフォーマット済みの投稿時間に適用

以下のサイトでは過去のバージョンごとの全てのフックや非推奨になったフックなどが掲載されています。

登録されているフック

個々のアクションフックやフィルターフックにどのような関数が登録されているかは、グローバル変数 $wp_filter で確認することができます。

add_action() と add_filter() はフックに登録された関数を $wp_filter[ "フック名" ] に追加しているので、以下のようにして確認できます。

<pre>
  <?php 
    global $wp_filter;
    var_dump ( $wp_filter['フック名'] );  
  ?>     
</pre>

以下は、var_dump ( $wp_filter['wp_head'] ) の場合の出力例です。add_action() や add_filter() の第3引数に指定した $priority の順に表示されています。

object(WP_Hook)#141 (5) {
  ["callbacks"]=>
  array(9) {
    [1]=>   //$priority(優先順位)
    array(4) {
      ["_wp_render_title_tag"]=>
      array(2) {
        ["function"]=>
        string(20) "_wp_render_title_tag"
        ["accepted_args"]=>
        int(1)
      }
      ["wp_enqueue_scripts"]=>
      array(2) {
        ["function"]=>
        string(18) "wp_enqueue_scripts"
        ["accepted_args"]=>
        int(1)
      }
      ["noindex"]=>
      array(2) {
        ["function"]=>
        string(7) "noindex"
        ["accepted_args"]=>
        int(1)
      }
      ["wp_post_preview_js"]=>
      array(2) {
        ["function"]=>
        string(18) "wp_post_preview_js"
        ["accepted_args"]=>
        int(1)
      }
    }
    [2]=>   //$priority(優先順位)
    array(2) {
      ["wp_resource_hints"]=>
      array(2) {
        ["function"]=>
        string(17) "wp_resource_hints"
        ["accepted_args"]=>
        int(1)
      }
      ["feed_links"]=>
      array(2) {
        ["function"]=>
        string(10) "feed_links"
        ["accepted_args"]=>
        int(1)
      }
    }
    [3]=>   //$priority(優先順位)
    array(1) {
      ["feed_links_extra"]=>
      array(2) {
        ["function"]=>
        string(16) "feed_links_extra"
        ["accepted_args"]=>
        int(1)
      }
    }
    [7]=>   //$priority(優先順位)
    array(1) {
      ["print_emoji_detection_script"]=>
      array(2) {
        ["function"]=>
        string(28) "print_emoji_detection_script"
        ["accepted_args"]=>
        int(1)
      }
    }
    [8]=>   //$priority(優先順位)
    array(1) {
      ["wp_print_styles"]=>
      array(2) {
        ["function"]=>
        string(15) "wp_print_styles"
        ["accepted_args"]=>
        int(1)
      }
    }
    [9]=>   //$priority(優先順位)
    array(1) {
      ["wp_print_head_scripts"]=>
      array(2) {
        ["function"]=>
        string(21) "wp_print_head_scripts"
        ["accepted_args"]=>
        int(1)
      }
    }
    [10]=>   //$priority(優先順位)デフォルト値
    array(11) {
      ["rest_output_link_wp_head"]=>
      array(2) {
        ["function"]=>
        string(24) "rest_output_link_wp_head"
        ["accepted_args"]=>
        int(0)
      }
      ["rsd_link"]=>
      array(2) {
        ["function"]=>
        string(8) "rsd_link"
        ["accepted_args"]=>
        int(1)
      }
      ["wlwmanifest_link"]=>
      array(2) {
        ["function"]=>
        string(16) "wlwmanifest_link"
        ["accepted_args"]=>
        int(1)
      }
      ["adjacent_posts_rel_link_wp_head"]=>
      array(2) {
        ["function"]=>
        string(31) "adjacent_posts_rel_link_wp_head"
        ["accepted_args"]=>
        int(0)
      }
      ["locale_stylesheet"]=>
      array(2) {
        ["function"]=>
        string(17) "locale_stylesheet"
        ["accepted_args"]=>
        int(1)
      }
      ["wp_generator"]=>
      array(2) {
        ["function"]=>
        string(12) "wp_generator"
        ["accepted_args"]=>
        int(1)
      }
      ["rel_canonical"]=>
      array(2) {
        ["function"]=>
        string(13) "rel_canonical"
        ["accepted_args"]=>
        int(1)
      }
      ["wp_shortlink_wp_head"]=>
      array(2) {
        ["function"]=>
        string(20) "wp_shortlink_wp_head"
        ["accepted_args"]=>
        int(0)
      }
      ["_custom_logo_header_styles"]=>
      array(2) {
        ["function"]=>
        string(26) "_custom_logo_header_styles"
        ["accepted_args"]=>
        int(1)
      }
      ["wp_oembed_add_discovery_links"]=>
      array(2) {
        ["function"]=>
        string(29) "wp_oembed_add_discovery_links"
        ["accepted_args"]=>
        int(1)
      }
      ["wp_oembed_add_host_js"]=>
      array(2) {
        ["function"]=>
        string(21) "wp_oembed_add_host_js"
        ["accepted_args"]=>
        int(1)
      }
    }
    [99]=>   //$priority(優先順位)
    array(1) {
      ["wp_site_icon"]=>
      array(2) {
        ["function"]=>
        string(12) "wp_site_icon"
        ["accepted_args"]=>
        int(1)
      }
    }
    [101]=>   //$priority(優先順位)
    array(1) {
      ["wp_custom_css_cb"]=>
      array(2) {
        ["function"]=>
        string(16) "wp_custom_css_cb"
        ["accepted_args"]=>
        int(1)
      }
    }
  }
  ["iterations":"WP_Hook":private]=>
  array(0) {
  }
  ["current_priority":"WP_Hook":private]=>
  array(0) {
  }
  ["nesting_level":"WP_Hook":private]=>
  int(0)
  ["doing_action":"WP_Hook":private]=>
  bool(false)
}    

false などの値を返す関数

フィルターに簡単に false などの値を返す関数が WordPress には用意されています。

例えば、ツールバーを非表示にするには show_admin_bar を使って false を返せば良いので以下のように記述することができます。

function my_display_no_admin_bar(){
  return false;
}
add_filter( 'show_admin_bar' , 'my_display_no_admin_bar');

__return_false と言う false を返す関数を使うと以下のように簡潔に記述することができます。

add_filter('show_admin_bar', '__return_false');

__return_false は wp-includes/functions.php に以下のように定義されています。単に false を返すだけです。

function __return_false() {
    return false;
}

false を返す以外にも以下のような値を返す関数が用意されています。

関数 戻り値
__return_true true
__return_false false
__return_zero 0
__return_empty_array array()
__return_null null
__return_empty_string ''
/** wp-includes/functions.php **/
/**
* Returns true.
* Useful for returning true to filters easily.
* @since 3.0.0
* @return true True.
*/
function __return_true() {
  return true;
}

/**
* Returns false.
* Useful for returning false to filters easily.
* @since 3.0.0
* @return false False.
*/
function __return_false() {
  return false;
}

/**
* Returns 0.
* Useful for returning 0 to filters easily.
* @since 3.0.0
* @return int 0.
*/
function __return_zero() {
  return 0;
}

/**
* Returns an empty array.
* Useful for returning an empty array to filters easily.
* @since 3.0.0
* @return array Empty array.
*/
function __return_empty_array() {
  return array();
}

/**
* Returns null.
* Useful for returning null to filters easily.
* @since 3.4.0
* @return null Null value.
*/
function __return_null() {
  return null;
}

/**
* Returns an empty string.
* Useful for returning an empty string to filters easily.
* @since 3.7.0
* @return string Empty string.
*/
function __return_empty_string() {
return '';
}

参考になるサイト

以下のサイトにアクションフックとフィルターフックについての詳しい解説があり参考になります。