管理画面に独自設定ページを追加する

ワードプレス

2021.04.16

 

上記記事でも使っているsettings_fields()を使うと、

  • ソース行が半分以下になる場合もあり、追加・削除等もかなり楽になる
  • 保存用のダミーデータが不要

等、かなりいい感じなので全面書き換えしました。

コピペで動くと思いますが、動かない場合は上記参考記事のほうをご覧ください。

 

テーマにいろいろな機能を追加していくと、それらを一括して管理できる機能が欲しくなってきます。

そこで、管理画面に設定ページを追加、UIで変更できるようにしよう、というお話です。

ソース

<?php
//サイト設定ページ追加
add_action( 'admin_menu', 'add_site_settings_menu' );
function add_site_settings_menu() {
	add_menu_page( 'サイト設定ページ', 'サイト設定', 'manage_options', 'site_settings', 'site_settings_page', '' );
	add_action( 'admin_init', 'register_custom_setting' );
}
function site_settings_page() {
?>
<div class="wrap">
<h2>サイト設定</h2>
<form method="post" action="options.php" enctype="multipart/form-data" encoding="multipart/form-data">
<?php
settings_fields( 'custom-menu-group' );
do_settings_sections( 'custom-menu-group' );
submit_button();
?>
<table class="form-table setting-table">
	<tr>
		<th><label for="theme_option_post_label">標準投稿の名称</label></th>
		<td colspan="2"><input name="theme_option_post_label" type="text" id="theme_option_post_label" value="<?php form_option( 'theme_option_post_label' ); ?>" class="regular-text" /></td>
	</tr>
	<tr>
		<th>グリッド間隔</th>
		<td colspan="2"><p><label><input name="theme_option_radio_grid_gap" type="radio" value="2" <?php checked( 2, get_option( 'theme_option_radio_grid_gap' ) ); ?> />2%</label> <label><input name="theme_option_radio_grid_gap" type="radio" value="3" <?php checked( 3, get_option( 'theme_option_radio_grid_gap' ) ); ?> />3%</label> <label><input name="theme_option_radio_grid_gap" type="radio" value="default" <?php checked( 'default', get_option( 'theme_option_radio_grid_gap' ) ); ?> />指定しない</label></p></td>
	</tr>
	<tr>
		<th scope="row"><label for="theme_option_head_script">head内にスクリプトを挿入する</label></th>
		<td><p><label><input name="theme_option_head_script" type="checkbox" id="theme_option_head_script" value="1" <?php checked( 1, get_option( 'theme_option_head_script' ) ); ?> />する</label></p>
			<textarea name="theme_option_head_script_source" id="theme_option_head_script_source" class="large-text code" rows="12"><?php echo esc_textarea( get_option( 'theme_option_head_script_source' ) ); ?></textarea></td>
	</tr>
</table>
<?php submit_button(); ?>
</form>
</div>
<?php
}
function register_custom_setting() {
	//標準投稿の名称
	register_setting( 'custom-menu-group', 'theme_option_post_label' );
	//グリッド間隔
	register_setting( 'custom-menu-group', 'theme_option_radio_grid_gap' );
	//スクリプト挿入
	register_setting( 'custom-menu-group', 'theme_option_head_script' );
	register_setting( 'custom-menu-group', 'theme_option_head_script_source' );
}
?>

テキスト、テキストエリア、チェックボックス、ラジオボタンと、一通りのUI例です。

メニュー名・ページ名・URL等、好きに書き換えていいのですが、12行目の「action=”options.php”」はお約束のようで、ほかのファイル名や空白では動作しませんでした。

出力

get_option( ‘オプション名’ )で呼び出して、そのまま出力するなり、条件分岐させるなり。

$post_label = get_option( 'theme_option_post_label' );
echo $post_label;

$grid_gap = get_option( 'theme_option_radio_grid_gap' );
if( $grid_gap === 1 ){
	echo '<link rel="stylesheet" href="' . bloginfo( 'stylesheet_directory' ) . '/css/grid-gap-2p.css">'; 
}

$head_script = get_option( 'theme_option_head_script' );
$head_script_source = get_option( 'theme_option_head_script_source' );
if( $head_script && $head_script_source ){
	echo $head_script_source;
}

サブメニュー

ついでにサブメニューも。

上記の設定画面にサブメニュー「オプション一覧・オプションリセット」を追加する、という例です。

中身の書き方は大体同じで、メニュー名・ページ名・URLを好きなように設定できますが、「settings_fields」はダブらないよう別名に!

/* ---------- サブメニュー ---------- */
add_action( 'admin_menu', 'add_site_settings_submenu' );
function add_site_settings_submenu() {
	add_submenu_page( 'site_settings' , 'options.php', 'オプション一覧', 'manage_options', 'options.php');
	add_submenu_page( 'site_settings', '設定リセット', '設定リセット', 'manage_options', 'site_settings_submenu_page', 'site_settings_submenu_page', '');
	add_action( 'admin_init', 'register_custom_setting_submenu' );
}
function site_settings_submenu_page() {
?>
<div class="wrap">
<h2>サイト設定リセット</h2>
<form method="post" action="options.php" enctype="multipart/form-data" encoding="multipart/form-data">
<?php
settings_fields( 'custom-menu-group-submenu' );
do_settings_sections( 'custom-menu-group-submenu' );
submit_button();
?>
<table class="form-table setting-table">
	<tr>
		<th scope="row"><label for="theme_option_radio_reset">テーマオプション - ラジオボタンだけをリセットする</label></th>
		<td><label><input name="theme_option_radio_reset" type="checkbox" id="theme_option_radio_reset" value="1" <?php checked( 1, get_option('theme_option_radio_reset')); ?> />リセットする</label></td>
	</tr>
	<tr>
		<th scope="row"><label for="theme_option_all_reset">テーマオプション - 全てをリセットする</label></th>
		<td><label><input name="theme_option_all_reset" type="checkbox" id="theme_option_all_reset" value="1" <?php checked( 1, get_option('theme_option_all_reset')); ?> />リセットする</label></td>
	</tr>
</table>
<h4 style="color: #F00; font-weight: bold;">リセットすると元には戻せません。実行は慎重に。</h4>
<?php submit_button(); ?>
</form>
</div>
<?php
}
function register_custom_setting_submenu() {
	register_setting( 'custom-menu-group-submenu', 'theme_option_radio_reset' );
	register_setting( 'custom-menu-group-submenu', 'theme_option_all_reset' );
}
  • 「オプション一覧」はWP標準の設定画面

メニューの出現位置

蛇足ですが、

add_menu_pageの引数でメニュー位置を指定していないのですが、これは個々に指定するのが面倒だから。

 

こんな感じに、一括でメニューの順番を変えています。

//管理画面メニューの表示順
function custom_menu_order( $menu_ord ) {
	if ( !$menu_ord ) return true;
	return array(
		'index.php', //ダッシュボード
		'edit.php?post_type=page', //固定ページ
		'edit.php', //投稿
		'edit.php?post_type=news', //カスタム投稿
		'site_settings',//追加した設定ページ
		'separator1',
		'upload.php', //メディア
		'users.php', //ユーザー
		'separator2',
		'themes.php', //テーマ
		'options-general.php', //設定
		'tools.php', //ツール
		'plugins.php', //プラグイン
		'separator-last',
	);
}
add_filter( 'custom_menu_order', 'custom_menu_order' );
add_filter( 'menu_order', 'custom_menu_order' );

ビジュアルエディタを呼び出す

ブロックエディタの時代に入ってきているので今更感もありますが、

テキストエリアの代わりにビジュアルエディタ(TinyMCE)を使いたい場合もあろうかと、検索してみるもほとんど見つからない。

すごく難しいor面倒なのか???

 

とりあえず、

をたよりに適当に試してみました。(ソースの30行目を置き換え)

<?php /* 変更前 - テキストエリア */ ?>
<textarea name="theme_option_head_script_source" id="theme_option_head_script_source" class="large-text code" rows="12"><?php echo esc_textarea( get_option( 'theme_option_head_script_source' ) ); ?></textarea>

<?php
/* ---------- 変更後 - tynyMCE ---------- */
$content = get_option( 'theme_option_head_script_source' );
$editor_id = 'theme_option_head_script_source';
$settings = array(
	'textarea_rows'	=> 8
);
wp_editor( $content, $editor_id, $settings );
?>

こんなんでいいのか分からないけど、

  • 追加したスタイル、ボタン類も表示され、正常に機能している。
  • テキストモードにしてスクリプトを入れれば正常に動く。

むむ、意外に簡単。

設定も、表示行数、改行の処理(wpautop)や Quicktagsなど一通り揃っているので十分。

画像アップローダーを呼び出す

「og:image」なんかの出力に便利ですね。

分かりやすい記事を拝見し、ほぼコピペで実装出来ました。

分かりやすく、また興味深い記事が多いのでプロフィール見てみたら、テーマ「Simplicity」の作成者さんでした。

functions.phpに記述

どこにでも呼び出せるようになっているので、順当にfunctions.phpに記述しておきます。

//ファイルアップローダー出力関数
function generate_upload_image_tag( $name, $value ){ ?>
	<input name="<?php echo $name; ?>" type="text" value="<?php echo $value; ?>" />
	<input type="button" name="<?php echo $name; ?>_slect" value="選択" />
	<input type="button" name="<?php echo $name; ?>_clear" value="クリア" />
	<div id="<?php echo $name; ?>_thumbnail" class="uploded-thumbnail">
		<?php
if( $value ){
	$value_id = attachment_url_to_postid( $value );
	$value_url = wp_get_attachment_image_src( $value_id, 'thumbnail' );
	echo '<p><img src="' .  $value_url[0] . '" alt="選択中の画像"></p>';
}
?>
	</div>
	<script type="text/javascript">
		(function ($) {
			var custom_uploader;
			$("input:button[name=<?php echo $name; ?>_slect]").click(function(e) {
				e.preventDefault();
				if (custom_uploader) {
					custom_uploader.open();
					return;
				}
				custom_uploader = wp.media({
					title: "画像を選択してください",
					/* ライブラリの一覧を画像のみにする */
					library: {
						type: "image"
					},
					button: {
						text: "画像の選択"
					},
					/* 複数選択 */
					multiple: false
				});
				custom_uploader.on("select", function() {
					var images = custom_uploader.state().get("selection");
					/* file の中に選択された画像の各種情報が入っている */
					images.each(function(file){
						/* テキストフォームと表示されたサムネイル画像があればクリア */
						$("input:text[name=<?php echo $name; ?>]").val("");
						$("#<?php echo $name; ?>_thumbnail").empty();
						/* テキストフォームに画像の URL を表示 */
						$("input:text[name=<?php echo $name; ?>]").val(file.attributes.sizes.full.url);
						/* プレビュー用に選択されたサムネイル画像を表示 */
						$("#<?php echo $name; ?>_thumbnail").append('<img src="'+file.attributes.sizes.thumbnail.url+'" />');
					});
				});
				custom_uploader.open();
			});
			/* クリアボタンを押した時の処理 */
			$("input:button[name=<?php echo $name; ?>_clear]").click(function() {
				$("input:text[name=<?php echo $name; ?>]").val("");
				$("#<?php echo $name; ?>_thumbnail").empty();
			});
		})(jQuery);
	</script>
<?php
}

参考記事のままだと、選択中の画像が常にフルサイズになってしまうので、サムネールサイズ(thumbnail)を表示するよう変更しています。

ただし、サムネールサイズにも満たない小さい画像の場合、保存しないと表示されないのが未解決。

設定画面の出力

使いたい場面で呼び出し、表示用HTMLとオプションテーブルを追加します。

//メディアアップローダ スクリプト呼び出し
function my_admin_scripts() {
	wp_enqueue_media();
}
add_action( 'admin_print_scripts', 'my_admin_scripts' );

<?php /* 出力HTML */ ?>
<table>
	<tr>
		<th scope="row"><label for="media">og:imageファイル名<br />※必須、jpeg/jpg形式<br />ルートに置いた場合はフルパスを記入</label></th>
		<td><?php
generate_upload_image_tag( 'theme_option_ogimage', get_option( 'theme_option_ogimage') );
?></td>
	</tr>
</table>

//関数追加
	register_setting( 'custom-menu-group', 'theme_option_ogimage' );

 

カラーピッカー

とりあえずは必要ないので実装していませんが、上記記事のサイトに詳しい記事がありました。

WordPressのカスタム設定画面にカラーピッカーを設置する方法。使い回せるように関数化。