LoginSignup
1
1

More than 1 year has passed since last update.

WordPressプラグイン(設定画面追加+データ保存)のはじめかた

Last updated at Posted at 2022-10-30

はじめに

こちらのページのソースが正しくないため修正しました。細かい説明は元記事をご確認ください。

0からわかるWordPressプラグイン開発(スッテプ・バイ・ステップ)

  • 実行時エラーの修正

  • 更新後のメッセージ表示を追加

    (元記事はWordPress4.9でしたが、 6.0.3で確認)

機能

  • 管理画面のメニューに項目追加
  • 設定画面を追加
  • DBに入力した項目を保存する

img40.png

チュートリアル

  1. プラグインの雛形を作成する
  2. メニューにプラグインを表示する
  3. フォームを作成する
  4. 保存処理

ソース全体

確認する場合はクリック
<?php
/*
Plugin Name: My Test Plugin
Description: データ保存画面表示プラグイン
Version: 1.0
 */

if (!defined('ABSPATH')) exit;

// ログインユーザのセットアップ後(プラグインの初期化処理に利用)
add_action('init', 'CustomIndexBanner::init');

class CustomIndexBanner
{
    const VERSION                 = '1.0.0';
    const PLUGIN_ID               = 'custom-index-banner';
    const CREDENTIAL_ACTION       = self::PLUGIN_ID . '-nonce-action';
    const CREDENTIAL_NAME         = self::PLUGIN_ID . '-nonce-key';
    const PLUGIN_DB_PREFIX        = self::PLUGIN_ID . '_';
    const MENU_PARENT_SLUG        = self::PLUGIN_ID;
    const MENU_CONFIG_SLUG        = self::PLUGIN_ID . '-config';
    const COMPLETE_TRANSIENT_KEY  = self::PLUGIN_ID . '_complete';

    static function init()
    {
        return new self();
    }

    function __construct()
    {
        if (is_admin() && is_user_logged_in()) {
            // メニュー追加
            add_action('admin_menu', [$this, 'set_plugin_menu']);
            add_action('admin_menu', [$this, 'set_plugin_sub_menu']);

            // コールバック関数定義
            add_action('admin_init', [$this, 'save_config']);
            add_action('admin_notices', [$this, 'admin_notices']);
        }
    }

    /**
     * 親メニューの追加
     */
    function set_plugin_menu()
    {
        add_menu_page(
            'My Test Plugin',           /* ページタイトル*/
            'My Test Plugin',           /* メニュータイトル */
            'manage_options',            /* 権限 */
            self::MENU_PARENT_SLUG,      /* ページを開いたときのURL(menu_slug) */
            [$this, 'show_about_plugin'],       /* メニューに紐づく画面を描画するcallback関数 */
            'dashicons-format-gallery',  /* アイコン see: https://developer.wordpress.org/resource/dashicons/#awards */
            3                           /* 表示位置 (2-ダッシュボード の次) */
        );
    }

    /**
     * サブメニューの追加
     */
    function set_plugin_sub_menu()
    {
        add_submenu_page(
            self::MENU_PARENT_SLUG,  /* 親メニューのslug */
            '設定ページ',             /* page_title */
            '設定ページ',             /* menu_title */
            'manage_options',
            self::MENU_CONFIG_SLUG,
            [$this, 'show_config_form']
        );
    }

    /**
     * メニュー(親)の画面
     */
    function show_about_plugin()
    {
        // テキストをechoで表示
        $html = "<h1>親メニュータイトル</h1>";
        $html .= "<p>親メニュー本文</p>";

        echo $html;
    }

    /**
     * サブメニュー画面
     */
    function show_config_form()
    {
        // wp_optionsのデータを取得して表示
        $title = get_option(self::PLUGIN_DB_PREFIX . "_title");
?>
        <div class="wrap">
            <h1>設定ページタイトル</h1>

            <form action="" method='post' id="my-submenu-form">
                <?php // nonceの設定
                ?>
                <?php wp_nonce_field(self::CREDENTIAL_ACTION, self::CREDENTIAL_NAME) ?>

                <p>
                    <label for="title">タイトル:</label>
                    <input type="text" name="title" value="<?= $title ?>" />
                </p>

                <p><input type='submit' value='保存' class='button button-primary button-large'></p>
            </form>
        </div>
<?php
    }

    /**
     * 設定画面の項目データベースに保存する
     */
    function save_config()
    {

        // nonceで設定したcredentialのチェック
        if (isset($_POST[self::CREDENTIAL_NAME]) && $_POST[self::CREDENTIAL_NAME]) {
            if (check_admin_referer(self::CREDENTIAL_ACTION, self::CREDENTIAL_NAME)) {
                // 変更前の値
                $prev_title = get_option(self::PLUGIN_DB_PREFIX . "_title");

                // 保存処理
                $title = $_POST['title'] ?? "";
                update_option(self::PLUGIN_DB_PREFIX .  '_title', $title);

                // 処理後のメッセージをtransientにセット
                $completed_text = "設定を保存しました。({$prev_title}{$title})";
                set_transient(self::COMPLETE_TRANSIENT_KEY, $completed_text, 5);
            }
        }
    }

    /**
     * 保存完了メッセージ
     */
	public function admin_notices()
	{
        global $pagenow;
        if ( $pagenow != 'admin.php' ) {
            return;
        }

        // 保存したメッセージがあれば表示する
		if ($notice = get_transient(self::COMPLETE_TRANSIENT_KEY)){
		?>
		<div id="message" class="notice notice-success is-dismissible">
			<p><?=$notice?></p>
		</div>
		<?php
		}
	}

} // end of class

1. プラグインの雛形を作成する

プラグイン名をmy-test-pluginとする。

  • wp-content/plugins/ の下にプラグイン用のディレクトリを作成する
cd ./wp-content/plugins/
mkdir my-test-plugin
  • プラグインファイルを作成する(プラグイン名と同名のファイルを作成する)
touch my-test-plugin.php
  • ファイルの先頭にプラグイン情報を記述する

これで、WordPressからプラグインとして認識されます

<?php
/*
Plugin Name: My Test Plugin
Description: データ保存画面表示プラグイン
Version: 1.0
 */

img10.png

2. カスタムメニューを追加

メニューに「My Test Plugin」というメニューを追加する。ダッシュボードの次に追加するため、$positionに2を設定

img20.png

<?php
/*
Plugin Name: My Test Plugin
Description: データ保存画面表示プラグイン
Version: 1.0
 */

if (!defined('ABSPATH')) exit;

// ログインユーザのセットアップ後(プラグインの初期化処理に利用)
add_action('init', 'CustomIndexBanner::init');

class CustomIndexBanner
{
    const VERSION           = '1.0.0';
    const PLUGIN_ID         = 'custom-index-banner';
    const MENU_PARENT_SLUG  = self::PLUGIN_ID;
    const MENU_CONFIG_SLUG  = self::PLUGIN_ID . '-config';

    static function init()
    {
        return new self();
    }

    function __construct()
    {
        if (is_admin() && is_user_logged_in()) {
            // メニュー追加
            add_action('admin_menu', [$this, 'set_plugin_menu']);
            add_action('admin_menu', [$this, 'set_plugin_sub_menu']);

            // コールバック関数定義
            add_action('admin_init', [$this, 'save_config']);
            add_action('admin_notices', [$this, 'admin_notices']);
        }
    }

    /**
     * 親メニューの追加
     */
    function set_plugin_menu()
    {
        add_menu_page(
            'My Test Plugin',           /* ページタイトル*/
            'My Test Plugin',           /* メニュータイトル */
            'manage_options',            /* 権限 */
            self::MENU_PARENT_SLUG,      /* ページを開いたときのURL(menu_slug) */
            [$this, 'show_about_plugin'],       /* メニューに紐づく画面を描画するcallback関数 */
            'dashicons-format-gallery',  /* アイコン see: https://developer.wordpress.org/resource/dashicons/#awards */
            3                           /* 表示位置 (2-ダッシュボード の次) */
        );
    }

    /**
     * サブメニューの追加
     */
    function set_plugin_sub_menu()
    {
        add_submenu_page(
            self::MENU_PARENT_SLUG,  /* 親メニューのslug */
            '設定ページ',             /* page_title */
            '設定ページ',             /* menu_title */
            'manage_options',
            self::MENU_CONFIG_SLUG,
            [$this, 'show_config_form']
        );
    }

※メニューは追加されるが、画面はまだ表示されない(画面描画は未作成)

次に画面を表示するshow_about_plugin ()show_config_form()を実装する

3. フォームを作成する

  • 親画面

img30.png

echo でhtmlを出力

function show_about_plugin()
{
    // テキストをechoで表示
    $html = "<h1>親メニュータイトル</h1>";
    $html .= "<p>親メニュー本文</p>";

    echo $html;
  • 子画面

img31.png

タグで出力

function show_config_form()
{
?>
  <div class="wrap">
      <h1>設定ページタイトル</h1>

      <form action="" method='post' id="my-submenu-form">
  • ソース
    const CREDENTIAL_ACTION = self::PLUGIN_ID . '-nonce-action';
    const CREDENTIAL_NAME   = self::PLUGIN_ID . '-nonce-key';
    const PLUGIN_DB_PREFIX  = self::PLUGIN_ID . '_';

/* ~~ 途中略 ~~ */

    /**
     * メニュー(親)の画面
     */
    function show_about_plugin()
    {
        // テキストをechoで表示
        $html = "<h1>親メニュータイトル</h1>";
        $html .= "<p>親メニュー本文</p>";

        echo $html;
    }

    /**
     * サブメニュー画面
     */
    function show_config_form()
    {
        // wp_optionsのデータを取得して表示
        $title = get_option(self::PLUGIN_DB_PREFIX . "_title");
?>
        <div class="wrap">
            <h1>設定ページタイトル</h1>

            <form action="" method='post' id="my-submenu-form">
                <?php // nonceの設定
                ?>
                <?php wp_nonce_field(self::CREDENTIAL_ACTION, self::CREDENTIAL_NAME) ?>

                <p>
                    <label for="title">タイトル:</label>
                    <input type="text" name="title" value="<?= $title ?>" />
                </p>

                <p><input type='submit' value='保存' class='button button-primary button-large'></p>
            </form>
        </div>
<?php
    }

4. 保存処理

保存処理と、処理後のメッセージ表示のためフックを「function __construct()」に追加する

フック名 説明
admin_init 管理画面ページ表示時に最初に呼び出される
admin_notices 更新通知
    add_action('admin_init', [$this, 'save_config']);
    add_action('admin_notices', [$this, 'admin_notices']);
  • save_configにデータの保存処理update_option()を実装

  • admin_noticesで、保存後のメッセージを表示する

  • ソース

    const COMPLETE_TRANSIENT_KEY  = self::PLUGIN_ID . '_complete';

/*  ~~ 途中略 ~~  */

            // コールバック関数定義
            add_action('admin_init', [$this, 'save_config']);
            add_action('admin_notices', [$this, 'admin_notices']);

/*  ~~ 途中略 ~~  */

    /**
     * 設定画面の項目データベースに保存する
     */
    function save_config()
    {

        // nonceで設定したcredentialのチェック
        if (isset($_POST[self::CREDENTIAL_NAME]) && $_POST[self::CREDENTIAL_NAME]) {
            if (check_admin_referer(self::CREDENTIAL_ACTION, self::CREDENTIAL_NAME)) {
                // 変更前の値
                $prev_title = get_option(self::PLUGIN_DB_PREFIX . "_title");

                // 保存処理
                $title = $_POST['title'] ?? "";
                update_option(self::PLUGIN_DB_PREFIX .  '_title', $title);

                // 処理後のメッセージをtransientにセット
                $completed_text = "設定を保存しました。({$prev_title}{$title})";
                set_transient(self::COMPLETE_TRANSIENT_KEY, $completed_text, 5);
            }
        }
    }

    /**
     * 保存完了メッセージ
     */
	public function admin_notices()
	{
        global $pagenow;
        if ( $pagenow != 'admin.php' ) {
            return;
        }

        // 保存したメッセージがあれば表示する
		if ($notice = get_transient(self::COMPLETE_TRANSIENT_KEY)){
		?>
		<div id="message" class="notice notice-success is-dismissible">
			<p><?=$notice?></p>
		</div>
		<?php
		}
	}

参考ページ

0からわかるWordPressプラグイン開発(スッテプ・バイ・ステップ)

WordPressでプラグインを使わずに管理(投稿)画面にメッセージを通知

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1