API de Configuración de WordPress: Implementación de Pestañas en Menú Personalizado

23 dic 2013, 23:09:51
Vistas: 17.5K
Votos: 10

He estado siguiendo la serie de tutoriales sobre la API de Configuración de WordPress de este chico:

http://wp.tutsplus.com/tutorials/theme-development/the-complete-guide-to-the-wordpress-settings-api-part-1/

Hasta ahora, he tenido éxito en hacer lo básico. Ahora, al implementar pestañas, estoy teniendo problemas.

Problema 1: Las pestañas no funcionan. Todos los campos se muestran en ambas pestañas. La Sección 1 debería mostrarse en la Pestaña Uno y la Sección 2 en la Pestaña Dos.

Problema 2: La Opción 2 no se guarda. Funcionaba bien antes de implementar las pestañas.

Captura de pantalla mostrando el problema con las pestañas

Captura de pantalla mostrando el problema de guardado

Código:

/* ----------------------------------------------------------------------------- */
/* Agregar Página de Menú */
/* ----------------------------------------------------------------------------- */ 

function add_my_menu() {
    add_menu_page (
        'Título de Página', // título de página 
        'Título de Menú', // título de menú
        'manage_options', // capacidad
        'my-menu-slug',  // slug del menú
        'my_menu_page',   // función que renderizará su salida
        get_template_directory_uri() . '/assets/ico/theme-option-menu-icon.png'   // enlace al ícono que se mostrará en la barra lateral
        //$position,    // posición de la opción de menú
    );
}
add_action('admin_menu', 'add_my_menu');
function my_menu_page() {
        ?>
        <?php  
        if( isset( $_GET[ 'tab' ] ) ) {  
            $active_tab = $_GET[ 'tab' ];  
        } else {
            $active_tab = 'tab_one';
        }
        ?>  
        <div class="wrap">
            <h2>Título de la Página de Menú</h2>
            <div class="description">Esta es la descripción de la página.</div>
            <?php settings_errors(); ?> 

            <h2 class="nav-tab-wrapper">  
                <a href="?page=my-menu-slug&tab=tab_one" class="nav-tab <?php echo $active_tab == 'tab_one' ? 'nav-tab-active' : ''; ?>">Pestaña Uno</a>  
                <a href="?page=my-menu-slug&tab=tab_two" class="nav-tab <?php echo $active_tab == 'tab_two' ? 'nav-tab-active' : ''; ?>">Pestaña Dos</a>  
            </h2>  

            <form method="post" action="options.php"> 
            <?php
                if( $active_tab == 'tab_one' ) {  

                    settings_fields( 'setting-group-1' );
                    do_settings_sections( 'my-menu-slug' );

                } elseif( $active_tab == 'tab_two' )  {

                    settings_fields( 'setting-group-2' );
                    do_settings_sections( 'my-menu-slug' );

                }
            ?>

                <?php submit_button(); ?> 
            </form> 

        </div>
        <?php
}

/* ----------------------------------------------------------------------------- */
/* Secciones y Campos de Configuración */
/* ----------------------------------------------------------------------------- */ 

function sandbox_initialize_theme_options() {  
    add_settings_section(  
        'page_1_section',         // ID usado para identificar esta sección y con el cual registrar opciones  
        'Sección 1',                  // Título a mostrar en la página de administración  
        'page_1_section_callback', // Función callback para renderizar la descripción de la sección  
        'my-menu-slug'                           // Página donde agregar esta sección de opciones  

    );

    add_settings_section(  
        'page_2_section',         // ID usado para identificar esta sección y con el cual registrar opciones  
        'Sección 2',                  // Título a mostrar en la página de administración  
        'page_2_section_callback', // Función callback para renderizar la descripción de la sección  
        'my-menu-slug'                           // Página donde agregar esta sección de opciones  
    );

    /* ----------------------------------------------------------------------------- */
    /* Opción 1 */
    /* ----------------------------------------------------------------------------- */ 

    add_settings_field (   
        'option_1',                      // ID usado para identificar el campo  
        'Opción 1',                           // Etiqueta a la izquierda del elemento de opción  
        'option_1_callback',   // Nombre de la función responsable de renderizar la interfaz de opción  
        'my-menu-slug',                          // Página donde se mostrará esta opción  
        'page_1_section',         // Nombre de la sección a la que pertenece este campo  
        array(                              // Array de argumentos para pasar al callback. En este caso, solo una descripción.  
            'Esta es la descripción de la opción 1',
        )  
    );  
    register_setting(  
        //~ 'my-menu-slug',  
        'setting-group-1',  
        'option_1'  
    );

    /* ----------------------------------------------------------------------------- */
    /* Opción 2 */
    /* ----------------------------------------------------------------------------- */     

    add_settings_field (   
        'option_2',  // ID -- ID usado para identificar el campo  
        'Opción 2', // ETIQUETA -- La etiqueta a la izquierda del elemento de opción  
        'option_2_callback', // FUNCIÓN CALLBACK -- Nombre de la función responsable de renderizar la interfaz de opción  
        'my-menu-slug', // SLUG DE PÁGINA DE MENÚ -- Página donde se mostrará esta opción  
        'page_2_section', // ID DE SECCIÓN -- Nombre de la sección a la que pertenece este campo  
        array( // Array de argumentos para pasar al callback. En este caso, solo una descripción.  
            'Esta es la descripción de la opción 2', // DESCRIPCIÓN -- Descripción del campo.
        )  
    );
    register_setting(  
        'setting-group-2',  
        'option_2'  
    );

} // function sandbox_initialize_theme_options
add_action('admin_init', 'sandbox_initialize_theme_options');

function page_1_section_callback() {  
    echo '<p>Descripción de la sección aquí</p>';  
} // function page_1_section_callback
function page_2_section_callback() {  
    echo '<p>Descripción de la sección aquí</p>';  
} // function page_1_section_callback

/* ----------------------------------------------------------------------------- */
/* Funciones Callback para Campos */
/* ----------------------------------------------------------------------------- */ 

function option_1_callback($args) {  
    ?>
    <input type="text" id="option_1" class="option_1" name="option_1" value="<?php echo get_option('option_1') ?>">
    <p class="description option_1"> <?php echo $args[0] ?> </p>
    <?php      
} // end option_1_callback  

function option_2_callback($args) {  
    ?>
    <textarea id="option_2" class="option_2" name="option_2" rows="5" cols="50"><?php echo get_option('option_2') ?></textarea>
    <p class="description option_2"> <?php echo $args[0] ?> </p>
    <?php      
} // end option_2_callback  
2
Comentarios

No estoy muy familiarizado con la API de ajustes, pero a primera vista parece que todos tus campos pertenecen a una única sección de ajustes, que muestras en ambas pestañas.

Milo Milo
23 dic 2013 23:20:13

@Milo Lo conseguí funcionar, pero diría que la API de Ajustes de WordPress es muy confusa de entender. Además, tiene casi cero documentación oficial.

Omar Tariq Omar Tariq
24 dic 2013 10:18:49
Todas las respuestas a la pregunta 3
2
16

Aquí está cómo lo hago, cuidado, el post es extenso.

/* Añadir Menús
-----------------------------------------------------------------*/
add_action('admin_menu', 'ch_essentials_admin');
function ch_essentials_admin() {
    /* Menú Base */
    add_menu_page(
    'Essentials Theme',
    'Essentials Theme',
    'manage_options',
    'ch-essentials-options',
    'ch_essentials_index');
}

Ahora para mis campos de configuración, campos extras removidos, solo como ejemplo.

Esto es para 'Configuraciones de Página Principal' y 'Pestaña de Página Principal'

add_action('admin_init', 'ch_essentials_options');
function ch_essentials_options() { 

/* Sección de Opciones de Página Principal */
add_settings_section( 
    'ch_essentials_front_page',
    'Opciones de Página Principal Essentials',
    'ch_essentials_front_page_callback',
    'ch_essentials_front_page_option'
);

add_settings_field(  
    'featured_post',                      
    'Post Destacado',               
    'ch_essentials_featured_post_callback',   
    'ch_essentials_front_page_option',                     
    'ch_essentials_front_page'
);

Esto es para mis opciones de encabezado, que es la pestaña 'opciones de encabezado'

/* Sección de Opciones de Encabezado */
add_settings_section( 
    'ch_essentials_header',
    'Opciones de Encabezado Essentials',
    'ch_essentials_header_callback',
    'ch_essentials_header_option'
);

add_settings_field(  
    'header_type',                      
    'Tipo de Encabezado',               
    'ch_essentials_textbox_callback',   
    'ch_essentials_header_option',                     
    'ch_essentials_header',
    array(
        'header_type' 
    ) 
);

Registrar Configuraciones

register_setting('ch_essentials_front_page_option', 'ch_essentials_front_page_option');
register_setting('ch_essentials_header_option', 'ch_essentials_header_option');

Todos estos están envueltos en una función, luego ejecutados con un admin_init

/* Opciones
-----------------------------------------------------------------*/
add_action('admin_init', 'ch_essentials_options');
function ch_essentials_options() { 
    /* Código mostrado arriba */
}

Funciones de Retorno:

/* Funciones de Retorno
-----------------------------------------------------------------*/
function ch_essentials_front_page_callback() { 
    echo '<p>Opciones de Visualización de Página Principal:</p>'; 
}
function ch_essentials_header_callback() { 
    echo '<p>Opciones de Visualización de Encabezado:</p>'; 
}
function ch_essentials_textbox_callback($args) { 
     
    $options = get_option('ch_essentials_header_option'); 
    
    echo '<input type="text" id="'  . $args[0] . '" name="ch_essentials_header_option['  . $args[0] . ']" value="' . $options[''  . $args[0] . ''] . '"></input>';
     
}
function ch_essentials_featured_post_callback($args) { 
     
    $options = get_option('ch_essentials_front_page_option'); 
    
    query_posts( $args );
    
    
    echo '<select id="featured_post" name="ch_essentials_front_page_option[featured_post]">';
    while ( have_posts() ) : the_post();
    
        $selected = selected($options['featured_post'], get_the_id(), false);
        printf('<option value="%s" %s>%s</option>', get_the_id(), $selected, get_the_title());
        
    endwhile;
    echo '</select>';
     
     
}

Ahora esta es la parte de visualización, con las pestañas..

Si tienes tus secciones y campos de configuración hechos exactamente así, entonces podrás hacer las pestañas sin problemas.

/* Página de Visualización
-----------------------------------------------------------------*/
function ch_essentials_index() {
?>
    <div class="wrap">  
        <div id="icon-themes" class="icon32"></div>  
        <h2>Opciones del Tema Essentials</h2>  
        <?php settings_errors(); ?>  
        
        <?php  
                $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'front_page_options';  
        ?>  
          
        <h2 class="nav-tab-wrapper">  
            <a href="?page=ch-essentials-options&tab=front_page_options" class="nav-tab <?php echo $active_tab == 'front_page_options' ? 'nav-tab-active' : ''; ?>">Opciones de Página Principal</a>  
            <a href="?page=ch-essentials-options&tab=header_options" class="nav-tab <?php echo $active_tab == 'header_options' ? 'nav-tab-active' : ''; ?>">Opciones de Encabezado</a>  
        </h2>  
          
        
        <form method="post" action="options.php">  
        
            <?php 
            if( $active_tab == 'front_page_options' ) {  
                settings_fields( 'ch_essentials_front_page_option' );
                do_settings_sections( 'ch_essentials_front_page_option' ); 
            } else if( $active_tab == 'header_options' ) {
                settings_fields( 'ch_essentials_header_option' );
                do_settings_sections( 'ch_essentials_header_option' ); 
                
            }
            ?>             
            <?php submit_button(); ?>  
        </form> 
  
    </div> 
<?php
}

-----EDITADO-----

y noté en tu post que tienes 'elseif' y no 'else if' en tu página de visualización real en la sección de pestañas

24 dic 2013 02:04:50
Comentarios

Esto fue bastante útil para mí. Tenía problemas para convertir una página individual en una página de pestañas. Las únicas cosas que añadí fueron una verificación empty() en el array $option para cada campo de entrada. De lo contrario, me aparecía un error cuando el valor no estaba establecido. También añadí un tercer argumento a register_settings(). Este acepta un array opcional para configurar cosas como la sanitización. En general, este fue un post muy bueno con código de calidad.

benjaminadk benjaminadk
10 mar 2020 06:43:49

¿por qué la palabra 'options' está en plural en la plantilla, pero en singular en el add_settings_field?

Philip Philip
25 sept 2023 02:35:45
0

Codificar así funcionó para mí:

<?php 

/* ----------------------------------------------------------------------------- */
/* Añadir Página de Menú */
/* ----------------------------------------------------------------------------- */ 

function add_my_menu() {
    add_menu_page (
        'Título de la Página', // título de la página 
        'Título del Menú', // título del menú
        'manage_options', // capacidad
        'my-menu-slug',  // slug del menú
        'my_menu_page',   // función que renderizará su salida
        get_template_directory_uri() . '/assets/ico/theme-option-menu-icon.png'   // enlace al icono que se mostrará en la barra lateral
        //$position,    // posición de la opción del menú
    );
}
add_action('admin_menu', 'add_my_menu');

function my_menu_page() {
        ?>
        <?php  
        if( isset( $_GET[ 'tab' ] ) ) {  
            $active_tab = $_GET[ 'tab' ];  
        } else {
            $active_tab = 'tab_one';
        }
        ?>  
        <div class="wrap">
            <h2>Título de la Página del Menú</h2>
            <div class="description">Esta es la descripción de la página.</div>
            <?php settings_errors(); ?> 

            <h2 class="nav-tab-wrapper">  
                <a href="?page=my-menu-slug&tab=tab_one" class="nav-tab <?php echo $active_tab == 'tab_one' ? 'nav-tab-active' : ''; ?>">Pestaña Uno</a>  
                <a href="?page=my-menu-slug&tab=tab_two" class="nav-tab <?php echo $active_tab == 'tab_two' ? 'nav-tab-active' : ''; ?>">Pestaña Dos</a>  
            </h2>  

            <form method="post" action="options.php"> 
            <?php
                if( $active_tab == 'tab_one' ) {  

                    settings_fields( 'setting-group-1' );
                    do_settings_sections( 'my-menu-slug-1' );

                } else if( $active_tab == 'tab_two' )  {

                    settings_fields( 'setting-group-2' );
                    do_settings_sections( 'my-menu-slug-2' );

                }
            ?>

                <?php submit_button(); ?> 
            </form> 

        </div>
        <?php
}

/* ----------------------------------------------------------------------------- */
/* Secciones y Campos de Configuración */
/* ----------------------------------------------------------------------------- */ 

function sandbox_initialize_theme_options() {  
    add_settings_section(  
        'page_1_section',         // ID usado para identificar esta sección y con el cual registrar opciones  
        'Sección 1',                  // Título a mostrar en la página de administración  
        'page_1_section_callback', // Función de callback para renderizar la descripción de la sección  
        'my-menu-slug-1'                           // Página donde añadir esta sección de opciones  

    );

    add_settings_section(  
        'page_2_section',         // ID usado para identificar esta sección y con el cual registrar opciones  
        'Sección 2',                  // Título a mostrar en la página de administración  
        'page_2_section_callback', // Función de callback para renderizar la descripción de la sección  
        'my-menu-slug-2'                           // Página donde añadir esta sección de opciones  
    );

    /* ----------------------------------------------------------------------------- */
    /* Opción 1 */
    /* ----------------------------------------------------------------------------- */ 

    add_settings_field (   
        'option_1',                      // ID usado para identificar el campo en todo el tema  
        'Opción 1',                           // La etiqueta a la izquierda del elemento de opción  
        'option_1_callback',   // El nombre de la función responsable de renderizar la interfaz de opción  
        'my-menu-slug-1',                          // La página donde se mostrará esta opción  
        'page_1_section',         // El nombre de la sección a la que pertenece este campo  
        array(                              // El array de argumentos para pasar al callback. En este caso, solo una descripción.  
            'Esta es la descripción de la opción 1',
        )  
    );  
    register_setting(  
        //~ 'my-menu-slug',  
        'setting-group-1',  
        'option_1'  
    );

    /* ----------------------------------------------------------------------------- */
    /* Opción 2 */
    /* ----------------------------------------------------------------------------- */     

    add_settings_field (   
        'option_2',  // ID -- ID usado para identificar el campo en todo el tema  
        'Opción 2', // ETIQUETA -- La etiqueta a la izquierda del elemento de opción  
        'option_2_callback', // FUNCIÓN CALLBACK -- El nombre de la función responsable de renderizar la interfaz de opción  
        'my-menu-slug-2', // SLUG DE PÁGINA DE MENÚ -- La página donde se mostrará esta opción  
        'page_2_section', // ID DE SECCIÓN -- El nombre de la sección a la que pertenece este campo  
        array( // El array de argumentos para pasar al callback. En este caso, solo una descripción.  
            'Esta es la descripción de la opción 2', // DESCRIPCIÓN -- La descripción del campo.
        )  
    );
    register_setting(  
        'setting-group-2',  
        'option_2'  
    );

} // function sandbox_initialize_theme_options
add_action('admin_init', 'sandbox_initialize_theme_options');

function page_1_section_callback() {  
    echo '<p>Descripción de la sección aquí</p>';  
} // function page_1_section_callback
function page_2_section_callback() {  
    echo '<p>Descripción de la sección aquí</p>';  
} // function page_1_section_callback

/* ----------------------------------------------------------------------------- */
/* Funciones Callback de Campos */
/* ----------------------------------------------------------------------------- */ 

function option_1_callback($args) {  
    ?>
    <input type="text" id="option_1" class="option_1" name="option_1" value="<?php echo get_option('option_1') ?>">
    <p class="description option_1"> <?php echo $args[0] ?> </p>
    <?php      
} // end sandbox_toggle_header_callback  

function option_2_callback($args) {  
    ?>
    <textarea id="option_2" class="option_2" name="option_2" rows="5" cols="50"><?php echo get_option('option_2') ?></textarea>
    <p class="description option_2"> <?php echo $args[0] ?> </p>
    <?php      
} // end sandbox_toggle_header_callback  

?>
11 nov 2016 14:35:30
0
<form method="post" action="options.php"> 

    <?php
        if( $active_tab == 'tab_one' ) {  

            settings_fields( 'setting-group-1' );
            do_settings_sections( 'my-menu-slug-1' );

        } elseif( $active_tab == 'tab_two' )  {

            settings_fields( 'setting-group-2' );
            do_settings_sections( 'my-menu-slug-1' );

        }
    ?> 

Cambia el my-menu-slug por my-menu-slug-1 y my-menu-slug-2

12 mar 2015 10:08:42