WordPress. API настроек (опций). Часть 3 из 4
Мы уже знаем, как создавать новые опции и поля формы для их сохранения в базу данных. И умеем создавать страницу или несколько страниц в панели управления для размещения полей формы. Но не умеем еще создавать форму, чтобы разместить внутри нее поля настроек. И сохранить все настройки после отправки данных формы. Давайте посмотрим, как это можно сделать.
Создание формы настроек
При добавлении опций на уже существующую страницу настроек, нет необходимости беспокоится о теге <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