register_setting()
Регистрирует новую опцию и callback функцию для обработки значения опции при её сохранении в БД.
Эта функция также может использоваться для регистрации новой опции, которая будет добавлена на базовую страницу настроек WordPress (Общие, Медиафайлы, Чтение...) и в REST API. Опция добавляется в существующую секцию при помощи функции add_settings_field() или можно создать новую секцию функцией add_settings_section() и добавить опцию туда.
Функцию нужно вызывать на хуке:
- admin_init - для использования через интерфейс админки.
- rest_api_init - для использования в REST API. Для этого нужно указать параметр
show_in_rest=true. См. примеры ниже.
При первом добавлении опции в БД очистка срабатывает два раза.
Например, следующая функция вернет строку с двумя восклицательными знаками:
function append_exclamation( $input ){ return $input .'!'; }
В этом случае, скорее всего, опции еще не существует в таблице wp_options, поэтому функция update_option() "увидев", что такой опции нет, вызывает add_option(), чтобы добавить новую опцию. Так получается потому что хук sanitize_option вызывается до вызова функции add_option() и срабатывает второй раз, уже внутри add_option().
Ошибка: ERROR: options page not found - объяснение и решение проблемы:
Такая ошибка возникает, когда фильтр whitelist_options ничего не знает о вашей новой опции.
register_settings() добавляет данные в глобальную переменную $new_allowed_options. Затем эта переменная объединяется с переменной $whitelist_options в option_update_filter(), которая в свою очередь добавляет новые данные в $new_allowed_options, где $option_group - используется как индекс новых данных. Когда вы получаете ошибку "ERROR: options page not found" - это означает, что не удалось найти опции по ключу.
ЗАМЕТКА: До версии 5.5 опция $new_allowed_options называлась $new_whitelist_options.
Путаница получается, потому что первый аргумент $options_group используется как ключ, а реальное сравнение в файле options.php происходит с параметром $options_page, который равен $hook_suffix, получаемый из результата работы функции add_submenu_page().
Простое решение этой проблемы, указывать одинаковые названия для параметров $option_group и $option_name.
Другая причина этой ошибки - когда неправильно указан параметр $page при вызове функции:
add_settings_section( $id, $title, $callback, $page )
или
add_settings_field( $id, $title, $callback, $page, $section, $args )
Заметка: $page должен быть равен $menu_slug из функции:
add_theme_page( $page_title, $menu_title, $capability, $menu_slug, $function );
Используется в связке с другими функциями API настроек:
Хуки из функции
Возвращает
null. Ничего не возвращает.
Использование
register_setting( $option_group, $option_name, $args );
- $option_group(строка) (обязательный)
- Название группы, к которой будет принадлежать опция. Это название должно совпадать с названием группы в функции settings_fields().
- $option_name(строка) (обязательный)
- Название опции, которая будет сохраняться в БД.
- $args(массив/строка)
Данные регистрируемой опции (с версии 4.7).
До версии 4.7. тут указывалась коллбэк функция: sanitize_callback, т.е. нужно было указывать строку - название функции, а теперь эта строка указывается в одноименном элементе массива. Прошлый вариант поддерживается, т.е. есть обратная совместимость.
Если опцию не планируется использовать в REST API, то можно указать только два элемента массива
sanitize_callbackиdefault.$defaults = array( 'sanitize_callback' => null, 'default' => null, 'type' => 'string', 'group' => $option_group, 'description' => '', 'show_in_rest' => false, );
-
sanitize_callback(строка/массив)
Название функции обратного вызова, которая будет обрабатывать значение опции перед сохранением.Важно! Функция получит один параметр - значение опции. Значение которое указанная функция вернет, будет записано в опцию.
-
default(разное)
Значение по умолчанию при вызове get_option().Влияет как на Options API (например, get_option()), так и на REST API.
-
type(строка) (REST API)
Тип данных с которыми опция ассоциирована. Возможные значения 'string', 'boolean', 'integer', 'number', 'array', 'object'.Используется только в REST API для определения схемы и применения соответствующей очистки (sanitization).
Имеет смысл только если
show_in_rest=true. Поэтому приshow_in_rest=falseили когда параметр не установлен, параметр можно не указывать.Не влияет на работу страниц админки или на то, как настройка обрабатывается в API опций. (Т.е., например, можно установить
type=booleanи в форме при сохранении этой опции передать строку - через админ-панель указанная строка сохранится в БД. Но в REST API при таком варианте будет ошибка. -
description(строка) (REST API)
Описание данных, которые будут храниться в этой опции.Используется только в REST API, поэтому имеет смысл только если
show_in_rest=true. -
show_in_rest(логический|массив) (REST API)
Нужно ли добавлять данные этой опции в REST API.При регистрации сложных настроек этот аргумент может быть массивом в котором можно использовать ключ
schema.
По умолчанию: array()
-
Примеры
#1 Пример показывающий как нужно подключать функцию через хук admin_init:
add_action( 'admin_init', 'register_my_setting' );
function register_my_setting() {
register_setting( 'my_options_group', 'my_option_name', 'intval' );
}
#2 Другие примеры
Еще примеры смотрите в описании API опций.
#3 Регистрация опции (текстовое поле), также и для REST API
Если регистрация делается и для сайта и для REST API, то вызов функции нужно повесить на оба хука rest_api_init и admin_init. Если использовать только хук admin_init то в REST опция работать не будет.
В этом случае опцию также можно будет видеть при обращениях к эндпоинту wp-json/wp/v2/settings.
add_action( 'admin_init', 'register_my_setting' );
add_action( 'rest_api_init', 'register_my_setting' );
function register_my_setting() {
$args = array(
'sanitize_callback' => 'sanitize_text_field',
'default' => '',
'type' => 'string',
'show_in_rest' => true,
);
register_setting( 'my_options_group', 'my_option_name', $args );
} #4 Регистрация опции только для REST API
add_action( 'rest_api_init', 'register_block_core_site_logo_setting', 10 );
/**
* Register a core site setting for a site logo
*/
function register_block_core_site_logo_setting() {
register_setting( 'general', 'site_logo', [
'show_in_rest' => array(
'name' => 'site_logo',
),
'type' => 'integer',
'description' => __( 'Site logo.' ),
] );
} #5 Опция типа массив в REST API
Если вы хотите сохранить массив в настройках, а также показать этот массив в конечной точке wp-json/wp/v2/settings, то нужно указать схему массива в параметре show_in_rest.
add_action( 'admin_init', 'wpdocs_foo_register_settings' );
add_action( 'rest_api_init', 'wpdocs_foo_register_settings' );
function wpdocs_foo_register_settings() {
register_setting( 'general_setting', 'id' );
register_setting( 'general_setting', 'order' );
register_setting(
'general_setting',
'slider-data',
array(
'show_in_rest' => array(
'name' => 'images_slide',
'schema' => array(
'type' => 'array',
'items' => array(
'id' => 'string',
'order' => 'string',
),
),
),
'type' => 'array',
'sanitize_callback' => array( $this, 'wpdocs_admin_post_save_data' ),
)
);
} #6 Пример для типов object и array:
register_setting( 'dp_example_settings_group', 'dp_example_array_settings', array( 'type' => 'object', 'default' => array( 'A', 'B', 'C', ), 'show_in_rest' => array( 'schema' => array( 'type' => 'object', 'items' => array( 'type' => 'string', ), ), ), ) ); register_setting( 'dp_example_settings_group', 'dp_example_object_settings', array( 'type' => 'object', 'default' => array( 'some_str' => 'A', 'some_int' => 3, ), 'show_in_rest' => array( 'schema' => array( 'type' => 'object', 'properties' => array( 'some_str' => array( 'type' => 'string', ), 'some_int' => array( 'type' => 'integer', ), ), ), ), ) );
#7 Обработка, когда sanitize срабатывает дважды
Как упоминалось в заметке выше sanitize может сработать два раза, когда опция первый раз добавляется в БД. Поэтому, если есть какие-либо критические по производительности моменты или другие моменты, которые нужно учесть в этом случае, то их нужно отдельно обработать в sanitize функции.
add_action( 'admin_init', 'on_admin_init' );
/*
* Add custom options to whitelist, allowing valiated settings to be saved by form.
*/
function on_admin_init(): void
{
register_setting( PLUGIN_SLUG, PLUGIN_SLUG, [ 'sanitize_callback' => 'my_sanitize_settings' ] );
}
/*
* Sanitize the form input.
*/
function my_sanitize_settings( $input = NULL ):
{
// Detect multiple sanitizing passes.
// Accomodates bug: https://core.trac.wordpress.org/ticket/21989
static $pass_count = 0; $pass_count++;
if ( $pass_count <= 1 ) {
// Handle any single-time / performane sensitive actions.
}
// Insert regular santizing code here.
}
Функция срабатывает дважды только при первом сохранении настройки и добавлении ее в таблицу в базе данных. Последующие обновления настройки выполняют функцию sanitize_callback только один раз. Так что если вы не выполняете какую-то очень-очень-очень тяжелую операцию по очистке, нет необходимости беспокоиться об этом.
Заметки
- Global. Массив.
$new_allowed_options - Global. Массив.
$wp_registered_settings
Список изменений
| С версии 2.7.0 | Введена. |
| С версии 3.0.0 | The misc option group was deprecated. |
| С версии 3.5.0 | The privacy option group was deprecated. |
| С версии 4.7.0 | $args can be passed to set flags on the setting, similar to register_meta(). |
| С версии 5.5.0 | $new_whitelist_options was renamed to $new_allowed_options. Please consider writing more inclusive code. |
| С версии 6.6.0 | Added the label argument. |