Skip to content
⌨️ Как добавить свою секцию на страницу настроек WordPress

⌨️ Как добавить свою секцию на страницу настроек WordPress

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

Создавать отдельную страницу в админке ради двух полей, перебор. Гораздо чище, добавить свою секцию на уже существующую страницу настроек, туда же, где находятся дефолтные опции WordPress. Для этого в Settings API предусмотрена одна функция: add_settings_section.

Разберём её синтаксис, параметры и соберём рабочий пример с секцией и полем, от хука admin_init до вывода в админке. Без лишних абстракций: только то, что вы скопируете и запустите у себя.

💡 Быстрый обзор:

  • Определите страницу-цель (general, reading, writing, discussion, media или кастомную), slug пригодится в четвёртом параметре
  • Зарегистрируйте секцию через add_settings_section() на хуке admin_init: задайте ID, заголовок и callback для пояснительного текста
  • Привяжите поля к секции через add_settings_field(), а саму опцию сохраните через register_setting()
  • Вызовите do_settings_sections() в колбэке страницы для кастомных страниц, секция отрендерится автоматически

Что такое Settings API и зачем он нужен

Settings API появился в WordPress 2.7 и с тех пор остаётся стандартным способом добавлять настройки в админку. Суть проста: вместо ручного вывода <form> и обработки $_POST вы описываете секции и поля через функции, а WordPress сам рендерит разметку, обрабатывает сохранение и проверяет nonce.

Три кита Settings API:

  • register_setting(), регистрирует опцию в wp_options;
  • add_settings_section(), создаёт блок (секцию) с заголовком;
  • add_settings_field(), добавляет конкретное поле в секцию.

Именно add_settings_section отвечает за «контейнер», визуальный блок, который группирует несколько полей под общим заголовком на странице настроек. Без неё поля просто некуда класть.

Синтаксис add_settings_section

Сигнатура функции лаконичная, четыре обязательных параметра и один опциональный массив:

1add_settings_section(
2 string $id,
3 string $title,
4 callable $callback,
5 string $page,
6 array $args = array()
7);

Функция ничего не возвращает. Она регистрирует секцию в глобальном массиве $wp_settings_sections, откуда WordPress забирает её при вызове do_settings_sections() на целевой странице. Вызов add_settings_section без последующего do_settings_sections на кастомной странице, секция молчаливо не отрендерится.

Важный нюанс: add_settings_section лишь описывает блок. Сами поля добавляются отдельными вызовами add_settings_field с указанием ID секции в пятом параметре. Без полей секция останется пустой обёрткой, иногда это нужно для текстового пояснения, но на практике рядом почти всегда идёт хотя бы одно поле.

Параметры функции, что передавать

$id** (string, обязательный)**, уникальный slug секции. Используйте строчные буквы, цифры и подчёркивания: my_plugin_main_section. Этот же ID вы укажете в add_settings_field, чтобы «привязать» поле к секции, и он же фигурирует в HTML-атрибуте id тега-обёртки.

$title** (string, обязательный)**, заголовок секции, который видит администратор. Выводится как <h2> внутри страницы настроек. Пишите по-русски для русской админки: «Настройки интеграции с CRM», а не my_plugin_crm_settings.

$callback** (callable, обязательный)**, имя функции, которая echo'ит пояснительный текст между заголовком секции и полями. Сигнатура: function my_callback($args), где $args, массив с ключами id, title и callback. Если пояснение не нужно, передайте '__return_false'.

$page** (string, обязательный)**, slug страницы настроек, куда добавляется секция. Встроенные страницы WordPress: general, reading, writing, discussion, media. Для кастомной страницы, slug, переданный в add_options_page(). ⚠ Страницы misc и privacy удалены из ядра (deprecated), WordPress автоматически перенаправит miscgeneral, privacyreading, но лучше не опираться на это поведение.

$args** (array, опциональный, с WordPress 6.1.0)**, массив для кастомизации HTML-обёртки секции:

Ключ

Тип

Описание

before_section

string

HTML, который вставляется ПЕРЕД содержимым секции. Получает класс секции как %s

after_section

string

HTML после содержимого секции. Не выводится, если секция пустая

section_class

string

CSS-класс для обёртки секции

Аргумент $args работает только при вызове do_settings_sections(). Если по ошибке используется do_settings_fields(), массив игнорируется, и before_section/after_section молча не сработают.

Практический пример: секция с полем на странице «Общие»

Соберём готовый фрагмент для functions.php или собственного плагина. Код добавляет секцию «Настройки сайта-визитки» на страницу options-general.php с одним текстовым полем, например, для номера телефона в футере.

1/**
2 * Добавляет кастомную секцию и поле на страницу «Общие».
3 */
4function sdstudio_add_visiting_card_section() {
5 // 1. Секция
6 add_settings_section(
7 'visiting_card_section', // ID секции
8 'Visiting Card Settings', // Заголовок
9 'sdstudio_visiting_card_section_cb', // Callback-пояснение
10 'general', // Страница «Общие»
11 array(
12 'before_section' => '<div class="visiting-card-wrapper">',
13 'after_section' => '</div>',
14 )
15 );
16
17 // 2. Поле
18 add_settings_field(
19 'footer_phone', // ID поля
20 'Footer Phone Number', // Лейбл
21 'sdstudio_footer_phone_field_cb', // Callback — рендерит <input>
22 'general', // Та же страница
23 'visiting_card_section' // К какой секции привязать
24 );
25
26 // 3. Регистрация опции
27 register_setting( 'general', 'footer_phone' );
28}
29add_action( 'admin_init', 'sdstudio_add_visiting_card_section' );
30
31/**
32 * Пояснительный текст над полями секции.
33 */
34function sdstudio_visiting_card_section_cb( $args ) {
35 ?>
36 <p id="<?php echo esc_attr( $args['id'] ); ?>">
37 Contact details displayed in the site footer.
38 </p>
39 <?php
40}
41
42/**
43 * Рендерит текстовое поле ввода.
44 */
45function sdstudio_footer_phone_field_cb() {
46 $value = get_option( 'footer_phone', '' );
47 printf(
48 '<input type="text" id="footer_phone" name="footer_phone" value="%s" class="regular-text" />',
49 esc_attr( $value )
50 );
51}

После добавления кода зайдите в админку: Настройки → Общие, под стандартными полями появится секция «Настройки сайта-визитки» с полем «Телефон в футере». Сохраните страницу, значение запишется в wp_options.

Код размещают в functions.php активной темы или, правильнее, в отдельном плагине. Плагин выживает при смене темы, а functions.php, нет. Если секция нужна только пока активна конкретная тема, functions.php допустим; во всех остальных случаях, только плагин.

Аргумент $args: что изменилось в WordPress 6.1

До версии 6.1 у add_settings_section было ровно четыре параметра, обёртку секции приходилось «подкрашивать» через CSS по ID, либо лезть в буфер вывода. Начиная с 6.1 добавился пятый параметр $args, и теперь HTML-обрамление задаётся прямо при регистрации секции:

  • before_section, div-обёртка или пояснительная плашка ДО содержимого;
  • after_section, закрывающий тег или подсказка ПОСЛЕ содержимого;
  • section_class, собственный класс, если стандартного form-table недостаточно.

Пример с пояснительной плашкой и кастомным классом:

1add_settings_section(
2 'api_keys_section',
3 'API Keys',
4 'sdstudio_api_keys_section_cb',
5 'general',
6 array(
7 'before_section' => '<div class="notice notice-info inline"><p>Store keys in wp-config.php, override here only.</p></div>',
8 'after_section' => '',
9 'section_class' => 'api-keys-section',
10 )
11);

Что важно помнить: after_section не выводится, если секция пустая, то есть когда внутри неё нет зарегистрированных полей. Если рассчитываете на закрывающий </div>, убедитесь, что через add_settings_field добавлено хотя бы одно поле. И главное: do_settings_sections(), а не do_settings_fields(), последний проигнорирует $args целиком.

Перед использованием before_section / after_section проверьте версию WordPress, на сайтах младше 6.1 передача пятого параметра вызовет фатальную ошибку. Безопасный подход: обернуть вызов в global $wp_version или использовать function_exists для проверки наличия хуков.

⁉️🤔 Частые вопросы

Можно ли обойтись без add_settings_section и добавлять поля напрямую?

Формально, нет. Поля регистрируются через add_settings_field(), а пятый параметр этой функции требует ID секции. Если секции нет, поле не отрендерится. Для единичного поля можно создать секцию с пустым заголовком и callback'ом '__return_false', секция будет невидимой, а поле, рабочим.

Чем отличается add_settings_section от add_settings_field?

Секция — это контейнер с заголовком и пояснительным текстом. Поле, конкретный элемент ввода (input, select, checkbox) внутри секции. Одна секция может содержать сколько угодно полей, все они группируются под одним заголовком и сохраняются одним нажатием кнопки «Сохранить».

Что будет, если указать slug несуществующей страницы в $page?

Секция зарегистрируется в $wp_settings_sections, но никогда не отрендерится, WordPress не знает, на какой странице её выводить. Ошибки при этом не будет, секция просто «повиснет в воздухе». Проверяйте slug: для встроенных страниц это general / reading / writing / discussion / media; для кастомных, точный slug из add_menu_page или add_options_page.

Можно ли добавить секцию на страницу чужого плагина?

Да, если знаете slug его страницы. Передайте его в $page, и секция появится на чужой странице настроек. Но это хрупкое решение: автор плагина может сменить slug в обновлении, и ваша секция «отвалится». Используйте только для собственных проектов или когда альтернатив нет.

Что делает хук admin_init и почему add_settings_section вызывают именно на нём?

admin_init срабатывает при каждом запросе к админке ДО рендеринга страницы. Это правильный момент для регистрации настроек: секции и поля должны быть объявлены до того, как WordPress начнёт собирать форму. Если вызвать add_settings_section позже, например, внутри колбэка страницы, секция не попадёт в $wp_settings_sections и не отобразится.

Своя секция или отдельная страница, что выбрать

Добавить секцию на general проще: меньше кода, пользователь видит настройки там же, где редактирует заголовок сайта. Но когда опций больше трёх-четырёх, секция раздувает стандартную страницу и путает администратора.

Правило простое: одна-две опции, логически связанные с общей страницей (телефон в футере, ключ API для комментариев), секция на general. Три и больше опций, самостоятельный функционал (слайдер, интеграция с CRM, сетка тарифов), отдельная страница через add_options_page(). В обоих случаях add_settings_section, тот самый кирпич, с которого начинается сборка.

Перед тем как копировать код, убедитесь, что WordPress обновлён до актуальной версии. Массив $args, section_class и обёртки before_section/after_section требуют как минимум 6.1, а сама функция живёт в ядре с версии 2.7. Два десятка лет обратной совместимости, не повод сидеть на устаревшем движке.