WordPress. API настроек (опций). Часть 3 из 4

22.07.2019

Теги: APICMSWeb-разработкаWordPressНастройкаПлагин

Мы уже знаем, как создавать новые опции и поля формы для их сохранения в базу данных. И умеем создавать страницу или несколько страниц в панели управления для размещения полей формы. Но не умеем еще создавать форму, чтобы разместить внутри нее поля настроек. И сохранить все настройки после отправки данных формы. Давайте посмотрим, как это можно сделать.

Создание формы настроек

При добавлении опций на уже существующую страницу настроек, нет необходимости беспокоится о теге <form>, потому что он уже добавлен на страницу и поля формы вставляются внутрь этого тега. Однако, при создании новой страницы настрек, мы должны сами создать форму, добавить поля для редактирования и не забыть кнопку отправки.

Функция settings_fields()

Выводит на страницу hidden-поля (option_page, _wpnonce), необходимые для правильной работы и защиты формы.

settings_fields($page);

Функция do_settings_sections()

Выводит на страницу все секции настроек, относящиеся к указанной странице настроек в панели управления.

do_settings_sections($page);
Функция do_settings_fields() похожа на do_settings_sections(), она также выводит поля для определенной страницы и секции, только эти поля не форматируются в табличный вид, а выводятся «как есть».

Функция submit_button()

Выводит на страницу кнопку отправки данных формы.

submit_button()

Пример использования этих трех функций:

<form method="post" action="options.php">
<?php 
settings_fields('some-plugin-page');
do_settings_sections('some-plugin-page');
submit_button();
?>
</form>

Пример создания страницы настроек плагина

Давайте создадим плагин, у которого будет отдельная страница настроек. Мы создадим в панели управления новую страницу, разместим на ней форму, а внутри формы — две настройки, объединенные в секцию.

/*
 * Plugin name: Example
 * Description: Пример создания страницы настроек плагина
 */

/*
 * Добавляем страницу настроек плагина
 */
add_action('admin_menu', function () {
    add_menu_page(
        // содержимое тега title этой страницы
        'Настройки плагина «Example»',
        // название пункта меню для этой страницы
        'Плагин «Example»',
        // права доступа, чтобы был показан этот пункт меню
        'manage_options',
        // уникальный идентификатор меню (страницы)
        'plugin_example_page',
        // функция выводит содержимое этой страницы
        function () {
            ?>
            <div class="wrap">
                <h1>Настройки плагина «Example»</h1>
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                    Blanditiis consequuntur delectus, deleniti deserunt earum,
                    enim exercitationem harum labore nam necessitatibus non
                    numquam perspiciatis quae recusandae sint temporibus.
                </p>

                <form method="post" action="options.php">
                    <?php
                    settings_fields('plugin_example_page');
                    do_settings_sections('plugin_example_page');
                    submit_button();
                    ?>
                </form>
            </div>
            <?php
        },
        // иконка для страницы настроек плагина
        'dashicons-admin-settings',
        // позиция страницы, в конце списка
        90
    );
});
/*
 * 1. Регистрируем две опции для плагина «Example»
 * 2. Добавляем новую секцию для этих двух опций
 * 3. Добавляем поля формы для редактирования опций
 */
add_action('admin_init', function () {
    /*
     * 1.1. Регистрируем первую опцию для плагина
     */
    register_setting(
        // страница меню, куда будет добавлена эта опция
        'plugin_example_page',
        // уникальный идентификатор этой опции (slug)
        'some_option_for_example'
    );
    /*
     * 1.2. Регистрируем вторую опцию для плагина
     */
    register_setting(
        // страница меню, куда будет добавлена эта опция
        'plugin_example_page',
        // уникальный идентификатор этой опции (slug)
        'other_option_for_example'
    );

    /*
     * 2. Регистрируем новую секцию для этих двух опций
     */
    add_settings_section(
        // уникальный идентификатор секции
        'plugin_example_section',
        // заголовок секции нам не нужен
        '',
        // функция выводит описание секции
        function () {
            /*
             * У секции не будет описания, потому что уже есть описание
             * для страницы настроек. Но в общем случае может быть
             * 1. описание для страницы верхнего уровня меню
             * 2. описание для дочерних страниц этого меню
             * 3. описание для каждой секции на странице верхнего уровня
             * 4. описание для каждой секции на каждой дочерней странице
             */
        },
        // страница, куда будет добавлена эта секция
        'plugin_example_page'
    );

    /*
     * 3.1. Добавляем поле формы для редактирования первой опции
     */
    add_settings_field(
        'some_option_for_example', // идентификатор поля формы
        'Первая настройка плагина', // заголовок поля формы
        function () {  // выводит html-код поля формы
            $value = esc_attr(get_option('some_option_for_example', ''));
            ?>
            <input
                type="text"
                id="some_option_for_example"
                name="some_option_for_example"
                value="<?= $value; ?>"
            />
            <?php
        },
        'plugin_example_page', // страница меню
        'plugin_example_section', // идентификатор секции
        ['label_for' => 'some_option_for_example']
    );
    /*
     * 3.2. Добавляем поле формы для редактирования второй опции
     */
    add_settings_field(
        'other_option_for_example', // идентификатор поля формы
        'Вторая настройка плагина', // заголовок поля формы
        function () {  // выводит html-код поля формы
            $value = esc_attr(get_option('other_option_for_example', ''));
            ?>
            <input
                type="text"
                id="other_option_for_example"
                name="other_option_for_example"
                value="<?= $value; ?>"
            />
            <?php
        },
        'plugin_example_page', // страница меню
        'plugin_example_section', // идентификатор секции
        ['label_for' => 'other_option_for_example']
    );
});

В результате будет сформирован такой HTML-код:

<div class="wrap">
    <h1>Настройки плагина «Example»</h1>
    <p>
    Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    Blanditiis consequuntur delectus, deleniti deserunt earum,
    enim exercitationem harum labore nam necessitatibus non
    numquam perspiciatis quae recusandae sint temporibus.
    </p>

    <form method="post" action="options.php">
        <input type="hidden" name="option_page" value="plugin_example_page">
        <input type="hidden" name="action" value="update">
        <input type="hidden" id="_wpnonce" name="_wpnonce" value="369668e973">
        <input type="hidden" name="_wp_http_referer" value="/wp-admin/admin.php?page=plugin_example_page">
        
        <table class="form-table">
            <tbody>
                <tr>
                    <th scope="row">
                        <label for="some_option_for_example">Первая настройка плагина</label>
                    </th>
                    <td>
                        <input type="text" id="some_option_for_example" name="some_option_for_example" value="...">
                    </td>
                </tr>
                <tr>
                    <th scope="row">
                        <label for="other_option_for_example">Вторая настройка плагина</label>
                    </th>
                    <td>
                        <input type="text" id="other_option_for_example" name="other_option_for_example" value="...">
                    </td>
                </tr>
            </tbody>
        </table>
    
        <p class="submit">
            <input type="submit" name="submit" id="submit" class="button button-primary" value="Сохранить изменения">
        </p>
    </form>
</div>

Рабочий плагин, имеющий страницу настроек

Давайте переделаем плагин, позволяющий удалить служебные теги внутри внутри тега <head>. У этого плагина есть настройки, размещенные на уже существующей странице «Настройки • Общие». Это одна-единственная опция, которая хранит несколько значений. Т.е. в базу данных сохраняется массив в сериализованном виде. Создадим для плагина отдельную страницу настроек, разместим на ней форму и создадим поля для этой формы.

<?php
/*
Plugin Name: Удаляет теги из заголовка
Plugin URI: https://tokmakov.msk.ru
Description: Позволяет удалить неиспользуемые служебные теги в заголовке страницы.
Version: 1.0
Author: Евгений Токмаков
Author URI: https://tokmakov.msk.ru
*/

/*
 * Добавляем страницу настроек плагина в панели управления
 */
add_action('admin_menu', function () {
    /*
     * Добавляем пункт меню верхнего уровня
     */
    add_menu_page(
        // содержимое тега title этой страницы
        'Удаление служебных тегов',
        // название пункта меню для этой страницы
        'Служебные теги',
        // права доступа, чтобы был показан этот пункт меню
        'manage_options',
        // уникальный идентификатор меню (страницы)
        'tokmakov_head_clean_page',
        // функция выводит содержимое этой страницы
        function () {
            ?>
            <div class="wrap">
                <h1>Служебные теги из заголовка</h1>
                <p>
                    Плагин позволяет удалить неиспользуемые служебные теги
                    в заголовке страницы. Здесь можно выбрать, какие теги
                    удалить, а какие оставить.
                </p>
                <?php
                $html =
<<<HTML
1. <link rel="EditURI" type="..." title="..." href="..." />
2. <link rel="wlwmanifest" type="..." href="..." />
3. <link rel="prev" title="..." href="..." />
3. <link rel="next" title="..." href="..." />
4. <meta name="generator" content="..." />
5. <link rel="canonical" href="..." />
6. <link rel="shortlink" href="..." />
HTML;
                $html = esc_html($html);
                ?>
                <pre style="border: 1px solid #ddd; padding: 5px;"><?= $html; ?></pre>

                <form method="post" action="options.php">
                    <?php
                    settings_fields('tokmakov_head_clean_page');
                    do_settings_sections('tokmakov_head_clean_page');
                    submit_button();
                    ?>
                </form>
            </div>
            <?php
        },
        // иконка для страницы настроек плагина
        'dashicons-editor-code',
        // позиция страницы, в конце списка
        90
    );
});
/*
 * 1. Регистрируем опцию для плагина. Опция у нас одна, но содержит
 *    несколько значений. В общем случае у плагина может быть много
 *    опций.
 * 2. Добавляем секцию и размещаем на странице. Секция у нас одна и
 *    содержит только одну опцию. Но у этой опции несколько значений.
 *    В общем случае секций может быть насколько и внутри каждой —
 *    несколько опций.
 * 3. Добавляем несколько полей формы. Опция у нас одна, но содержит
 *    несколько значений. Для каждого значения — отдельный checkbox.
 */
add_action('admin_init', function () {

    /*
     * 1. Регистрируем новую опцию для плагина
     */
    register_setting(
        /*
         * Страница меню, куда будет добавлена опция плагина
         */
        'tokmakov_head_clean_page',
        /*
         * Идентификатор опции (slug)
         */
        'tokmakov_head_clean'
    );

    /*
     * 2. Регистрируем новую секцию для этой опции
     */
    add_settings_section(
        // уникальный идентификатор секции
        'tokmakov_head_clean_section',
        // заголовок секции нам не нужен
        '',
        // функция выводит описание секции
        function () {
            /*
             * У секции не будет описания, потому что уже есть описание
             * для страницы настроек. Но в общем случае может быть
             * 1. описание для страницы верхнего уровня меню
             * 2. описание для дочерних страниц этого меню
             * 3. описание для каждой секции на странице верхнего уровня
             * 4. описание для каждой секции на каждой дочерней странице
             */
        },
        // страница, куда будет добавлена эта секция
        'tokmakov_head_clean_page'
    );

    /*
     * 3.1. Добавляем поле формы для первого значения опции
     */
    add_settings_field(
        'tokmakov_head_clean_edituri', // идентификатор поля формы
        'Удалить служебный тег № 1', // заголовок поля формы
        function () {  // выводит html-код поля формы
            $option = get_option('tokmakov_head_clean');
            $checked = '';
            if (isset($option['edituri'])) {
                $checked = 'checked';
            }
            ?>
            <input
                type="checkbox"
                id="tokmakov_head_clean_edituri"
                name="tokmakov_head_clean[edituri]"
                value="1"
                <?= $checked; ?>
            />
            <label for="tokmakov_head_clean_edituri">
                Ссылка для редактирования блога внешними сервисами
            </label>
            <?php
        },
        'tokmakov_head_clean_page', // страница меню
        'tokmakov_head_clean_section' // идентификатор секции
    );

    /*
     * 3.2. Добавляем поле формы для второго значения опции
     */
    add_settings_field(
        'tokmakov_head_clean_wlwmanifest', // идентификатор поля формы
        'Удалить служебный тег № 2', // заголовок поля формы
        function () {  // выводит html-код поля формы
            $checked = '';
            $option = get_option('tokmakov_head_clean');
            if (isset($option['wlwmanifest'])) {
                $checked = 'checked';
            }
            ?>
            <input
                type="checkbox"
                id="tokmakov_head_clean_wlwmanifest"
                name="tokmakov_head_clean[wlwmanifest]"
                value="1"
                <?= $checked; ?>
            />
            <label for="tokmakov_head_clean_wlwmanifest">
                Ссылка для редактирования блога клиентом Windows Live Writer
            </label>
            <?
        },
        'tokmakov_head_clean_page', // страница меню
        'tokmakov_head_clean_section' // идентификатор секции
    );

    /*
     * 3.3 Добавляем поле формы для третьего значения опции
     */
    add_settings_field(
        'tokmakov_head_clean_prevnext', // идентификатор поля формы
        'Удалить служебный тег № 3', // заголовок поля формы
        function () {  // выводит html-код поля формы
            $checked = '';
            $option = get_option('tokmakov_head_clean');
            if (isset($option['prevnext'])) {
                $checked = 'checked';
            }
            ?>
            <input
                type="checkbox"
                id="tokmakov_head_clean_prevnext"
                name="tokmakov_head_clean[prevnext]"
                value="1"
                <?= $checked; ?>
            />
            <label for="tokmakov_head_clean_prevnext">
                Ссылки на предыдущую и следующую записи блога
            </label>
            <?
        },
        'tokmakov_head_clean_page', // страница меню
        'tokmakov_head_clean_section' // идентификатор секции
    );

    /*
     * 3.4. Добавляем поле формы для четвертого значения опции
     */
    add_settings_field(
        'tokmakov_head_clean_generator', // идентификатор поля формы
        'Удалить служебный тег № 4', // заголовок поля формы
        function () { // выводит html-код поля формы
            $checked = '';
            $option = get_option('tokmakov_head_clean');
            if (isset($option['generator'])) {
                $checked = 'checked';
            }
            ?>
            <input
                type="checkbox"
                id="tokmakov_head_clean_generator"
                name="tokmakov_head_clean[generator]"
                value="1"
                <?= $checked; ?>
            />
            <label for="tokmakov_head_clean_generator">
                Мета-тег установленной версии WordPress (особо опасен)
            </label>
            <?
        },
        'tokmakov_head_clean_page', // страница меню
        'tokmakov_head_clean_section' // идентификатор секции
    );

    /*
     * 3.5. Добавляем поле формы для пятого значения опции
     */
    add_settings_field(
        'tokmakov_head_clean_canonical', // идентификатор поля формы
        'Удалить служебный тег № 5', // заголовок поля формы
        function () {  // выводит html-код поля формы
            $checked = '';
            $option = get_option('tokmakov_head_clean');
            if (isset($option['canonical'])) {
                $checked = 'checked';
            }
            ?>
            <input
                type="checkbox"
                id="tokmakov_head_clean_canonical"
                name="tokmakov_head_clean[canonical]"
                value="1"
                <?= $checked; ?>
            />
            <label for="tokmakov_head_clean_canonical">
                Вывод канонической ссылки на пост или страницу
            </label>
            <?
        },
        'tokmakov_head_clean_page', // страница меню
        'tokmakov_head_clean_section' // идентификатор секции
    );

    /*
     * 3.6. Добавляем поле формы для шестого значения опции
     */
    add_settings_field(
        'tokmakov_head_clean_shortlink', // идентификатор поля формы
        'Удалить служебный тег № 6', // заголовок поля формы
        function () {  // выводит html-код поля формы
            $checked = '';
            $option = get_option('tokmakov_head_clean');
            if (isset($option['shortlink'])) {
                $checked = 'checked';
            }
            ?>
            <input
                type="checkbox"
                id="tokmakov_head_clean_shortlink"
                name="tokmakov_head_clean[shortlink]"
                value="1"
                <?= $checked; ?>
            />
            <label for="tokmakov_head_clean_shortlink">
                Вывод короткой ссылки на пост или страницу
            </label>
            <?
        },
        'tokmakov_head_clean_page', // страница меню
        'tokmakov_head_clean_section' // идентификатор секции
    );
});
/*
 * Получаем настройки плагина и удаляем служебные теги в head
 */
add_action('init', function () {
    $option = get_option('tokmakov_head_clean', false);
    if (empty($option)) {
        return;
    }
    if (isset($option['edituri'])) {
        remove_action('wp_head', 'rsd_link');
    }
    if (isset($option['wlwmanifest'])) {
        remove_action('wp_head', 'wlwmanifest_link');
    }
    if (isset($option['prevnext'])) {
        remove_action('wp_head','adjacent_posts_rel_link_wp_head');
    }
    if (isset($option['generator'])) {
        remove_action('wp_head', 'wp_generator');
    }
    if (isset($option['canonical'])) {
        remove_action('wp_head', 'rel_canonical');
    }
    if (isset($option['shortlink'])) {
        remove_action('wp_head', 'wp_shortlink_wp_head');
    }
});

Поиск: API • Web-разработка • WordPress • Настройка • Плагин • Option • Опция • Setting • Plugin

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.