Como crear una página de opciones con la Settings API en PHP en WordPress

Contents

Introducción

Este tutorial explica paso a paso cómo crear una página de opciones en WordPress usando la Settings API en PHP. Está pensado para desarrolladores que quieran proporcionar una interfaz de administración limpia y segura para configurar un plugin o tema. Incluye ejemplos prácticos, callbacks de renderizado, sanitización, recuperación de valores y mejores prácticas.

Qué es la Settings API

La Settings API es un conjunto de funciones de WordPress que facilita el registro, presentación y guardado de opciones en la base de datos. Permite definir:

  • Settings: registros que agrupan opciones y controlan la validación/sanitización.
  • Sections: secciones visibles en la pantalla de administración para agrupar campos.
  • Fields: campos individuales que se muestran y almacenan, cada uno con su callback de renderizado.

Conceptos clave

  • register_setting(): registra un setting y la función de sanitización.
  • add_settings_section(): añade una sección dentro de la página de ajustes.
  • add_settings_field(): añade un campo dentro de una sección.
  • settings_fields(), do_settings_sections() y submit_button(): ayudan a construir el formulario de la página de opciones correctamente (nonces, campos ocultos, etc.).

Paso 1: Crear el plugin básico y la página en el admin

Primero crea un plugin simple con su cabecera y añade una página al menú de administración donde se mostrarán las opciones.

lt?php
/
Plugin Name: Mi Plugin de Opciones
Description: Ejemplo de Settings API.
Version: 1.0
Author: Autor Ejemplo
/

if ( ! defined( ABSPATH ) ) {
    exit
}

add_action( admin_menu, mpo_add_admin_menu )
add_action( admin_init, mpo_register_settings )

function mpo_add_admin_menu() {
    add_options_page(
        Mi Plugin de Opciones, // Título de la página
        Mi Plugin,             // Texto del menú
        manage_options,        // Capacidad requerida
        mpo-options,           // Slug del menú
        mpo_options_page_html  // Callback para mostrar la página
    )
}
?gt

Paso 2: Registrar settings, secciones y campos

Registra un setting que será un array de opciones, añade una sección y varios campos dentro de esa sección.

lt?php
function mpo_register_settings() {
    // Registra el setting: mpo_options es el option_name en la tabla wp_options
    register_setting(
        mpo_options_group,   // Grupo (se usará en settings_fields)
        mpo_options,         // Nombre de la opción
        array(
            type => array,
            sanitize_callback => mpo_sanitize_options,
            default => array(
                text_field => ,
                checkbox_field => 0,
                select_field => option1,
                textarea_field => 
            ),
        )
    )

    // Añade una sección
    add_settings_section(
        mpo_main_section,          // ID
        Ajustes principales,       // Title visible
        mpo_main_section_cb,       // Callback para texto descriptivo
        mpo-options                // Página donde aparece (slug)
    )

    // Añade campos
    add_settings_field(
        mpo_text_field,            // ID
        Campo de texto,            // Título
        mpo_text_field_cb,         // Callback de renderizado
        mpo-options,               // Página
        mpo_main_section,          // Sección
        array( label_for => mpo_text_field )
    )

    add_settings_field(
        mpo_checkbox_field,
        Activar opción,
        mpo_checkbox_field_cb,
        mpo-options,
        mpo_main_section,
        array( label_for => mpo_checkbox_field )
    )

    add_settings_field(
        mpo_select_field,
        Selector,
        mpo_select_field_cb,
        mpo-options,
        mpo_main_section,
        array( label_for => mpo_select_field )
    )

    add_settings_field(
        mpo_textarea_field,
        Área de texto,
        mpo_textarea_field_cb,
        mpo-options,
        mpo_main_section,
        array( label_for => mpo_textarea_field )
    )
}
?gt

Callbacks de sección

lt?php
function mpo_main_section_cb() {
    echo ltpgtAquí puedes configurar las opciones principales de Mi Plugin.lt/pgt
}
?gt

Callbacks de renderizado de campos

Cada campo debe leer el valor actual con get_option y mostrar el control HTML adecuado. Usa las funciones de escape de WordPress al imprimir valores.

lt?php
function mpo_get_options() {
    opts = get_option( mpo_options )
    if ( ! is_array( opts ) ) {
        opts = array()
    }
    return opts
}

function mpo_text_field_cb( args ) {
    opts = mpo_get_options()
    value = isset( opts[text_field] ) ? opts[text_field] : 
    printf(
        ltinput type=text id=%1s name=mpo_options[text_field] value=%2s class=regular-text /gt,
        esc_attr( args[label_for] ),
        esc_attr( value )
    )
}

function mpo_checkbox_field_cb( args ) {
    opts = mpo_get_options()
    checked = ! empty( opts[checkbox_field] ) ? checked : 
    printf(
        ltinput type=checkbox id=%1s name=mpo_options[checkbox_field] value=1 %2s /gt,
        esc_attr( args[label_for] ),
        checked
    )
}

function mpo_select_field_cb( args ) {
    opts = mpo_get_options()
    value = isset( opts[select_field] ) ? opts[select_field] : option1
    options = array(
        option1 =gt Opción 1,
        option2 =gt Opción 2,
        option3 =gt Opción 3
    )
    echo ltselect id=. esc_attr( args[label_for] ) . name=mpo_options[select_field]gt
    foreach ( options as key =gt label ) {
        printf(
            ltoption value=%1s %2sgt%3slt/optiongt,
            esc_attr( key ),
            selected( value, key, false ),
            esc_html( label )
        )
    }
    echo lt/selectgt
}

function mpo_textarea_field_cb( args ) {
    opts = mpo_get_options()
    value = isset( opts[textarea_field] ) ? opts[textarea_field] : 
    printf(
        lttextarea id=%1s name=mpo_options[textarea_field] rows=5 cols=50gt%2slt/textareagt,
        esc_attr( args[label_for] ),
        esc_textarea( value )
    )
}
?gt

Paso 3: Construir el formulario en la página de administración

Usa settings_fields(), do_settings_sections() y submit_button() para renderizar el formulario correctamente con nonces y control de guardado.

lt?php
function mpo_options_page_html() {
    if ( ! current_user_can( manage_options ) ) {
        return
    }

    // Mensajes de error/éxito
    settings_errors( mpo_messages )
    ?gt

    ltdiv class=wrapgt
        lth1gtConfiguración de Mi Pluginlt/h1gt
        ltform action=options.php method=postgt
            lt?php
            // Imprime los campos ocultos, nonce y el option_group definido en register_setting
            settings_fields( mpo_options_group )
            // Imprime las secciones y sus campos para la página especificada
            do_settings_sections( mpo-options )
            // Botón de enviar estándar de WP
            submit_button( Guardar opciones )
            ?gt
        lt/formgt
    lt/divgt

    lt?php
}
?gt

Paso 4: Sanitización y validación

La función de sanitización recibe los datos enviados y debe limpiar/validar cada campo antes de guardarlo. A continuación un ejemplo que procesa distintos tipos de campos dentro de un mismo array.

lt?php
function mpo_sanitize_options( input ) {
    output = array()

    // Campo de texto: limpiar etiquetas HTML
    if ( isset( input[text_field] ) ) {
        output[text_field] = sanitize_text_field( input[text_field] )
    }

    // Checkbox: forzar 1 o 0
    output[checkbox_field] = ! empty( input[checkbox_field] ) ? 1 : 0

    // Select: validar que esté entre las opciones permitidas
    allowed = array( option1, option2, option3 )
    if ( isset( input[select_field] )  in_array( input[select_field], allowed, true ) ) {
        output[select_field] = input[select_field]
    } else {
        output[select_field] = option1
    }

    // Textarea: permitir algunos tags básicos si lo deseas, o sanear completamente
    if ( isset( input[textarea_field] ) ) {
        // Ejemplo: permitir sólo tags básicos
        output[textarea_field] = wp_kses_post( input[textarea_field] )
    }

    add_settings_error(
        mpo_messages,
        mpo_saved,
        Opciones guardadas.,
        updated
    )

    return output
}
?gt

Paso 5: Recuperar y usar las opciones en tu plugin o tema

Una vez guardadas, recupera las opciones con get_option y utiliza los valores de forma segura (escapando al imprimir en frontend).

lt?php
// Obtener el array de opciones
opts = get_option( mpo_options, array() )

// Uso en el plugin (ejemplo)
text = isset( opts[text_field] ) ? opts[text_field] : 
enabled = ! empty( opts[checkbox_field] )

// Mostrar en el frontend (ejemplo dentro de un template)
echo ltdiv class=mi-plugin-textgt . esc_html( text ) . lt/divgt
?gt

Buenas prácticas y recomendaciones

  • Prefija todo: usa un prefijo único (por ejemplo mpo_) para evitar colisiones con otros plugins.
  • Opciones como array: agrupar opciones en un solo item en wp_options reduce consultas pero para opciones muy cambiantes puede convenir opciones independientes.
  • Sanitiza siempre: todas las entradas deben pasar por funciones de sanitización apropiadas (sanitize_text_field, absint, wp_kses_post, etc.).
  • Escapa al mostrar: usa esc_html, esc_attr, esc_textarea, esc_url según corresponda al imprimir en frontend o backend.
  • Control de capacidades: solo usuarios con capability apropiada (manage_options) deberían acceder a la página.
  • Usa settings_errors(): para comunicar errores y confirmaciones al usuario tras guardar las opciones.
  • Valores por defecto: proporciona defaults en register_setting para evitar valores no definidos.
  • Internacionalización: marca cadenas para traducción si vas a distribuir el plugin.

Ejemplo completo integrado

A continuación un ejemplo completo que reúne lo explicado. Puedes copiarlo como un plugin único (archivo PHP) y activarlo en tu instalación de WordPress.

lt?php
/
Plugin Name: Mi Plugin de Opciones
Description: Ejemplo completo de Settings API.
Version: 1.0
Author: Autor Ejemplo
/

if ( ! defined( ABSPATH ) ) {
    exit
}

add_action( admin_menu, mpo_add_admin_menu )
add_action( admin_init, mpo_register_settings )

function mpo_add_admin_menu() {
    add_options_page(
        Mi Plugin de Opciones,
        Mi Plugin,
        manage_options,
        mpo-options,
        mpo_options_page_html
    )
}

function mpo_register_settings() {
    register_setting(
        mpo_options_group,
        mpo_options,
        array(
            type => array,
            sanitize_callback => mpo_sanitize_options,
            default => array(
                text_field => ,
                checkbox_field => 0,
                select_field => option1,
                textarea_field => 
            ),
        )
    )

    add_settings_section( mpo_main_section, Ajustes principales, mpo_main_section_cb, mpo-options )

    add_settings_field( mpo_text_field, Campo de texto, mpo_text_field_cb, mpo-options, mpo_main_section, array( label_for => mpo_text_field ) )
    add_settings_field( mpo_checkbox_field, Activar opción, mpo_checkbox_field_cb, mpo-options, mpo_main_section, array( label_for => mpo_checkbox_field ) )
    add_settings_field( mpo_select_field, Selector, mpo_select_field_cb, mpo-options, mpo_main_section, array( label_for => mpo_select_field ) )
    add_settings_field( mpo_textarea_field, Área de texto, mpo_textarea_field_cb, mpo-options, mpo_main_section, array( label_for => mpo_textarea_field ) )
}

function mpo_main_section_cb() {
    echo ltpgtAquí puedes configurar las opciones principales de Mi Plugin.lt/pgt
}

function mpo_get_options() {
    opts = get_option( mpo_options )
    if ( ! is_array( opts ) ) {
        opts = array()
    }
    return opts
}

function mpo_text_field_cb( args ) {
    opts = mpo_get_options()
    value = isset( opts[text_field] ) ? opts[text_field] : 
    printf(
        ltinput type=text id=%1s name=mpo_options[text_field] value=%2s class=regular-text /gt,
        esc_attr( args[label_for] ),
        esc_attr( value )
    )
}

function mpo_checkbox_field_cb( args ) {
    opts = mpo_get_options()
    checked = ! empty( opts[checkbox_field] ) ? checked : 
    printf(
        ltinput type=checkbox id=%1s name=mpo_options[checkbox_field] value=1 %2s /gt,
        esc_attr( args[label_for] ),
        checked
    )
}

function mpo_select_field_cb( args ) {
    opts = mpo_get_options()
    value = isset( opts[select_field] ) ? opts[select_field] : option1
    options = array(
        option1 =gt Opción 1,
        option2 =gt Opción 2,
        option3 =gt Opción 3
    )
    echo ltselect id=. esc_attr( args[label_for] ) . name=mpo_options[select_field]gt
    foreach ( options as key =gt label ) {
        printf(
            ltoption value=%1s %2sgt%3slt/optiongt,
            esc_attr( key ),
            selected( value, key, false ),
            esc_html( label )
        )
    }
    echo lt/selectgt
}

function mpo_textarea_field_cb( args ) {
    opts = mpo_get_options()
    value = isset( opts[textarea_field] ) ? opts[textarea_field] : 
    printf(
        lttextarea id=%1s name=mpo_options[textarea_field] rows=5 cols=50gt%2slt/textareagt,
        esc_attr( args[label_for] ),
        esc_textarea( value )
    )
}

function mpo_sanitize_options( input ) {
    output = array()

    if ( isset( input[text_field] ) ) {
        output[text_field] = sanitize_text_field( input[text_field] )
    }

    output[checkbox_field] = ! empty( input[checkbox_field] ) ? 1 : 0

    allowed = array( option1, option2, option3 )
    if ( isset( input[select_field] )  in_array( input[select_field], allowed, true ) ) {
        output[select_field] = input[select_field]
    } else {
        output[select_field] = option1
    }

    if ( isset( input[textarea_field] ) ) {
        output[textarea_field] = wp_kses_post( input[textarea_field] )
    }

    add_settings_error( mpo_messages, mpo_saved, Opciones guardadas., updated )

    return output
}

function mpo_options_page_html() {
    if ( ! current_user_can( manage_options ) ) {
        return
    }

    settings_errors( mpo_messages )
    ?gt

    ltdiv class=wrapgt
        lth1gtConfiguración de Mi Pluginlt/h1gt
        ltform action=options.php method=postgt
            lt?php
            settings_fields( mpo_options_group )
            do_settings_sections( mpo-options )
            submit_button( Guardar opciones )
            ?gt
        lt/formgt
    lt/divgt

    lt?php
}
?gt

Resumen final

La Settings API es la forma recomendada para crear páginas de opciones robustas en WordPress: centraliza validación, nonce y presentación de campos. Siguiendo los pasos anteriores tendrás una estructura clara: registro del setting, definición de secciones y campos, renderizado del formulario y sanitización de los datos. Aplica las buenas prácticas (prefijos, escape, sanitización y capacidades) para asegurar compatibilidad y seguridad.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *