管理画面
管理ページを追加する方法について。
メニューの追加
まず管理画面を追加する簡単な例です。
// admin_menuアクションでメニュー追加を定義
add_action('admin_menu', function(){
// メニューの情報。
add_menu_page(
'クラゲ管理画面',
'クラゲメニュー設定',
'manage_options',
'kurage',
function()
{
echo '<h2>クラゲの設定項目・・・</h2>';
}
);
});
管理画面にメニュー(クラゲメニュー設定)が表示されるのでそれをクリック。
admin_menu
フックの中でadd_menu_page()
を使用します。
第一引数は管理ページのタイトル(タイトルバーに表示される)、
第二引数はメニューのタイトル(画面左のメニューに表示される)、
第三引数は権限(ここでは説明しません)、
第四引数にスラグ(今回はkurage
としました。)
第五引数は管理画面に表示する内容をコールバックで指定できます。
後の引数は省略。
スラグにkurage
を指定した場合、メニューを開いた時のURLには
admin.php?page=kurage
のようなクエリが追加されてます。
隠しフィールド
入力値を送信するためにまずsettings_fields()
とsubmit_button()
を追加します。
管理画面に表示するコールバック関数を定義しました。
add_action('admin_menu', function(){
$showPage = function()
{
?>
<div class="wrap">
<h2>テキストの追加</h2>
<form action="options.php" method="POST">
<?php settings_fields('kurage') ?>
<p>ここにいろんな入力フィールドを置く・・・</p>
<?php submit_button() ?>
</form>
</div>
<?php
};
add_menu_page(
'クラゲ管理画面',
'クラゲメニュー設定',
'manage_options',
'kurage',
fn() => $showPage()
);
});
まずはフォームです。
<form action="options.php" method="POST">
宛先はoptions.php
で、メソッドをPOST
にして送信するようにします。
ただそれだけでは役不足です。
隠しフィールドに必要な情報を持たせないといけません。
それをやってくれるのがsettings_fields()
です。
settings_fields('kurage')
引数にスラグを指定します。
この関数は以下の隠し要素を吐き出します。
<input type="hidden" name="option_page" value="kurage">
<input type="hidden" name="action" value="update">
<input type="hidden" id="_wpnonce" name="_wpnonce" value="16a1d9fd5f">
<input type="hidden" name="_wp_http_referer" value="/wp-admin/admin.php?page=kurage">
option_page
でスラグ(今回はkurage
)を保持します。
action
がupdate
になるとoptions.php
は更新作業だと判断します。
_wpnonce
はセキュリティ対策のものでCSRF攻撃
を回避するためのナンス
を忍ばせます。
次に送信ボタンです。
submit_button()
以下のHTMLを吐き出します。
<p class="submit">
<input type="submit" name="submit" id="submit" class="button button-primary" value="変更を保存">
</p>
早速送信ボタンを押す!
・・・。
オプションとの連携
WordPressのオプションについてあらかじめ知っておく必要があります。
データベースにwp_options
というテーブルがあって、
WordPressでKeyValue的なデータを扱うものです。
分からない人はget_option()
やset_option()
などを調べてみてください。
WordPressのoptions.php
はこのオプションをうまく処理してくれます。
add_action('admin_menu', function(){
function showPage()
{
?>
<div class="wrap">
<h2>テキストの追加</h2>
<form action="options.php" method="POST">
<?php settings_fields('kurage') ?>
<h3>text 1</h3>
<input
type="text"
id="kurage_text_1"
name="kurage_text_1"
value="<?php echo esc_attr( get_option('kurage_text_1') ) ?>" />
<h3>text 2</h3>
<input
type="text"
id="kurage_text_2"
name="kurage_text_2"
value="<?php echo esc_attr( get_option('kurage_text_2') ) ?>" />
<h3>text 3</h3>
<input
type="text"
id="kurage_text_3"
name="kurage_text_3"
value="<?php echo esc_attr( get_option('kurage_text_3') ) ?>" />
<?php submit_button() ?>
</form>
</div>
<?php
}
add_menu_page(
'クラゲ管理画面',
'クラゲメニュー設定',
'manage_options',
'kurage',
function()
{
showPage();
}
);
});
add_action('admin_init', function(){
register_setting('kurage', 'kurage_text_1');
register_setting('kurage', 'kurage_text_3');
});
以下のページが表示されるので、適当に入力していきます。
送信ボタンを押した後、DBを確認してみましょう。
以下のクエリを投げます。
select * from wp_options where option_name like 'kurage\_text\_%';
kurage_text_1
には111
が、
kurage_text_3
には333
が入ってます。
ただし、
kurage_text_2
には222
は入ってません。
どのような仕組みでしょう!?
まずフォームの一つ目を見てください。
<input
type="text"
id="kurage_text_1"
name="kurage_text_1"
value="<?php echo esc_attr( get_option('kurage_text_1') ) ?>" />
name
がkurage_text_1
となってます。
value
はオプションからkurage_text_1
を取得してサニタイズしたものを与えてます。
他の入力要素も同じような感じです。
ボタンを送信するとkurage_text_1
, kurage_text_2
, kurage_text_3
の入力値が送信されます。
次にPHP側の設定です。
register_setting('kurage', 'kurage_text_1');
register_setting('kurage', 'kurage_text_3');
register_setting()
はフォームの値をオプションにマッピングし自動更新出来るように設定します。
この例では、POSTリクエストのaction
がupdate
であり、
管理ページのスラグ(option_page
)がkurage
の時、
リクエスト中にkurage_text_1
かkurage_text_3
が入っていたらその名前と値のセットを自動的にオプションにたいして更新させますよ、
っていう設定です。
なのでkurage_text_2
はリクエストで渡したものの、
オプションには追加されず無視されました。
その様子をoptions.php
のある部分(update_option()が実行されている箇所
)にブレークポイントを張って調べてみましょう。
Watch式に注目してください。
kurage_text_1
の情報
kurage_text_3
の情報
Settings
Settingsについてです。
この機能は、管理画面の入力フィールドを描画するための機能なようで、
描画する場所に張る関数と、描画するための設定を登録する関数があります。
描画する場所に張る関数は
do_settings_fields()
,do_settings_sections()
描画するための設定を登録する関数
add_settings_field()
,add_settings_section()
これらの関数は引数に何を渡せばいいのか非常に分かりづらかったです。
最初にざっくり概念を知ってないと引数が多すぎてどれがどの値なのか混乱します。
管理画面には、管理画面を識別するスラグ(今回の例ではkurage
があります)。
設定画面には、値を入力するフィールドを記述しますが、セクションでそれらを分割することが出来ます。
ちょっと分かりにくいので画像にするとこんな感じです。
まず管理ページの(kurage
)があって、
その下に3つのセクションがあって、それぞれID(今回はそれぞれnumber
, alfabet
, symbol
)を付けてます(任意につけることが出来ます)。
さらにそのセクション下に入力フィールド(それぞれテキストフィールド3つ)を追加している状態です。
つまり、
管理ページスラグ -> セクション -> フィールド
という階層構造になってます。
この構造を作るには、セクションの登録にadd_settings_section()
を、
フィールドの登録にadd_settings_field()
を使います。
do_settings_sections(管理ページスラグ)
を使って3つのセクションをまとめて描画します。
do_settings_fields(管理ページスラグ, セクションID)
を使って対象のセクションにあるフィールドをまとめて描画します。
では今回の例を再現してみましょう。
add_action('admin_menu', function(){
function showPage()
{
?>
<div class="wrap">
<h2>テキストの追加</h2>
<form action="options.php" method="POST">
<?php settings_fields('kurage') ?>
<?php do_settings_sections('kurage') ?>
<?php submit_button() ?>
<?php
}
add_menu_page(
'クラゲ管理画面',
'クラゲメニュー設定',
'manage_options',
'kurage',
function()
{
showPage();
}
);
});
add_action('admin_init', function(){
$callback = fn() => print('<input type="text" />');
// セクションの設定
add_settings_section('number', '数値の項目', null, 'kurage');
add_settings_section('alfabet', 'アルファベットの項目', null, 'kurage');
add_settings_section('symbol', '記号の項目', null, 'kurage');
// numberセクションに追加するフィールドの設定
add_settings_field('one', 'すうじの1', $callback, 'kurage', 'number');
add_settings_field('two', 'すうじの2', $callback, 'kurage', 'number');
add_settings_field('three', 'すうじの3', $callback, 'kurage', 'number');
// alfabetセクションに追加するフィールドの設定
add_settings_field('a', 'あるふぁべっとのA', $callback, 'kurage', 'alfabet');
add_settings_field('b', 'あるふぁべっとのB', $callback, 'kurage', 'alfabet');
add_settings_field('c', 'あるふぁべっとのC', $callback, 'kurage', 'alfabet');
// symbolセクションに追加するフィールドの設定
add_settings_field('plus', '記号の +', $callback, 'kurage', 'symbol');
add_settings_field('minus', '記号の -', $callback, 'kurage', 'symbol');
add_settings_field('dollar', '記号の $', $callback, 'kurage', 'symbol');
});
以下が結果です。
add_settings_section()
はセクションを登録します。
add_settings_section('number', '数値の項目', null, 'kurage');
第一引数がセクションのIDとなるものでnumber
を指定しました(名前は任意です。)。
第四引数は管理ページのスラグでkurage
を指定しました。
これで
kurage -> number
という階層のセクションを登録しました。
あとalfabet
とsymbol
も同様にセクションを登録していきます。
第二引数はラベルです。
do_settings_sections()
によってセクションごとに描画されます。
次にadd_settings_field()
でフィールドを登録します。
add_settings_field('one', 'すうじの1', $callback, 'kurage', 'number');
第一引数がセクションのIDで、
第四引数が管理画面のスラグ、
第五引数がセクションのIDです。
これで
kurage -> number -> one
という階層のフィールドを登録しました。
第三引数はINPUT要素などを描画するコールバック関数を指定します。
今回は面倒なので全部未記入のテキストフィールドを返すコールバック関数を指定しました。
そして描画するにはdo_settings_sections()
を使います。
do_settings_sections('kurage')
引数に管理画面のスラグを渡すことで、その管理画面に属する全てのセクション、フィールドをまとめて描画します。
セクション単位の描画
全セクションの描画をしましたが、セクション単位の描画もできはします。
もしdo_settings_sections('kurage')
の部分をdo_settings_fields()
に置き換えるとどうなるでしょう。
function showPage()
{
?>
<div class="wrap">
<h2>テキストの追加</h2>
<form action="options.php" method="POST">
<?php settings_fields('kurage') ?>
<table>
<?php do_settings_fields('kurage', 'alfabet') ?>
</table>
<?php submit_button() ?>
<?php
}
今回の例はdo_settings_fields('kurage', 'alfabet')
を使いました。
管理画面(kurage
)のセクション(alfabet
)にあるフィールド一覧を描画します。
注意しないといけないのは、この関数はTABLEタグ
を描画しません。
いきなりテーブルの行をフィールド数の分描画します。
そのため自分でTABLEで囲んでやる必要があります。
そして本来do_settings_fields()
はdo_settings_sections()
によって内部的に呼び出されるもので直接呼び出すものでもなさそうです。
ちなみにdo_settings_sections()
ではTABLEに追加されるクラス(CSS)もあるのです。
フィールドの作成
また、以下のようにフィールドを作成することが出来ます。
add_action('admin_menu', function(){
function showPage()
{
?>
<div class="wrap">
<h2>テキストの追加</h2>
<form action="options.php" method="POST">
<?php settings_fields('kurage') ?>
<table>
<?php do_settings_sections('kurage') ?>
</table>
<?php submit_button() ?>
<?php
}
add_menu_page(
'クラゲ管理画面',
'クラゲメニュー設定',
'manage_options',
'kurage',
function()
{
showPage();
}
);
});
add_action('admin_init', function(){
$callback = fn($args) => printf('<input type="text" name="%s" value="%s"/>', esc_attr($args[0]), esc_attr($args[1]));
// セクションの設定
add_settings_section('number', '数値の項目', null, 'kurage');
// numberセクションに追加するフィールドの設定
add_settings_field('one', 'すうじの1', $callback, 'kurage', 'number', ['one', 111]);
add_settings_field('two', 'すうじの2', $callback, 'kurage', 'number', ['two', 222]);
add_settings_field('three', 'すうじの3', $callback, 'kurage', 'number', ['three', 333]);
});
add_settings_field()
の第六引数ではコールバックに渡す引数を指定することが出来ます。
add_settings_field('one', 'すうじの1', $callback, 'kurage', 'number', ['one', 111]);
一行で長いですが、コールバックではテキストフィールドにname
とvalue
を指定出来るようにしました。
fn($args) => printf('<input type="text" name="%s" value="%s"/>', esc_attr($args[0]), esc_attr($args[1]));
これで入力済のフィールドを描画出来るようになりました。
本体の設定ページに追加
ところでWordPress本体の設定画面がありますよね。
例えば設定
からメディア
を開いてみてください。
画像サイズの設定などの項目があります。
この管理画面は/wp-admin/options-media.php
で実装されています。
そのソースコードの一部を見ると
</tr>
<?php do_settings_fields( 'media', 'uploads' ); ?>
</table>
<?php endif; ?>
<?php do_settings_sections( 'media' ); ?>
<?php submit_button(); ?>
などのように定義されています!
ということは、本体の設定画面にセクションやフィールドを追加出来るということですね。
add_action('admin_init', function(){
// media の uploads セクションに追加
add_settings_field('kurage-uploader', 'クラゲアップローダー', fn() => print('... 省略'), 'media', 'uploads');
// media にセクションごと追加
add_settings_section('kurage-section', 'クラゲセクション', null, 'media');
add_settings_field('kurage-a', 'クラゲA', fn() => print('AAA'), 'media', 'kurage-section');
add_settings_field('kurage-b', 'クラゲB', fn() => print('BBB'), 'media', 'kurage-section');
add_settings_field('kurage-c', 'クラゲC', fn() => print('CCC'), 'media', 'kurage-section');
});
これで目的の場所にフィールドを追加出来るようになりました。