admin_headを特定のページでのみ使用するにはhook_suffixを知るべし

WordPressのプラグインで管理画面を追加した際に、そのページにだけ外部CSSやJavaScriptを適用させたい場合があります。

そんな場合に、admin_headフックを使用すると全ての管理画面で動作してしまうため条件分岐が必要となりますが、admin_headの後ろに以下のようにhook_suffixをつけてやることで特定のページに限定して関数を実行させることができます。

// wp-admin以下の全てのページでmy_func()が実行される
add_action('admin_head', 'my_func');

// hook_suffixが一致するページのみでmy_func()が実行される
add_action('admin_head-hook_suffix', 'my_func');

これに関しては以前にも書いたのですが、今日の作業でようやくコツがわかったので、補足します。

wp-admin/admin-header.phpを見てみる。

現時点での最新バージョンのWordPress 3.1.2 のwp-admin/admin-header.php では、以下のようなフックが実行されています。

admin-header.php 76行目より

do_action('admin_enqueue_scripts', $hook_suffix);
do_action("admin_print_styles-$hook_suffix");
do_action('admin_print_styles');
do_action("admin_print_scripts-$hook_suffix");
do_action('admin_print_scripts');
do_action("admin_head-$hook_suffix");
do_action('admin_head');

admin_header.php では、admin_head(admin_print_xxxなども同様)フックとは別に、admin_head-$hook_sufffix というフックなどが実行されているのがわかります。

このフックを利用することで管理画面内の特定のページに限定して関数を実行することが可能です。

hook_suffixの種類

hook_suffixは、管理画面内のページ毎にユニークなものが割り当てられており、以下のパターンのいずれかに該当します。

ファイル名

WordPressでもともと用意されているページでは、admin_headの末尾に以下のようにファイル名をつけることで、そのページに限定して関数を実行することができます。

// 新規投稿画面でのみmy_function()を実行する
add_action("admin_head-post-new.php", "my_function");

固有の識別子

プラグインによって追加されたページでは、ページを識別する文字列がhook_suffixとして渡されます。

実は、これがわかりいくい。(泣)

そこで以下のようなプラグインを作って、ページごとにhook_suffixを見てみました。

このプラグインを適用すると、JavaScriptのデバッグコンソールにhook_suffixの値を出力します。

それによると、たとえば [外観] – [ヘッダー] のページ(/wp-admin/themes.php?page=custom-header)では、以下のようなhook_suffixになっています。

appearance_page_custom-header

長いし覚えにくいのですが、これをもとにカスタムヘッダーのページの admin_head でのみ動作する関数を定義するには以下のような感じになります。

add_action('admin_head-appearance_page_custom-header', 'my_func')

しかし、実はこれでは不十分でした。

冒頭でご紹介したプラグインをテストしてて気がついたのですが、このhook_suffixは言語によってかわる仕様になっています。

どういうことかといいますと、プラグイン用の管理ページをadd_menu_page()などで追加して新しいトップレベルのメニューを生成した場合に、そのページのhook_suffixはページのタイトルを使用しますので、多言語化している場合に言語によってhook_suffixが変わってしまいます。

多言語化したプラグインで上手く処理するには、add_menu_page() や add_submenu_page() の戻り値が hook_suffix になっているので、それを取得して ”admin_head-” のうしろに付ける必要があります。

// メニューを追加し、そのページに対するadmin_headを定義する
$hook = add_submenu_page(....);
add_action("admin_head-".$hook, 'my_func');

プラグインのファイル名

ネット上のいくつかのブログではadmin_head-path/foo.phpのようにhook_suffixの部分にプラグインのファイル名を書くというような情報がありましたが、前回の記事でもそうでしたが、結局これはわからないままです。

ただし、前述した方法を使用することで、hook_suffixはバッチリ把握できるので、すべて解決とします。

まとめ

  • 管理ページでページを限定して関数をコールするには、admin_headの後ろにハイフォンに続けてhook_suffixをつける。
  • hook_suffix は。add_menu_page() や add_submenu_page() の戻り値で取得できるので、それを使わないと多言語化でハマることがある。
  • プラグインのファイル名で指定する方法があるらしいのだが動かない。どういうときに使用できるのか誰か教えてください。