前回、プラグイン独自の管理画面を作成し、タイトルのみ表示できるようになりました。今回は、設定値を表示・編集するためのフィールドを作成し、データベースに保存できるようにします。
Settings API
WordPressではSettings APIを利用することで、決まった方法でデータベースに設定を保存・管理することができます。そのために、設定用のページにセクションとフィールドを作成します。
セクション
セクションとは、フィールドをグループ分けしたものです。設定値が少ない場合は一つのセクションで十分ですが、多い場合は内容に合わせて複数のセクションを定義することができます。今回は一つだけセクションを作成します。
add_settings_section( string $id, string $title, callable $callback, string $page, array $args = array() )
https://developer.wordpress.org/reference/functions/add_settings_section/
値 | 型 | 必須 | デフォルト値 | 内容 |
---|---|---|---|---|
第1引数 | string 型の$id | 必須 | セクションを識別するためのスラグ | |
第2引数 | string 型の$title | 必須 | セクション見出しとして表示されるテキスト | |
第3引数 | callable 型の$callbak | 必須 | セクションの最初に描画されるHTMLを指定するコールバック関数 | |
第4引数 | string 型の$page | 必須 | 設定を表示するページのスラグ | |
第5引数 | array 型の$args | 任意 | array() | その他のセクションの設定(前後に描画するHTMLやクラス名など) |
フィールド
各セクションには、複数のフォールドを含むことができます。一つのセクションに一つの設定値を対応させるイメージです。今回は、get_post_types
関数でカスタム投稿タイプを取得し、foreach
でループしてカスタム投稿タイプの数だけフィールドを作成します。
add_settings_field( string $id, string $title, callable $callback, string $page, string $section = ‘default’, array $args = array() )
https://developer.wordpress.org/reference/functions/add_settings_field/
値 | 型 | 必須 | デフォルト値 | 内容 |
---|---|---|---|---|
第1引数 | string 型の$id | 必須 | フィールドを識別するためのスラグ | |
第2引数 | string 型の$title | 必須 | フィールド見出しとして表示されるテキスト | |
第3引数 | callable 型の$callbak | 必須 | フィールドに描画されるHTMLを指定するコールバック関数 | |
第4引数 | string 型の$page | 必須 | 設定を表示するセクションのスラグ | |
第5引数 | string 型の$section | 任意 | ‘default’ | フィールドを配置するセクションのスラグ |
第5引数 | array 型の$args | 任意 | array() | その他のフィールドの設定。ラベル名やクラス名など。コールバック関数に渡される |
設定値の登録
register_setting()
でフィールドグループに登録します。これにより、フィールドの値が自動的に保存されるようになります。
register_setting( string $option_group, string $option_name, array $args = array() )
https://developer.wordpress.org/reference/functions/register_setting/
値 | 型 | 必須 | デフォルト値 | 内容 |
---|---|---|---|---|
第1引数 | string 型の$option_group | 必須 | 設定グループ名。settings_fields で参照する | |
第2引数 | string 型の$option_name | 必須 | オプション名。データベース上にこの名前で保存される | |
第3引数 | array 型の$args | 任意 | array() | その他のオプションの設定。サニタイズ関数やデフォルト値など |
フック
drnp_section_field_init()
関数をadmin_init
にフックし、add_settings_section()
、add_settings_field()
、register_setting()
を実行します。
また、drnp_section_html()
コールバック関数、drnp_field_html()
コールバック関数を追加し、それぞれセクションの説明文とフィールドの<input>
タグを準備します。
ここまででセクション、フィールドを追加する下準備ができました。
function drnp_section_field_init() {
add_settings_section(
'drnp_section',
'Dashboard Right Now Section',
'drnp_section_html',
'dashboard-right-now-plus'
);
$args = array(
'public' => true,
'_builtin' => false,
);
$custom_post_types = get_post_types( $args, 'object', 'and' );
foreach ( $custom_post_types as $custom_post_type ) {
add_settings_field(
'drnp_field_' . $custom_post_type->name,
$custom_post_type->labels->name,
'drnp_field_html',
'dashboard-right-now-plus',
'drnp_section',
array(
'name' => $custom_post_type->name,
)
);
register_setting(
'drnp_field',
'drnp_cpt_' . $custom_post_type->name . '_dashicon',
'esc_attr'
);
}
}
add_action( 'admin_init', 'drnp_section_field_init' );
dashboard-right-now-plus.phpfunction drnp_section_html() {
echo '概要メタボックスでカスタム投稿タイプに表示される dashicon 名を設定';
}
dashboard-right-now-plus.phpfunction drnp_field_html( $args ) {
printf(
'<input type="text" name="drnp_cpt_%s_dashicon" id="drnp_cpt_%s_dashicon" value="%s" />',
esc_attr( $args['name'] ),
esc_attr( $args['name'] ),
esc_attr( get_option( 'drnp_cpt_' . $args['name'] . '_dashicon' ) )
);
}
dashboard-right-now-plus.phpセクションにフィールドを描画
最後に、do_settings_sections()、settings_fields()、submit_button()でフィールドを描画します。
function drnp_add_options_page_html() {
echo '<div class="wrap">';
echo '<h1>Dashboard Right Now Plus Setting</h1>';
echo '<form method="post" action="options.php">';
do_settings_sections( 'dashboard-right-now-plus' );
settings_fields( 'drnp_field' );
submit_button();
echo '</form>';
echo '</div>';
}
dashboard-right-now-plus.phpコードまとめ
<?php
/**
* Dashboard Right Now Plus
*
* @package DashboardRightNowPlus
*
* @wordpress-plugin
* Plugin Name: Dashboard Right Now Plus
* Plugin URI: https://gist.github.com/web83info/5747ac715e4544b408e91e2ec034ab05/
* Description: Add custom post type to "Right Now" meta box on WordPress dashboard
* Version: 1.0.0
* Requires at least: 6.4
* Requires PHP: 7.2
* Author: web83info
* Author URI: https://labs.web83.info/
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/
/**
* カスタム投稿タイプ drnp-mycpt-a, drnp-mycpt-b を追加
*
* @return void
*/
function drnp_add_my_custom_post_type() {
$custom_post_types = array(
'drnp-mycpt-a' => array(
'type' => 'drnp-mycpt-a',
'name' => 'マイCPT-A',
'menu_icon' => 'dashicons-bell',
),
'drnp-mycpt-b' => array(
'type' => 'drnp-mycpt-b',
'name' => 'マイCPT-B',
'menu_icon' => 'dashicons-heart',
),
);
foreach ( $custom_post_types as $custom_post_type ) {
$dashicon_key = 'drnp_cpt_' . $custom_post_type['type'] . '_dashicon';
add_option( $dashicon_key, $custom_post_type['menu_icon'] );
register_post_type(
$custom_post_type['type'],
array(
'labels' => array(
'name' => $custom_post_type['name'],
'singular_name' => $custom_post_type['name'],
),
'public' => true,
'menu_icon' => $custom_post_type['menu_icon'],
)
);
if ( 0 === wp_count_posts( $custom_post_type['type'] )->publish ) {
for ( $i = 1; $i <= 3; $i++ ) {
wp_insert_post(
array(
'post_type' => $custom_post_type['type'],
'post_title' => $custom_post_type['name'] . ' 記事 #' . $i,
'post_status' => 'publish',
)
);
}
}
}
}
add_action( 'init', 'drnp_add_my_custom_post_type' );
/**
* アンインストール時にカスタム投稿タイプ drnp-mycpt-a, drnp-mycpt-b の記事を削除
*
* @return void
*/
function drnp_uninstall_my_custom_post_type() {
$args = array(
'post_type' => array(
'drnp-mycpt-a',
'drnp-mycpt-b',
),
'numberposts' => -1,
);
$posts = get_posts( $args );
foreach ( $posts as $post ) {
wp_delete_post( $post->ID );
}
}
register_uninstall_hook( __FILE__, 'drnp_uninstall_my_custom_post_type' );
/**
* 概要メタボックスにカスタム投稿タイプの件数を表示
*
* @param array $elements 追加表示させる内容.
* @return array 追加表示させる内容.
*/
function drnp_add_my_custom_post_type_to_right_now( $elements ) {
$args = array(
'public' => true,
'_builtin' => false,
);
$custom_post_types = get_post_types( $args, 'object', 'and' );
foreach ( $custom_post_types as $custom_post_type ) {
$num_posts = wp_count_posts( $custom_post_type->name );
if ( $num_posts && $num_posts->publish ) {
$text = sprintf( '%s件の%s', number_format_i18n( $num_posts->publish ), $custom_post_type->labels->name );
$dashicon = get_option( 'drnp_cpt_' . $custom_post_type->name . '_dashicon' );
if ( current_user_can( $custom_post_type->cap->edit_posts ) ) {
$elements[] = sprintf(
'<a class="drnp-cpt %1$s-count" href="edit.php?post_type=%1$s"><span class="drnp-cpt-icon dashicons %3$s"></span>%2$s</a>',
esc_html( $custom_post_type->name ),
esc_html( $text ),
esc_html( $dashicon )
);
} else {
$elements[] = sprintf(
'<span class="drnp-cpt %1$s-count"><span class="drnp-cpt-icon dashicons %3$s"></span>%2$s</span></li>',
esc_html( $custom_post_type->name ),
esc_html( $text ),
esc_html( $dashicon )
);
}
}
}
return $elements;
}
add_filter( 'dashboard_glance_items', 'drnp_add_my_custom_post_type_to_right_now' );
/**
* 管理画面でのみ読み込む CSS
*
* @return void
*/
function drnp_add_my_admin_style() {
echo <<< 'EOT'
<style>
#dashboard_right_now .drnp-cpt:before {
content: none !important;
}
#dashboard_right_now .drnp-cpt-icon {
padding: 0 5px 0 0;
}
</style>
EOT;
}
add_action( 'admin_enqueue_scripts', 'drnp_add_my_admin_style' );
/**
* 管理画面のメニューに options.php を読み込む
*
* @return void
*/
function drnp_add_options_php() {
add_submenu_page(
'options-general.php',
'Options',
'Options',
'manage_options',
'options.php'
);
}
add_action( 'admin_menu', 'drnp_add_options_php' );
/**
* 管理画面のメニューにプラグイン独自の設定画面を作成する
*
* @return void
*/
function drnp_add_options_page() {
add_options_page(
'Dashboard Right Now Plus',
'Dashboard Right Now Plus',
'manage_options',
'dashboard-right-now-plus',
'drnp_add_options_page_html'
);
}
add_action( 'admin_menu', 'drnp_add_options_page' );
/**
* プラグイン独自の設定画面の表示内容
*
* @return void
*/
function drnp_add_options_page_html() {
echo '<div class="wrap">';
echo '<h1>Dashboard Right Now Plus Setting</h1>';
echo '<form method="post" action="options.php">';
do_settings_sections( 'dashboard-right-now-plus' );
settings_fields( 'drnp_field' );
submit_button();
echo '</form>';
echo '</div>';
}
/**
* 管理画面のメニューにセクション・フィールドを追加する
*
* @return void
*/
function drnp_section_field_init() {
// セクションを追加.
add_settings_section(
'drnp_section',
'Dashboard Right Now Section',
'drnp_section_html',
'dashboard-right-now-plus'
);
// フィールドを追加.
$args = array(
'public' => true,
'_builtin' => false,
);
$custom_post_types = get_post_types( $args, 'object', 'and' );
foreach ( $custom_post_types as $custom_post_type ) {
add_settings_field(
'drnp_field_' . $custom_post_type->name,
$custom_post_type->labels->name,
'drnp_field_html',
'dashboard-right-now-plus',
'drnp_section',
array(
'name' => $custom_post_type->name,
)
);
register_setting(
'drnp_field',
'drnp_cpt_' . $custom_post_type->name . '_dashicon',
'esc_attr'
);
}
}
add_action( 'admin_init', 'drnp_section_field_init' );
/**
* セクション下の表示内容
*
* @return void
*/
function drnp_section_html() {
echo '概要メタボックスでカスタム投稿タイプに表示される dashicon 名を設定';
}
/**
* フィールドの表示内容
*
* @param array $args カスタム投稿タイプ名.
* @return void
*/
function drnp_field_html( $args ) {
printf(
'<input type="text" name="drnp_cpt_%s_dashicon" id="drnp_cpt_%s_dashicon" value="%s" />',
esc_attr( $args['name'] ),
esc_attr( $args['name'] ),
esc_attr( get_option( 'drnp_cpt_' . $args['name'] . '_dashicon' ) )
);
}
dashboard-right-now-plus.php