プラグインの動作をユーザーが設定できるようにする
「WordPressプラグインの解説」第4弾。
プラグインの動作をユーザー側で変更できるようにするには、プラグインに設定を追加します。
プラグインの設定で良くあるのが「設定画面 > 設定」に追加するタイプです。
この解説ではトップレベルメニューやサブレベルメニューの追加、フォームのHTML・CSSを分離する方法も解説します。
このページの目次
- カスタムメニューとカスタム管理画面の作成
- トップレベルメニューの追加
- サブメニューの追加
- 既存のメニューにオリジナルの設定項目を追加する方法
- プラグイン専用のオプションページを作る
- HTMLやCSSファイル(View)を分離する方法
- 外部コンテンツを取得する場合はfile_get_contentsではなく、wp_remote_getを使う
カスタムメニューとカスタム管理画面の作成
まずは一般的な実装として、「設定画面 > 設定」にプラグインの専用ページを追加する方法を解説します。
WordPressの設定画面は柔軟に設計されており、あらゆる場所にメニューを追加することができます。残念なことに、その柔軟性ゆえに非常に複雑な仕組みをしています。
一読しただけで理解できる方は稀だと思います。この解説やCodexの解説を何度か読み返して理解を深めていただければと思います。
Codexの解説にありますが、「設定」に管理画面を追加するには、3つの要素が必要です。
1つ目はadmin_menuというアクションフック。
2つ目はadmin_menuで呼び出されるadd_options_page()を内包した関数。
3つ目は設定画面用のHTML。
// 1つ目、アクションフック add_action( 'admin_menu', 'add_plugin_admin_menu' ); // 2つ目、アクションフックで呼ばれる関数 function add_plugin_admin_menu() { add_options_page( 'Hello_World', // page_title(オプションページのHTMLのタイトル) 'Hello_Worldプラグインの管理画面', // menu_title(メニューで表示されるタイトル) 'administrator', // capability 'hello-world', // menu_slug(URLのスラッグこの例だとoptions-general.php?page=hello-world) 'display_plugin_admin_page' // function ); } // 3つ目、設定画面用のHTML function display_plugin_admin_page() { echo '<div class="wrap">'; echo '<p>Hello_Worldプラグインの管理画面</p>'; echo '</div>'; }
この設定だと「設定メニュー」にプラグイン専用のメニューが追加されます。
これが最も簡単なカスタム管理画面の実装です。ではそれぞれの関数について補足します。
admin_menuについて
admin_menuは名前の通り、メニューを追加するアクションフックです。
Codexのadmin_menu()の解説(日本語の解説はありません)
add_action('admin_menu', 'function_name');
1点注意点があります。同じく管理画面で項目を追加する際に使うadmin_initがあります。同じように設定項目を追加するのでadmin_menuで指定する関数でadmin_initを追加したいと思うかもしれません。しかし、関数の実行順序はadmin_initが実行された後にadmin_menuが実行されるためadmin_menuの関数内でadmin_initは使えません。
add_options_page()について
add_options_page()は「設定メニュー」にサブメニューページを追加する関数です。
Codexのadd_options_page()の解説(こちらは日本語の解説あり)
add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function);
$page_titleはHTMLのタイトル。
$menu_titleはWordPressのメニューに表示されるタイトル。
$capabilityは権限。プラグインのインストールや削除などの権限を持つのは管理者だけなので、普通はadministratorを指定します。
なぜかCodexにはcapabilityの指定方法についての解説がありませんが、以下のようになっています。
administrator | 管理者 |
---|---|
editor | 編集者 |
author | 投稿者 |
contributor | 寄稿者 |
subscriber | 購読者 |
その他、サイト独自の権限やグループがある場合もあります。また、権限を数字で指定するのは古い方法で、現在では非推奨です。
$menu_slugはURLのスラッグです。スペース等は使わず、ハイフンで繋ぐのがWordPressの流儀のようです。
$functionはメニューボタンをクリックした際に実行されるコールバック関数を指定します。
コールバック関数で実行される表示のためのHTMLはサンプルということで簡単にすませました。
トップレベルメニューの追加
トップレベルメニューは外観、プラグイン、設定などと並列しているメニューです。
1ページで済むなら設定メニューに追加するのが望ましいですが、設定が複数のページに及ぶと、オリジナルのトップレベルメニューとサブメニューという2段階の構成にしたい場合もあると思います。
まずはトップレベルメニューの追加方法を見ていきます。
トップレベルメニューの追加はadd_menu_page()で追加します。基本的にはadd_options_page()と同じです。
add_action( 'admin_menu', 'add_plugin_admin_menu' ); function add_plugin_admin_menu() { add_menu_page( 'Hello_World', // page_title 'Hello_World', // menu_title 'manage_options', // capability 'hello-world', // menu_slug 'display_plugin_admin_page', // function '', // icon_url 81 // position ); } function display_plugin_admin_page() { echo '<div class="wrap">'; echo '<p>Hello_Worldプラグインの管理画面</p>'; echo '</div>'; }
上の例で言うadd_options_page()がadd_menu_page()に置き換わっています。
実行すると以下のように表示されます。
add_menu_page()について
add_menu_page()の書式
add_menu_page( $page_title, $menu_title, $capability, $menu_slug, $function, $icon_url, $position );
$page_titleはHTMLのタイトル。
$menu_titleはWordPressのメニューに表示されるタイトル。
$capabilityは権限。指定の仕方はadd_options_page()と同じです。繰り返しますが数字で指定する方法は、現在では非推奨になっているので注意してください。
$menu_slugはメニューのURL。
$functionはメニューボタンをクリックした際に実行されるコールバック関数を指定します。
$icon_urlはそのままアイコンのURLを指定します。空欄だとデフォルトのアイコンが表示されます。
$positionは表示の位置です。英語版のCodexの解説ページに既存メニューの順序を表す数字が記載されています。
既存メニューと同じ数字を指定すると、既存メニューが消えてしまうので別の数字にしてください。「設定は80」なので次に表示したい場合は「81」とする。
2 | ダッシュボード(Dashboard) |
---|---|
4 | セパレーター(Separator) |
5 | 投稿(Posts) |
10 | メディア(Media) |
15 | リンク(Links) |
20 | 固定ページ(Pages) |
25 | コメント(Comments) |
59 | セパレーター(Separator) |
60 | 外観(Appearance) |
65 | プラグイン(Plugins) |
70 | ユーザー(Users) |
75 | ツール(Tools) |
80 | 設定(Settings) |
99 | セパレーター(Separator) |
ちなみにセパレーターは区切りのことです。テーマによっては明確な線にはなっていませんが多少スペースが多く取られています。
サブメニューの追加
先ほど追加したトップレベルメニューにサブメニューを追加します。
サブメニューの追加はadd_submenu_page()を使います。
ではトップレベルメニューと、サブメニューを組み合わせて指定してみます。
add_action( 'admin_menu', 'add_plugin_admin_menu' ); function add_plugin_admin_menu() { add_menu_page( 'Hello_World', // page_title 'Hello_World', // menu_title 'administrator', // capability 'hello-world', // menu_slug 'display_plugin_admin_page', // function '', // icon_url 81 // position ); add_submenu_page( 'hello-world', // parent_slug 'Hello_World', // page_title 'Hello_World_Sub', // menu_title 'administrator', // capability 'hello-world-sub', // menu_slug 'display_plugin_sub_page' // function ); } function display_plugin_admin_page() { echo '<div class="wrap">'; echo '<p>Hello_Worldプラグインの管理画面</p>'; echo '</div>'; } function display_plugin_sub_page() { echo '<div class="wrap">'; echo '<p>Hello_Worldプラグインのサブメニュー用管理画面</p>'; echo '</div>'; }
この設定だと以下のようになります。
Hello_Worldの後に、Hello_World_Subが表示され、クリックすると「Hello_Worldプラグインのサブメニュー用管理画面」が表示されます。
add_submenu_pageについて
Codexのadd_submenu_page()の解説(日本語の解説は無し)
add_submenu_page()の書式(add_menu_page()と被るところは省略)
add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function );
$parent_slugは親メニューを指定します。
WordPressの既存のメニューにサブメニューを追加したい場合は以下のスラッグを指定すればサブメニューを追加することができます。
トップレベルメニュー | add_submenu_page()の指定方法 | 独自のタグによる指定方法 |
---|---|---|
ダッシュボード | add_submenu_page( ‘index.php’, … ) | add_dashboard_page() |
投稿 | add_submenu_page( ‘edit.php’, … ) | add_posts_page() |
メディア | add_submenu_page( ‘upload.php’, … ) | add_media_page() |
リンク | add_submenu_page( ‘link-manager.php’, … ) | add_links_page() |
固定ページ | add_submenu_page( ‘edit.php?post_type=page’, … ) | add_pages_page() |
コメント | add_submenu_page( ‘edit-comments.php’, … ) | add_comments_page() |
カスタム投稿タイプ | add_submenu_page( ‘edit.php?post_type=your_post_type’, … ) | |
外観 | add_submenu_page( ‘themes.php’, … ) | add_theme_page() |
プラグイン | add_submenu_page( ‘plugins.php’, … ) | add_plugins_page() |
ユーザー | add_submenu_page( ‘users.php’, … ) | add_users_page() |
ツール | add_submenu_page( ‘tools.php’, … ) | add_management_page() |
設定 | add_submenu_page( ‘options-general.php’, … ) | add_options_page() |
一番上の解説で「設定メニュー」にサブメニューを追加した際にadd_options_page()を利用しましたが、そうしたサブメニュー専用のタグを使って追加する方法と、このadd_submenu_page()でサブメニューを追加する、二種類の実装ができるということです。
$page_titleはサブメニューページHTMLのタイトル。
$menu_titleはサブメニューのタイトル。
$capabilityは権限。
$menu_slugはメニューのURL。
$functionはメニューボタンをクリックした際に実行されるコールバック関数を指定します。
試しにadd_submenu_page()のparent_slugをhello-worldからindex.phpに置き換えてダッシュボードにサブメニューを追加してみます。
あまり実用性があるとは思えませんが、こんなこともできるということは理解していただけたと思います。
以上、管理画面のプラグインにサブメニューを追加する方法、トップレベルメニューとサブメニューを追加する方法を解説しました。
既存のメニューにオリジナルの設定項目を追加する方法
メニューが追加できたので、今度は設定項目を追加します。
既存の「設定フィード」へカスタムの設定項目を追加
設定フィールドとは管理画面の「設定」をクリックしたときに表示される設定画面です。WordPress全体の動作に影響するような設定を保存するのに向いています。
今回はここに設定項目を追加してみます。
add_settings_field()の追加
add_settings_field()はフィールドを追加するための関数です。
注意点があり、単体では項目が追加されるだけです。データベースへデータを保存するには後述するregister_setting()も合わせて設定する必要があります。
Codexのadd_settings_fieldの解説
add_settings_fieldの書式
add_settings_field( $id, $title, $callback, $page, $section = 'default', $args = array() )
$idは設定画面のフォームでフィールドに指定するIDです。以下の様なフィールドがあった場合、id=”active_twitter”の部分です。
<input type="text" name="active_twitter" id="active_twitter" value="" />
$titleは設定項目の項目名
$callbackはコールバックで実行する関数を指定
$pageはサブメニューを指定することができます。「設定」の例で言えば、サブメニューは以下のようになっています。
設定 | general |
---|---|
投稿設定 | writing |
表示設定 | reading |
ディスカッション | discussion |
メディア | media |
パーマリンク設定 | permalink |
$sectionはセクションを指定します。セクションは節の意味で、小見出しがある項目の場合はこちらに指定します。何も入力しないとdefaultとなり、defaultの項目の最後に追加されます。
$argsは2つの役割があり、配列の名前に「label_for」を指定した場合は$titleのlavelのvalueを指定することができます。こうすることで項目名をクリックすると、対応するフィールドがアクティブになります。
もう1つの役割は、コールバック関数に引数を渡すことができます。
変数名で分かる通り、どちらも配列で渡す必要があります。
register_setting()の追加
register_setting()はadd_settings_field()で追加した設定項目をデータベースへ渡すための関数です。
この関数でサニタイズやバリデーションを行い、<接頭辞> + optionsテーブルに保存します。
register_setting()の書式
register_setting( $option_group, $option_name, $sanitize_callback )
$option_groupは設定のグループ名を指定します。グループ名とは具体的には設定のform中にsettings_fields()で設定します。(後述)
Codexにもこのように解説されていますが、この記述だけでは片手落ちで、WordPressで予め作成された設定画面の場合は自分でsettings_fields()を設定していないので、グループ名は分かりません。
そんなときは設定画面のソースを開き、nameがoption_pageの項目のvalueを見ます。
<input type="hidden" name="option_page" value="general">
この場合は「設定 > 一般」の場合は「general」だということがわかります。
$option_nameはformに追加した項目のnameを指定します。
具体的には以下の様な項目を作った場合、nameの「active_twitter」がこれに該当します。この名前で<接頭辞> + optionsテーブルに保存したり、取り出したりするため一意である必要があります。
<input type="checkbox" id="active_twitter" name="active_twitter" size="30" value="" />Twitter</input>
$sanitize_callbackはサニタイズのための関数を指定します。サニタイズは無害化の意味ですが、入力値の検証という意味合いが強いのでバリデーションを行う関数を用意するという感じです。
WordPressで行うバリデーション
WordPressでは入力値検証用の関数が用意されています。emailであればis_email( $email_address )、投稿のスラッグであればsanitize_title( $title )など。
管理者権限で設定の値を改ざんされている状況は、バリデーション云々を言っている場合では無いですが、意図しない脆弱性からの侵入も考慮して、入力値を制限しておきましょう。
基本的にはホワイトリスト形式で、それ以外のものを弾くという設定で良いと思います。入力値がエラーだった場合の処理ですが、wp_die()で処理を停止する方法や、add_settings_error()でエラーメッセージを表示する方法、一旦エラー情報を保存しておいて設定画面でadd_settings_error()でエラーを表示する方法などが考えられます。
チェックボックスで不正な値が入力される場合は、攻撃の可能性が高いのでwp_die()で停止して、emailなど間違えやすい項目はエラーメッセージを返すなど、項目に応じて適宜選択するのが良いと思います。
add_settings_error()の仕様
エラーメッセージの実装も必要になると思うので解説します。
add_settings_error()の書式
add_settings_error( $setting, $code, $message, $type )
$settingはエラーを適用する設定項目のスラッグ名。具体的には項目のnameの値。
$codeはエラーを特定するスラッグ名。エラー出力時にHTMLで「id=」の形式で「setting-error-」の後に追加される文字列。
$messageはエラー時に表示されるメッセージ。
$typeはエラーのタイプを指定(オプション)。errorもしくはupdatedを指定する。デフォルトはerror。errorは赤、updatedは緑でメッセージが表示される。
以上の内容を組み合わせると以下のようになります。
add_action( 'admin_init', 'add_general_custom_fields' ); function add_general_custom_fields() { add_settings_field( 'active_twitter', // id 'Twitter', // title 'twitter_callback_function', // callback 'general', // page 'default', // section array( 'hoge' => 'ほげ', 'label_for' => 'active_twitter' ) // args ); register_setting( 'general', // option_group 'active_twitter', // option_name 'active_twitter_validation' // sanitize_callback ); } function twitter_callback_function( $args ) { $checked = get_site_option( 'active_twitter' ); if( empty( $checked ) ){ $checked = ''; } else { $checked = 'checked="checked"'; } echo '<input type="hidden" name="active_twitter" value="0">'; echo '<label for="active_twitter"><input type="checkbox" id="active_twitter" name="active_twitter" size="30" value="1"' . $checked . '/>Twitter' . $args["hoge"] . '</input></label>'; } function active_twitter_validation( $input ) { // $input = (int) $input; (本番ではこんな感じでキャストすればよい) if ( $input === 0 || $input === 1 ) { return $input; } else { add_settings_error( 'active_twitter', 'active-twitter-validation_error', __( 'illegal data', 'Hello_World' ), 'error' ); } }
add_settings_fieldのpageでgeneralを指定しているので「設定 > 一般」に項目を追加しています。
コールバック関数でHTMLを出力するtwitter_callback_function()を指定しています。
twitter_callback_function()ではチェックボックスを表示しています。
hiddenで隠し項目のvalueに「0」、普通のチェックボックスに「1」を入れておきます。こうすることでチェックしない場合は「0」、チェックした場合は「1」が渡されます。
またget_site_option( ‘active_twitter’ )で既に保存されたオプション項目があれば取得します。項目が「1」の場合は「checked=”checked”」を追加して、チェック済みにしています。
ちなみにオプションに保存されたデータはシリアライズされています。あまりないとは思いますがget_site_optionでなく直接データベースの値を取得する場合は、アンシリアライズするmaybe_unserialize()を挟む必要があります。
他にもこんなこともできるという例で、add_settings_fieldから渡される引数を$argsで受け取ってますTwitterという文字の後に「ほげ」を追加しています。
register_settingでoption_nameにactive_twitterを指定しているので<接頭辞> + optionsテーブルへ保存されるのはoption_nameがactive_twitterで、option_valueが入力値になります。
またsanitize_callbackでは自作のバリデーション用の関数であるactive_twitter_validationを実行しています。
active_twitter_validationでは入力値が引数に入っているので、適宜バリデーションしてreturnで入力値を返します。
この例ではadd_settings_errorを使いたかったので無理やりホワイトリスト形式にしています。
通常であれば入力値は0か1なので、(int)でキャストすれば不正な値は0になり、サニタイズの目的は果たせます。
add_settings_errorでは対応する項目名やエラー表示時のID、エラーメッセージなどを指定。エラー時には「illegal data」が表示されます。一応「__()」で第2引数に「Hello_World」を指定して国際化に対応できるようになってます。
参考までにこのコードで設定画面に追加されたHTMLは以下の通りです。
<tr> <th scope="row"><label for="active_twitter">Twitter</label></th> <td> <input type="hidden" name="active_twitter" value="0"> <label for="active_twitter"><input type="checkbox" id="active_twitter" name="active_twitter" size="30" value="1">Twitterほげ</label> </td> </tr>
では実際に「設定 > 一般」を開いて項目にチェックをして「変更を保存」をクリックしてみます。
正しく設定が保存されたかphpMyAdminで確認してみます。
無事「active_twitter」の値が「1」というデータが追加されています。
保存したオプションを取得する方法
この設定を取得するにはget_site_option()を利用します。
echo get_site_option( 'active_twitter' );
エラーメッセージの表示例
では不正な値を入力したらどうなるか見てみます。
hiddenの値を適当な数値に変更後、チェックを外した状態で、「変更を保存」をクリックしてみます。
するとエラーメッセージで設定したように「illegal data」と表示されます。
また、エラーのHTMLのIDに「setting-error-active-twitter-validation_error」と指定した通りに表示されています。
このIDをフラグにCSS等で独自のエラー表示を追加したりすることもできます。
以上で、設定項目の追加、バリデーション、エラーメッセージ、データベースへの保存、保存した設定の取得、という一連の流れを実装できました。
後は項目をテキストエリアにしたり、ラジオボックにしたりとアレンジしてみてください。
プラグイン専用のオプションページを作る
続いてプラグイン専用のオプションページを作成する方法を解説します。
基本的には既に解説した方法を踏襲します。
既存の設定ページヘ項目を追加するにはformタグなどは必要ありませんでしたが、自分でオリジナルの設定ページを作る場合は自分でフォームタグやセキュリティ対策をする必要があります。
「設定」へオリジナルのページを追加するのはadd_options_page()を利用する。というところまでは解説しました。
更にオリジナルの設定ページに設定項目を追加するには以下のようにします。
add_action( 'admin_menu', 'add_general_custom_fields' ); function add_general_custom_fields() { add_options_page( 'Hello Worldのタイトル', // page_title 'Hello Worldのメニュー', // menu_title 'administrator', // capability 'hello-world', // menu_slug 'display_plugin_admin_page' // function ); register_setting( 'hello-world-group', // option_group 'active_twitter', // option_name 'active_twitter_validation' // sanitize_callback ); } function active_twitter_validation( $input ) { $input = (int) $input; if ( $input === 0 || $input === 1 ) { return $input; } else { add_settings_error( 'active_twitter', 'active-twitter-validation_error', __( 'illegal data', 'Hello_World' ), 'error' ); } } function display_plugin_admin_page() { $checked = get_site_option( 'active_twitter' ); if( empty( $checked ) ){ $checked = ''; } else { $checked = 'checked="checked"'; } ?> <div class="wrap"> <h2>Hello Worldプラグインだよ</h2> <form method="post" action="options.php"> <?php settings_fields( 'hello-world-group' ); do_settings_sections( 'default' ); ?> <table class="form-table"> <tbody> <tr> <th scope="row"><label for="active_twitter">Twitter</label></th> <td> <input type="hidden" name="active_twitter" value="0"> <label for="active_twitter"><input type="checkbox" id="active_twitter" name="active_twitter" size="30" value="1"<?php echo $checked; ?>/>Twitter</input></label> </td> </tr> </tbody> </table> <?php submit_button(); // 送信ボタン ?> </form> </div><!-- .wrap --> <?php } ?>
この記述で以下のように表示されます。
まずメニューを追加するので、add_action()でアクションフックはadmin_initではなくadmin_menuにします。
register_setting()のoption_groupはhello-world-groupにしています。このグループは後述しますが、formで設定するsettings_fields()やdo_settings_sections()と合わせる必要があります。
display_plugin_admin_page()のHTMLの指定ですが、PHPとHTMLが混在するので書き方に迷いますが、HTMLが多くなるので?>で一回閉じて、PHPを使うところだけ<?php コード ?>とするのが書きやすいと思います。
また設定画面の書式を他と合わせるには<div class="wrap"></div>で囲み、タイトルは<h2></h2>で指定します。
そしてformですが、<form method="post" action="options.php"></form>というのはテンプレです。
続くsettings_fields( ‘…’ )とdo_settings_sections( ‘…’ )もSetting APIの決まり事です。
既に上で触れましたが、settings_fields()の引数はregister_setting()のoption_groupと一致させる必要があります。また、
do_settings_sections()の引数はadd_settings_section()のページ名と一致させる必要があります。何も引数を入れないとエラーが出るので、特にセクションを指定していない場合はdefaultとしておきましょう。
以上の設定で以下のように出力されます。
<input type="hidden" name="option_page" value="hello-world-group"> <input type="hidden" name="action" value="update"> <input type="hidden" id="_wpnonce" name="_wpnonce" value="fc47a9f686"> <input type="hidden" name="_wp_http_referer" value="/xampp/oxynotes/wp-admin/options-general.php?page=hello-world&settings-updated=true">
CSRF対策でWordPressが用いているwp_nonceが発行されている点に注目してください。
かつてはwp_nonce用の記述を追加する必要がありましたが、プラグイン作者による漏れが多かったのでこの方法になったようです。(それでもかなり複雑ですが…)
最後にsubmit_button()で送信ボタンを付けます。
今回はチェックボックスだけだったので必要ありませんでしたが、入力欄などがある場合は出力の前にエスケープすることを忘れないようにしてください。
とりあえずesc_html()を利用しておけば安心です。タグはエスケープされるのでJavaScriptもHTMLも解釈されることはなくなります。
他にもテキストエリアはesc_textarea()。URLはesc_url()などが用意されています。
許可したタグ以外は認めないということならwp_kses()という関数も用意されています。
HTMLやCSSファイル(View)を分離する方法
設定画面の出力が他のタグに紛れると、見通しが悪くなります。そんなときは表示に関する部分を外部ファイルにするとわかりやすくなります。
上の例で言えば、add_options_page()で呼ばれるコールバック関数で、以下のように別ファイルを読みこむだけです。
上のコードでdisplay_plugin_admin_page()の部分だけ以下のように変えます。
function display_plugin_admin_page() { include_once( 'views/options.php' ); wp_enqueue_style( "hello-world", plugins_url( 'style/options.css', __FILE__ ) ); }
CSSの読み込みはwp_enqueue_style()でスラッグとCSSのパスを指定しましょう。
CSSはwp_print_styles()でも追加できますが、意図したページ以外でも無駄に読み込まれてしまうので使わないようにしてください。
views/options.php
<?php $checked = get_site_option( 'active_twitter' ); if( empty( $checked ) ){ $checked = ''; } else { $checked = 'checked="checked"'; } ?> <div class="wrap"> <h2>Hello Worldプラグインだよ</h2> <form method="post" action="options.php"> <?php settings_fields( 'hello-world-group' ); do_settings_sections( 'default' ); ?> <table class="form-table"> <tbody> <tr> <th scope="row"><label for="active_twitter">Twitter</label></th> <td> <input type="hidden" name="active_twitter" value="0"> <label for="active_twitter"><input type="checkbox" id="active_twitter" name="active_twitter" size="30" value="1"<?php echo $checked; ?>/>Twitter</input></label> </td> </tr> </tbody> </table> <?php submit_button(); // 送信ボタン ?> </form> </div><!-- .wrap -->
style/options.css
今回はテスト用としてとりあえず背景を白にしてみました。
.wrap { background-color: #fff; padding: 20px; }
このように設定すると以下のようになります。
他の設定画面を開いて、options.cssが別のプラグインには適用されておらず、読み込まれてもいないことを確認してください。
プラグインの設定ページ限定でJavaScriptファイルを読み込む方法
プラグインの設定ページ限定でJavaScriptファイルを読み込むのはもっと複雑です。
詳しくは「関数リファレンス/wp enqueue script」の「プラグイン管理画面のみでスクリプトをリンクする」をご覧ください。
簡単に解説するとadmin_initで設定画面が呼び出される前にwp_register_scriptを利用してJavaScriptを定義しておきます。
続いてadd_submenu_pageやadd_options_pageから$page_hook_suffixを作成します。
それをadd_actionの第1引数の「admin_print_scripts-」の後に付けて、第2引数でJavaScriptを呼び出す関数を指定します。その関数でwp_register_scriptで定義したスクリプトを呼び出します。
これでadd_submenu_pageやadd_options_pageで指定したページ限定でJavaScriptファイルを呼び出すことができます。
ちなみに全てのadminページ(設定ページ)でスクリプトを呼び出す場合はadd_actionの第1引数に「admin_print_scripts」だけ指定します。
ほかにもCSS用のhookなんかも「wp-admin/admin-header.php」で定義されています。気になる方は調べてみてください。
以上で設定画面に関する解説は終わりです。
応用すればプルダウンメニューでも、テキストエリアでも、問題なく実装できると思います。
WordPressの設定画面は、はっきり言えば煩雑で、1度で構造を理解できる人は稀だと思います。様々な解説ページやCodexなどを読み返して、理解を深めてみてください。
外部コンテンツを取得する場合はfile_get_contentsではなく、wp_remote_getを使う
これは設定とは直接関係ありませんが、解説の都合上ここで解説します。
CSSやPHPファイルの読み込み方を解説しましたが、外部サイトのデータを取得する場合もWordPressの流儀があります。
file_get_contents()やcURLではなく、wp_remote_get()という専用の関数を使います。
これはcURL等のライブラリに依存することなく外部ファイルを取得することのできるWordPress独自の関数です。積極的に使いましょう。
定義はclass-http.phpのpublic function requestでされています。
サンプルでTwitterのカウントを取得
$url = "https://oxynotes.com/"; $twit_uri = 'http://urls.api.twitter.com/1/urls/count.json?url=' . rawurlencode($url); $result = wp_remote_get($twit_uri); var_dump($result);
↓返り値
array(5) { ["headers"]=> array(18) { ["cache-control"]=> string(28) "must-revalidate, max-age=900" ["content-encoding"]=> string(4) "gzip" ["content-type"]=> string(30) "application/json;charset=utf-8" ["expires"]=> string(29) "Wed, 29 Jul 2015 07:18:41 GMT" ["last-modified"]=> string(29) "Wed, 29 Jul 2015 07:03:41 GMT" ["server"]=> string(5) "tsa_a" ["x-connection-hash"]=> string(32) "f10d48f2f4d403551bcfed136e5385fb" ["x-response-time"]=> string(1) "6" ["content-length"]=> string(2) "69" ["accept-ranges"]=> string(5) "bytes" ["date"]=> string(29) "Wed, 29 Jul 2015 07:04:13 GMT" ["via"]=> string(11) "1.1 varnish" ["age"]=> string(2) "32" ["connection"]=> string(5) "close" ["x-served-by"]=> string(26) "cache-tw-tyo1-cr1-3-TWTYO1" ["x-cache"]=> string(3) "HIT" ["x-cache-hits"]=> string(1) "1" ["vary"]=> string(15) "Accept-Encoding" } ["body"]=> string(43) "{"count":9,"url":"http:\/\/oxynotes.com\/"}" ["response"]=> array(2) { ["code"]=> int(200) ["message"]=> string(2) "OK" } ["cookies"]=> array(0) { } ["filename"]=> NULL }
あとはbodyの要素を取得するだけですが、responseコードも帰ってきているので、エラー処理を追加するのが一般的です。
Step by Step Social Count Cacheでのサンプル
/** * twitterのカウントを返す * * @param str 投稿のURL * @return int 返り値はカウント */ public function get_twitter( $url ) { $twit_uri = 'http://urls.api.twitter.com/1/urls/count.json?url=' . rawurlencode($url); $result = wp_remote_get( $twit_uri, array( 'timeout' => 5 ) ); if ( !is_wp_error( $result ) && $result["response"]["code"] === 200 ) { $array = json_decode( $result["body"], true ); // jsonをデコード。trueで連想配列に変換 return (int) $array["count"]; } else { // エラー処理が面倒なので0を返す return 0; } }
このようにcURLを利用した時のようにレスポンスコードに応じて処理を振り分けることができます。
ここまでの解説でプラグインに機能を付けて、専用の設定項目を追加することができるようになりました。
後は応用で何でもできるはずです。