WordPress как на ладони
Очень Удобный и Быстрый Хостинг для сайтов на WordPress. Пользуюсь сам и вам рекомендую!

API настроек (опций)

API опций было добавлено в версии 2.7 и позволяет создавать поля формы для сохранения настроек. API автоматизирует сохранение опций в БД и вывод нужного HTML кода на экран. Такой подход дает возможность удобно добавлять свои опции и секции опций в уже существующие страницы настроек (Общие, Чтение, Медиафайлы и т.д.). Или можно создавать страницы настроек плагинов без использования лишнего кода.

Несмотря на все удобства, регистрация и проверка (очистка) значений полей никуда не исчезла - все это нужно делать вручную.

Заметка: все POST запросы с данными формы должны отправляться на страницу wp-admin/options.php. Пользователи должны иметь право manage_options. В мультисайт версиях должны быть Супер Админами (Super Admin), чтобы отправлять данные формы.

Все функции регистрации опций: register_setting(), add_settings_*() и т.д. должны вызываться на хуке admin_init.

Функции API настроек

Регистрация/удаление опций
Добавление секций и отдельных полей
Вывод на экран
Ошибки

Добавление полей опций

Новое поле опции можно добавить в секцию на уже существующую страницу опций WordPress или на страницу опций плагина. Для этого используется функция add_settings_field().

Функция обратного вызова (callback) должна выводить html код поля (input, textarea, ...). WordPress сам позаботится о сохранении опции в базу данных. Обычно данные сохраняется в таблицу wp_options, но можно и перенастроить.

Добавляемая опция должна быть сначала зарегистрирована функцией register_setting(), иначе она не будет сохраняться и обновляться.

add_settings_field( $id, $title, $callback, $page, $section = 'default', $args = array() );
  • $id - Ярлык (slug) опции, используется как идентификатор поля. Используется в ID атрибуте тега.

  • $title - заголовок поля.

  • $callback - название функции обратного вызова. Функция должна заполнять поле нужным <input> тегом, который станет частью одной большой формы. Атрибут name должен быть равен параметру $option_name из register_setting(). Атрибут id обычно равен параметру $id. Результат должен сразу выводиться на экран (echo).

  • $page - страница меню в которую будет добавлено поле. Указывать нужно slug страницы, т.е. параметр должен быть равен параметру $menu_slug из add_theme_page(). У базовых страниц WordPress названия равны: general, reading, writing и т.д. по аналогии...

  • $section - название секции страницы настроек, в которую должно быть добавлено поле. По умолчанию default или может быть секцией добавленной функцией add_settings_section.

  • $args - дополнительные параметры, которые должны быть переданы callback функции.

Добавление секции опций

Секции опций - это блоки опций выделенные заголовком. Вместо того, чтобы создавать новую страницу настроек, иногда разумнее добавить новую секцию на уже существующую страницу настроек WordPress - это сделает плагин более простым и WordPress не будет нагружен новой страницей настроек плагина.

add_settings_section( $id, $title, $callback, $page );
  • $id - идентификатор секции. К этому ID прикрепляются поля (см. add_settings_field()).

  • $title - заголовок секции (название блока).

  • $callback - функция обратного вызова, которая выполняется в начале секции, перед выводом полей. В ней можно вывести текст описывающий секцию, выводить нужно сразу на экран, используя echo.

  • $page - тип страницы настроек, на которой будет показана секция (general, reading, writing, ...).

Регистрация опций

register_setting( $option_group, $option_name, $sanitize_callback );
unregister_setting( $option_group, $option_name, $sanitize_callback );
  • $option_group - название группы, к которой относится опция. Должна совпадать с группой в функции settings_fields().

  • $option_name - название опции, которая будет сохраняться.

  • $sanitize_callback - функция обратного вызова, которая будет обрабатывать значение перед сохранением.

Вывод секции опций на экран

Когда API используется для добавления опций к уже существующей странице опций, нет необходимости беспокоится о html теге самой формы, потому что она уже добавлена на странице и опции (input поля) будут вставляться внутри этой формы. Однако, когда вы создаете новую страницу опций, то вам нужно указать HTML тег формы (form) и его структуру.

settings_fields

Чтобы вывести скрытые поля и обеспечить безопасность данных формы опций, используйте функцию settings_fields(): settings_fields( $option_group );

  • $option_group - название группы. Должно совпадать с таким же параметром у register_setting(). Это название страницы (её slug) на которой выводятся опции.
do_settings_sections

Чтобы вывести секцию предназначенную для страницы опций, нужно использовать функцию do_settings_sections(): do_settings_sections( $page );

  • $page - альтернативное название (slug) страницы секции которой нужно вывести. Должен совпадать с названием страницы в функции add_settings_section().

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

submit_button

Форма опций нуждается в кнопке отправки данных. Для этого, используйте функцию submit_button().

Вывод всего блока формы

И в заключении вам нужно будет добавить HTML тег

в котором указать атрибуты action="options.php" method="POST". Этот пример, показывает как правильно выводить форму для отдельной страницы опций, с использованием ранее зарегистрированных полей:

<form method="POST" action="options.php">
	<?php
	settings_fields( 'my-page' );  // название группы опций - register_setting( $option_group )
	do_settings_sections( 'my-page' ); // slug страницы на которой выводится форма
	submit_button();
	?>
</form>

Примеры

#1. Дополнительные опции на странице настройки WordPress "Чтение"

Добавим новую секцию с двумя новыми опциями на базовую страницу настроек WordPress "Чтение"

// регистрируем все опции, секции, поля на хуке admin_init
add_action( 'admin_init', 'eg_settings_api_init' );

function eg_settings_api_init() {

	// Добавляем блок опций на базовую страницу "Чтение"
	add_settings_section(
		'eg_setting_section', // секция
		'Заголовок для секции настроек',
		'eg_setting_section_callback_function',
		'reading' // страница
	);

	// Добавляем поля опций. Указываем название, описание,
	// функцию выводящую html код.
	add_settings_field(
		'eg_setting_name',
		'Описание поля опции',
		'eg_setting_callback_function', // можно указать ''
		'reading', // страница
		'eg_setting_section' // секция
	);
	add_settings_field(
		'eg_setting_name2',
		'Описание поля опции2',
		'eg_setting_callback_function2',
		'reading', // страница
		'eg_setting_section' // секция
	);

	// Регистрируем опции, чтобы они сохранялись при отправке
	// $_POST параметров и чтобы callback функции опций выводили их значение.
	register_setting( 'reading', 'eg_setting_name' );
	register_setting( 'reading', 'eg_setting_name2' );
}

/**
 * Сallback функция для секции.
 *
 * Функция срабатывает в начале секции, если не нужно выводить
 * никакой текст или делать что-то еще до того как выводить опции,
 * то функцию можно не использовать для этого укажите '' в третьем
 * параметре add_settings_section
 *
 * @return void
 */
function eg_setting_section_callback_function() {
	echo '<p>Текст описывающий блок настроек</p>';
}

/**
 * Callback функции выводящие HTML код опций.
 *
 * Создаем checkbox и text input теги.
 *
 * @return void
 */
function eg_setting_callback_function() {
	?>
	<input
		name="eg_setting_name"
		type="checkbox"
		<?php checked( 1, get_option( 'eg_setting_name' ) ) ?>
		value="1"
		class="code"
	/>
	<?php
}

function eg_setting_callback_function2() {
	?>
	<input
		name="eg_setting_name2"
		type="text"
		value="<?= esc_attr( get_option( 'eg_setting_name2' ) ) ?>"
		class="code2"
	 />
	<?php
}

Получилось:

Графическое изображение кода - что за что отвечает.

#2. Страница настроек плагина (опции в массиве)

Давайте создадим плагин, в котором будет только страница настроек. Сделаем мы это, чтобы разобраться как работает API настроек.

Здесь регистрируется одна опция и в нее добавляются несколько разных опций как массив данных. Так удобнее и практичнее.

<?php
/*
 * Plugin name: Primer
 * Description: Демонстрация создания страницы настроек для плагина
*/

/**
 * Создаем страницу настроек плагина
 */
add_action( 'admin_menu', 'add_plugin_page' );

function add_plugin_page(){

	add_options_page(
		'Настройки Primer',
		'Primer',
		'manage_options',
		'primer_slug',
		'primer_options_page_output'
	);
}

function primer_options_page_output(){
	?>
	<div class="wrap">
		<h2><?php echo get_admin_page_title() ?></h2>

		<form action="options.php" method="POST">
			<?php
				settings_fields( 'option_group' );     // скрытые защитные поля
				do_settings_sections( 'primer_page' ); // секции с настройками (опциями). У нас она всего одна 'section_id'
				submit_button();
			?>
		</form>
	</div>
	<?php
}

/**
 * Регистрируем настройки.
 * Настройки будут храниться в массиве, а не одна настройка = одна опция.
 */
add_action( 'admin_init', 'plugin_settings' );

function plugin_settings(){

	// параметры: $option_group, $option_name, $sanitize_callback
	register_setting( 'option_group', 'option_name', 'sanitize_callback' );

	// параметры: $id, $title, $callback, $page
	add_settings_section( 'section_id', 'Основные настройки', '', 'primer_page' );

	// параметры: $id, $title, $callback, $page, $section, $args
	add_settings_field('primer_field1', 'Название опции', 'fill_primer_field1', 'primer_page', 'section_id' );
	add_settings_field('primer_field2', 'Другая опция', 'fill_primer_field2', 'primer_page', 'section_id' );
}

// Заполняем опцию 1
function fill_primer_field1(){

	$val = get_option('option_name');
	$val = $val ? $val['input'] : null;
	?>
	<input type="text" name="option_name[input]" value="<?php echo esc_attr( $val ) ?>" />
	<?php
}

// Заполняем опцию 2
function fill_primer_field2(){

	$val = get_option('option_name');
	$val = $val ? $val['checkbox'] : null;
	?>
	<label><input type="checkbox" name="option_name[checkbox]" value="1" <?php checked( 1, $val ) ?> /> отметить</label>
	<?php
}

// Очистка данных
function sanitize_callback( $options ){

	foreach( $options as $name => & $val ){
		if( $name == 'input' )
			$val = strip_tags( $val );

		if( $name == 'checkbox' )
			$val = intval( $val );
	}

	//die(print_r( $options )); // Array ( [input] => aaaa [checkbox] => 1 )

	return $options;
}

В итоге получим такую страницу:

primer

Теперь, давайте разберем код по порядку.

1) Создание страницы настроек

Регистрируем страницу настроек функцией add_options_page() - она не относится к API настроек напрямую:

add_options_page( 'Настройки Primer', 'Primer', 'manage_options', 'primer_slug', 'primer_options_page_output' );
  • primer_slug - это ярлык страницы настроек и он по сути в API настроек нигде не фигурирует...
2) Вывод секции на странице настроек

Страница настроек есть, теперь на ней нам нужно вызвать секцию с настройками. Самой секции пока нет и в ней тоже ничего нет. Секцию и её содержимое мы создадим чуть ниже:

<form action="options.php" method="POST">
	<?php
	settings_fields( 'option_group' );     // скрытые защитные поля
	do_settings_sections( 'primer_page' ); // секции с настройками (опциями). У нас она всего одна 'section_id'
	submit_button();
	?>
</form>
3) Регистрация/создание секции
add_settings_section( 'section_id', 'Основные настройки', '', 'primer_page' );
  • section_id - чтобы к этой секции потом добавить поля
  • primer_page - привязывает эту секцию к выводу секции do_settings_sections( 'primer_page' );
4) Заполнение секции опциями
add_settings_field('primer_field1', 'Название опции', 'fill_primer_field1', 'primer_page', 'section_id' );
add_settings_field('primer_field2', 'Другая опция', 'fill_primer_field2', 'primer_page', 'section_id' );
  • section_id - добавляет поле в секцию.
  • primer_page - дополнительное уточнение, что поле нужно добавить в секцию, которая вызывается с параметром do_settings_sections( 'primer_page' );.
5) Регистрация самой настройки

Сейчас у нас уже полностью готов весь вывод настроек, но сохранение не работает, потому что WordPress не знает о существовании новой опции. Нужно «сказать» WordPress, что есть настройка option_name и её нужно обрабатывать.

register_setting( 'option_group', 'option_name', 'sanitize_callback' );
  • option_group - нужно для вывода скрытых полей, для защиты формы. Для settings_fields( 'option_group' );

  • option_name - название самой опции, которая будет записываться в таблицу wp_options

  • sanitize_callback - функция для изменения/очистки передаваемых данных. Её можно не указывать, тогда данные сохраняться как есть (как передаются).

#3. Поле с вводом телефона

Добавим поле с вводом телефона на страницу "Общие настройки":

add_action( 'admin_init', 'phone_settings_api_init' );

function phone_settings_api_init() {
	register_setting( 'general', 'phone', 'sanitize_text_field' );

	add_settings_field(
		'phone',
		'<label for="phone">Телефон</label>',
		'phone_field_html',
		'general'
	);
}

function phone_field_html() {
	$value = get_option( 'phone', '' );
	printf( '<input type="text" id="phone" name="phone" value="%s" />', esc_attr( $value ) );
}

Выведем сохраненный телефон на экран в нужном месте шаблона:

echo esc_html( get_option( 'phone', '' ) );
51 комментарий
Полезные 7Вопросы 1 Все
    Войти