Skip to content
⌨️ Cómo añadir tu propia sección a la página de ajustes de WordPress

⌨️ Cómo añadir tu propia sección a la página de ajustes de WordPress

Las páginas de ajustes estándar de WordPress, «General», «Lectura», «Comentarios», cubren las necesidades básicas de un sitio. Pero en cuanto escribe un plugin o personaliza un tema para un cliente, el conjunto de campos integrado deja de ser suficiente. Necesita un bloque con sus propias opciones: una clave API, texto del pie de página, un interruptor de modo.

Crear una página de administración separada para solo dos campos es excesivo. Es mucho más limpio añadir su propia sección a una página de ajustes existente, justo donde residen las opciones predeterminadas de WordPress. La API de Ajustes proporciona una única función para esto: add_settings_section.

Recorramos su sintaxis, parámetros y construyamos un ejemplo funcional con una sección y un campo, desde el gancho admin_init hasta la salida en el panel de administración. Sin abstracciones innecesarias: solo lo que puede copiar y ejecutar usted mismo.

💡 Resumen rápido:

  • Defina la página de destino (general, lectura, escritura, comentarios, medios o una personalizada), necesitará su slug en el cuarto parámetro
  • Registre la sección mediante add_settings_section() en el gancho admin_init: proporcione un ID, título y una función de retrollamada para el texto descriptivo
  • Adjunte campos a la sección mediante add_settings_field(), y guarde la opción en sí mediante register_setting()
  • Llame a do_settings_sections() en la función de retrollamada de la página para páginas personalizadas, la sección se renderizará automáticamente

Qué es la API de Ajustes y por qué la necesita

La API de Ajustes apareció en WordPress 2.7 y desde entonces se ha mantenido como la forma estándar de añadir ajustes al panel de administración. La idea es simple: en lugar de escribir manualmente un <form> y manejar $_POST, usted describe secciones y campos mediante funciones, y el propio WordPress renderiza el marcado, gestiona el guardado y verifica el nonce.

Los tres pilares de la API de Ajustes:

  • register_setting(), registra una opción en wp_options;
  • add_settings_section(), crea un bloque (sección) con un título;
  • add_settings_field(), añade un campo específico a una sección.

Es add_settings_section la responsable del «contenedor», el bloque visual que agrupa varios campos bajo un encabezado común en la página de ajustes. Sin él, simplemente no hay dónde colocar los campos.

Sintaxis de add_settings_section

La firma de la función es concisa, cuatro parámetros obligatorios y un array opcional:

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

La función no devuelve nada. Registra la sección en el array global $wp_settings_sections, del cual WordPress la recupera cuando se llama a do_settings_sections() en la página de destino. Si llama a add_settings_section sin un do_settings_sections posterior en una página personalizada, la sección simplemente no se renderiza.

Un matiz importante: add_settings_section solo describe el bloque. Los campos en sí se añaden mediante llamadas separadas a add_settings_field, especificando el ID de la sección en el quinto parámetro. Sin campos, la sección queda como un envoltorio vacío, lo que a veces es útil para una explicación textual, pero en la práctica casi siempre se coloca al menos un campo junto a ella.

Parámetros de la función, qué pasar

$id (string, obligatorio), el slug único de la sección. Use letras minúsculas, números y guiones bajos: my_plugin_main_section. Especificará este mismo ID en add_settings_field para «adjuntar» el campo a la sección, y también aparece en el atributo HTML id de la etiqueta contenedora.

$title (string, obligatorio), el título de la sección que ve el administrador. Se muestra como un <h2> dentro de la página de ajustes. Escríbalo en lenguaje claro para el administrador: «Настройки интеграции с CRM», no my_plugin_crm_settings.

$callback (callable, obligatorio), el nombre de la función que imprime el texto descriptivo entre el título de la sección y los campos. Firma: function my_callback($args), donde $args es un array con las claves id, title y callback. Si no se necesita explicación, pase '__return_false'.

$page (string, obligatorio), el slug de la página de ajustes donde se añade la sección. Páginas integradas de WordPress: general, reading, writing, discussion, media. Para una página personalizada, el slug pasado a add_options_page(). ⚠ Las páginas misc y privacy se han eliminado del núcleo (obsoletas), WordPress redirigirá automáticamente miscgeneral, privacyreading, pero es mejor no confiar en este comportamiento.

$args (array, opcional, desde WordPress 6.1.0), un array para personalizar el envoltorio HTML de la sección:

Clave

Tipo

Descripción

before_section

string

HTML insertado ANTES del contenido de la sección. Recibe la clase de la sección como %s

after_section

string

HTML después del contenido de la sección. No se muestra si la sección está vacía

section_class

string

Clase CSS para el envoltorio de la sección

El argumento $args solo funciona cuando se llama a do_settings_sections(). Si se usa do_settings_fields() por error, el array se ignora y before_section/after_section no tienen efecto alguno.

Ejemplo práctico: una sección con un campo en la página «General»

Armemos un fragmento listo para usar en functions.php o en su propio plugin. El código añade una sección «Ajustes del sitio tarjeta de presentación» a la página options-general.php con un campo de texto, por ejemplo, para un número de teléfono en el pie de página.

1/**
2 * Adds a custom section and field to the «General» page.
3 */
4function sdstudio_add_visiting_card_section() {
5 // 1. Section
6 add_settings_section(
7 'visiting_card_section', // Section ID
8 'Visiting Card Settings', // Title
9 'sdstudio_visiting_card_section_cb', // Callback explanation
10 'general', // «General» page
11 array(
12 'before_section' => '<div class="visiting-card-wrapper">',
13 'after_section' => '</div>',
14 )
15 );
16
17 // 2. Field
18 add_settings_field(
19 'footer_phone', // Field ID
20 'Footer Phone Number', // Label
21 'sdstudio_footer_phone_field_cb', // Callback — renders <input>
22 'general', // Same page
23 'visiting_card_section' // Which section to attach to
24 );
25
26 // 3. Registering the option
27 register_setting( 'general', 'footer_phone' );
28}
29add_action( 'admin_init', 'sdstudio_add_visiting_card_section' );
30
31/**
32 * Explanatory text above the section fields.
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 * Renders a text input field.
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}

Después de añadir el código, vaya al panel de administración: Ajustes → General, y debajo de los campos estándar verá la sección «Ajustes del sitio tarjeta de presentación» con el campo «Teléfono del pie de página». Guarde la página y el valor se escribirá en wp_options.

El código se coloca en el functions.php del tema activo o, más correctamente, en un plugin separado. Un plugin sobrevive a un cambio de tema, mientras que functions.php no. Si la sección solo se necesita mientras un tema específico está activo, functions.php es aceptable; en todos los demás casos, solo un plugin.

El argumento $args: qué cambió en WordPress 6.1

Antes de la versión 6.1, add_settings_section tenía exactamente cuatro parámetros, y había que «reto car» el envoltorio de la sección mediante CSS por ID, o manipular el búfer de salida. A partir de la 6.1, se añadió un quinto parámetro $args, y ahora el marco HTML se establece directamente al registrar la sección:

  • before_section, un envoltorio div o un banner explicativo ANTES del contenido;
  • after_section, una etiqueta de cierre o una pista DESPUÉS del contenido;
  • section_class, una clase personalizada si la estándar form-table no es suficiente.

Un ejemplo con un banner explicativo y una clase personalizada:

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);

Lo importante de recordar: after_section no se muestra si la sección está vacía, es decir, cuando no hay campos registrados dentro de ella. Si cuenta con un </div> de cierre, asegúrese de que se añada al menos un campo mediante add_settings_field. Y lo más importante: use do_settings_sections(), no do_settings_fields(), ya que esta última ignorará $args por completo.

Antes de usar before_section / after_section, verifique la versión de WordPress, en sitios anteriores a la 6.1 pasar el quinto parámetro causará un error fatal. Un enfoque seguro: envuelva la llamada en una comprobación de global $wp_version o use function_exists para verificar la presencia de ganchos.

⁉️🤔 Preguntas frecuentes

¿Puedo omitir add_settings_section y añadir campos directamente?

Formalmente, no. Los campos se registran mediante add_settings_field(), y el quinto parámetro de esta función requiere un ID de sección. Si la sección no existe, el campo no se renderizará. Para un solo campo, puede crear una sección con un título vacío y una función de retrollamada '__return_false', la sección será invisible y el campo funcionará.

¿Cuál es la diferencia entre add_settings_section y add_settings_field?

Una sección es un contenedor con un título y texto descriptivo. Un campo es un elemento de entrada específico (input, select, checkbox) dentro de una sección. Una sección puede contener cualquier número de campos, todos agrupados bajo un mismo encabezado y guardados con un solo clic del botón «Guardar».

¿Qué sucede si especifico un slug de página inexistente en $page?

La sección se registrará en $wp_settings_sections pero nunca se renderizará, ya que WordPress no sabe en qué página mostrarla. No habrá error, la sección simplemente «quedará en el aire». Verifique el slug: para páginas integradas es general / reading / writing / discussion / media; para las personalizadas, el slug exacto de add_menu_page o add_options_page.

¿Puedo añadir una sección a la página de otro plugin?

Sí, si conoce su slug de página. Páselo en $page y la sección aparecerá en la página de ajustes del otro plugin. Pero esta es una solución frágil: el autor del plugin puede cambiar el slug en una actualización y su sección «se caerá». Úselo solo para sus propios proyectos o cuando no haya alternativas.

¿Qué hace el gancho admin_init y por qué se llama a add_settings_section en él?

admin_init se ejecuta en cada solicitud al panel de administración ANTES de que se renderice la página. Este es el momento adecuado para registrar ajustes: las secciones y los campos deben declararse antes de que WordPress comience a ensamblar el formulario. Si llama a add_settings_section más tarde, por ejemplo, dentro de la función de retrollamada de la página, la sección no llegará a $wp_settings_sections y no se mostrará.

Su propia sección o una página separada, qué elegir

Añadir una sección a general es más simple: menos código y el usuario ve los ajustes en el mismo lugar donde edita el título del sitio. Pero cuando hay más de tres o cuatro opciones, la sección infla la página estándar y confunde al administrador.

La regla es simple: una o dos opciones, lógicamente relacionadas con la página general (teléfono del pie de página, clave API para comentarios), use una sección en general. Tres o más opciones, funcionalidad independiente (un deslizador, integración CRM, una cuadrícula de precios), use una página separada mediante add_options_page(). En ambos casos, add_settings_section es el bloque de construcción mismo donde comienza el ensamblaje.

Antes de copiar el código, asegúrese de que WordPress esté actualizado a la última versión. El array $args, section_class y los envoltorios before_section/after_section requieren al menos la 6.1, mientras que la función en sí ha vivido en el núcleo desde la versión 2.7. Dos décadas de compatibilidad hacia atrás no son una razón para permanecer en un motor obsoleto.