WordPressのプラグイン開発時での管理画面のコーディング例です。
WordPress管理画面に登録する際のアクションフックの記述方法などいくつか悩んだポイントがありましたので参考までに解説します。
WordPressで管理画面をつくるサンプルコード
class-admin.php
<?php
/**
* 管理画面コントローラー
*/
if (!defined('ABSPATH')) exit;
require_once __DIR__ . '/view-admin.php';
// オプション名設定
define('MY_EXT_OPTION', 'my_ext_option');
class adminController
{
/**
* コンストラクタ
*/
function __construct()
{
// WordPress管理画面にメニュー登録するアクションフック
add_action('admin_menu', array($this, 'my_ext_create_menu'));
// WordPress設定を登録するアクションフック
add_action('admin_init', array($this, 'register_my_ext_settings'));
}
/**
* WordPress管理画面にメニュー追加
*/
public function my_ext_create_menu()
{
// トップレベルメニューを登録
add_menu_page(
'MYSETTING',
'設定',
'administrator',
dirname(__DIR__), //スラッグをプラグインディレクトリ名にする
array($this, 'my_ext_settings_page')
);
}
/**
* WordPress設定登録
*/
function register_my_ext_settings()
{
register_setting('my-ext-options', 'my_ext_option');
}
/**
* WordPress設定ページを出力
*/
public function my_ext_settings_page()
{
$html = viewAdmin::get_settings_page_html();
echo $html;
}
}
?>
ポイント
WordPress管理画面の登録
WordPressの管理画面にメニュー項目を登録するには ‘admin_menu’ アクションフックを利用します。
テーマのfunctions.phpなどにコードを記述する場合や、クラス化せずにそのまま記述するような場合は以下のような書き方になります。
add_action('admin_menu', 'my_ext_create_menu');
public function my_ext_create_menu()
{
// トップレベルメニューを登録
add_menu_page(
'MYSETTING',
'設定',
'administrator',
'menu-slug',
'my_ext_settings_page'
);
}
が、クラス化するような場合、add_actionはコンストラクタなどで呼び出しを行います。
function __construct()
{
add_action('admin_menu', array($this, 'my_ext_create_menu'));
}
また、add_actionの第2引数には add_menu_page 関数を指定しますが、プラグインなどでクラスのメンバとして記述する場合は上記のように配列array($this, 関数名)
で指定する必要があります。add_action('admin_menu', 'my_ext_create_menu');
やadd_action('admin_menu', $this->my_ext_create_menu());
などの指定では動きません。
add_menu_pageの記述
管理画面のメニュー項目や設定画面の出力関数などの指定は ‘add_menu_page’ 関数で行います。ここでも同じようにメニューページを表示する際に実行する関数を指定するには配列array($this, 関数名)
を使用します。
add_menu_page(
'MYSETTING',
'設定',
'administrator',
dirname(__DIR__), //スラッグをプラグインディレクトリ名にする
array($this, 'my_ext_settings_page')
);
また、メニューページを出力する関数は、返り値ではなくバッファ出力(echoなど)する必要があります。
/**
* WordPress設定ページを出力
*/
public function my_ext_settings_page()
{
$html = viewAdmin::get_settings_page_html();
echo $html;
}
上記の例では viewAdminクラス(後述)の静的メソッドを使ってメニューページのHTMLを取得してecho $html;
で表示していますが、return $html;
などで戻しても画面には何も表示されませんので注意してください。
view-admin.php
<?php
/**
* 管理画面HTMLビューテンプレート
*/
if (!defined('ABSPATH')) exit;
class adminView
{
/**
* WordPress設定ページを出力
*/
public static function get_settings_page_html()
{
ob_start();
?>
<div class="wrap">
<h1>プラグイン設定</h1>
<?php
if (true == @$_GET['settings-updated']) : ?>
<div id="settings_updated" class="updated notice is-dismissible">
<p><strong>設定を保存しました。</strong></p>
</div>
<?php endif; ?>
<form method="post" action="options.php">
<?php
settings_fields('my-ext-options');
do_settings_sections('my-ext-options');
$options = get_option(MY_EXT_OPTION);
//var_dump($options);
?>
<div class="postbox">
<h3 class="hndle">全般</h3>
<div class="inside">
<table class="form-table">
<tr valign="top">
<th scope="row">設定1</th>
<td><input type="text" size="60" class="code" name="cravel_ext_option[value1]" value="<?php echo esc_attr(@$options['value1']); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row">設定2</th>
<td><input type="text" size="60" class="code" name="cravel_ext_option[value2]" value="<?php echo esc_attr(@$options['value2']); ?>" /></td>
</tr>
<tr valign="top">
<th scope="row">設定3</th>
<td><input type="text" size="60" class="code" name="cravel_ext_option[value3]" value="<?php echo esc_attr(@$options['value3']); ?>" /></td>
</tr>
</table>
</div>
</div>
<?php submit_button(); ?>
</form>
</div>
<?php
$html = ob_get_contents();
ob_end_clean();
return $html;
}
}
ポイント
if (!defined(‘ABSPATH’)) exit;
最初に記述しているif (!defined('ABSPATH')) exit;
は、このファイルに直接アクセスして不正な処理を行われないようにするための対策のひとつです。この記述によってWordPressのシステムから以外にこのファイルが読みだされても記述以下の内容が実行されないようになります。
似たようなセキュリティ対策の記述方法はいろいろありますが、WordPressのテーマ開発やプラグイン開発ではこの方法がシンプルで慣習化されていますのでほぼ定型文として覚えておけば問題ないと思います。
クラスメソッドの静的呼び出し
phpファイルに関数をべた書きしても良いのですが、ここではhtml出力関連の処理をまとめてひとつのクラスとして記述しています。
このクラスではインスタンス化せずに直接メソッドを実行できる「静的呼び出し」を使っています。静的メソッドの定義はstatic
を使って行います。
class adminView
{
public static function get_settings_page_html()
{
/* 静的メソッド */
}
}
このようにしておくことで、adminView::get_settings_page_html();
のような記述で直接クラス内のget_settings_page_htmlを呼び出すことができます。
ob_startによる出力のバッファリング
ビューを生成する際、htmlタグを文字列変数で切り貼りすることも多いと思いますが、文字列が長くなってしまうと収拾がつかなくなってしまうことも多いと思います。
<?php
function my_function($head, $items) {
$html = '';
$html .= '<div class="classA">';
$html .= '<h2>'.$head.'</h2>';
$html .= '<ul>'
foreach($items as $item) {
$html .= '<li><a href="'.$item['url'].'">".$item['title'].'</a>';
}
$html .= '</ul>'
;
$html = '</div>';
return $html;
}
?>
今回の例ではメインのHTML出力部分を「出力バッファリング制御」を使ってソースコードを記述しています。よく使用する出力バッファリングにはob_start()
(バッファリングの開始)、ob_get_contents()
(バッファの内容を取得)、ob_end_clean()
(バッファリング終了してクリア)で、この3つを使うと簡単にphpの関数内にHTMLをべた書きするような記述が可能になります。
<?php
function my_function($head, $items) {
ob_start();
?>
<div class="classA">
<h2>'.$head.'</h2>
<ul>
<?php
foreach($items as $item) {
?>
<li><a href="<?= $item['url'] ?>"><?= $item['title'] ?></a>
<?php
}
?>
</ul>
</div>
<?php
$html = ob_get_contents();
ob_end_clean();
return $html;
}
?>
上記の例では、ob_start();
から$html = ob_get_contents();
の間に出力された内容がリアルタイムで表示されることなく、結果を$html
に格納することができます。
前述のコードと比べてそれほどコード量の違いはないかもしれませんが、出力するHTMLの長さや内容によってはより判読しやすく編集がしやすいコード記述ができる場合もあるので覚えておくと便利です。
コメント