Cómo actualizar las opciones selectivas en la página de configuración del complemento

2

Escribo un plugin de wordpress. Mi plugin tiene opciones. Todas las opciones están en un grupo, 'configuración de pluginname'. Todos los nombres de las opciones son uniformes y se parecen a "configuración de nombre de plugin ['nombre-opción']". Algún código para ilustrar mi caso:

register_setting( 'pluginname_options', 'pluginname-settings', 'pluginname_validate' );
add_settings_section( 'section-one', 'Name of Section One', 'section_one_callback', 'pluginname_options-sectionname' );
add_settings_field( 'optionname', 'First Option', 'my_text_input', 'pluginname_options-sectionname', 'section-button', array(
    'name' => 'pluginname[optionname]',
    'value' => '42')
    )

Para que los administradores de blogs los modifiquen, creé una página de configuración y agrupé las opciones en pestañas. Cada pestaña muestra un subconjunto de opciones (una sección) y un "botón Actualizar", como se muestra a continuación:

echo "<form action=\"options.php\" method=\"POST\">";
settings_fields( 'pluginname_options' );
do_settings_sections( 'pluginname_options-sectionname' ); 
submit_button('Update', 'primary',  'submit-form', false);
echo "</form>";

El problema es que cuando presiono "Actualizar" en una pestaña, las opciones de otras pestañas se borran.

A mi entender, esto se debe a que todas las opciones representan una matriz de una configuración.

Pregunta: ¿es posible guardar una sección sin borrar otras en esta configuración? ¿Cuál es una buena práctica en estos casos: registrar configuraciones separadas, usar la función de validación para completar los espacios en blanco o algo más? ¿O es solo que estoy haciendo todo mal?

Gracias de antemano.

P.S .: Según lo solicitado en los comentarios, aquí hay un ejemplo de trabajo mínimo:

<?php
/*
Plugin Name: Plugin Name
Plugin URI:
Description: Description
Version: 0.0.1
Author: Author Name
Author URI:
License: GPL3+
*/

add_action( 'admin_menu', 'pluginname_menu' );

function pluginname_menu()
    {
    add_options_page( 'PluginName Options', 'pluginname', 'manage_options', 'pluginname_options_page', 'pluginname_options_page' );
    }

add_action( 'admin_init', 'pluginname_admin_init' );

function pluginname_admin_init()
    {
    register_setting( 'pluginname_options', 'pluginname-settings' );
    add_settings_section( 'section-one', 'Section One', 'pluginname_section_callback', 'pluginname_options-section-one' );
    $options_array = get_option('pluginname-settings');
    add_settings_field( 'optionname-one', 'First Option', 'pluginname_field_callback', 'pluginname_options-section-one', 'section-one', array(
    'name' => 'pluginname-settings[optionname-one]',
    'value' => isset($options_array['optionname-one']) ? $options_array['optionname-one'] : '42')
    );
    add_settings_field( 'optionname-two', 'Second Option', 'pluginname_field_callback', 'pluginname_options-section-one', 'section-one', array(
    'name' => 'pluginname-settings[optionname-two]',
    'value' => isset($options_array['optionname-two']) ? $options_array['optionname-two'] : '42')
    );
    add_settings_section( 'section-two', 'Section Two', 'pluginname_section_callback', 'pluginname_options-section-two' );
    add_settings_field( 'optionname-three', 'Third Option', 'pluginname_field_callback', 'pluginname_options-section-two', 'section-two', array(
    'name' => 'pluginname-settings[optionname-three]',
    'value' => isset($options_array['optionname-three']) ? $options_array['optionname-three'] : '42')
    );
    add_settings_field( 'optionname-four', 'Fourth Option', 'pluginname_field_callback', 'pluginname_options-section-two', 'section-two', array(
    'name' => 'pluginname-settings[optionname-four]',
    'value' => isset($options_array['optionname-four']) ? $options_array['optionname-four'] : '42')
    );
    }

function pluginname_validate($input)
    {
    return $input;
    }

function pluginname_section_callback()
    {
    echo 'Feel free to change parameters below.';
    }

function pluginname_field_callback( $args )
    {
    $name = esc_attr( $args['name'] );
    $value = esc_attr( $args['value'] );
    echo "<input type='text' name='$name' value='$value' /> ";
    }

function pluginname_tab1()
    {
    echo "<form action=\"options.php\" method=\"POST\">";
    settings_fields( 'pluginname_options' );
    do_settings_sections( 'pluginname_options-section-one' ); 
    submit_button('Update', 'primary',  'submit-form', false);
    echo "</form>";
    }

function pluginname_tab2()
    {
    echo "<form action=\"options.php\" method=\"POST\">";
    settings_fields( 'pluginname_options' );
    do_settings_sections( 'pluginname_options-section-two' ); 
    submit_button('Update', 'primary',  'submit-form', false);
    echo "</form>";
    }

function pluginname_options_page()
    {
    ?>
    <div class="wrap">
        <h2>Options</h2>
        <h2 class="nav-tab-wrapper">
        <a href="?page=pluginname_options_page&tab=1" class="nav-tab <? if ( @( $_GET['tab'] == '1' ) || !isset($_GET['tab'])) echo "nav-tab-active"; ?>">Section One Options</a>
        <a href="?page=pluginname_options_page&tab=2" class="nav-tab <? if ( $_GET['tab'] == '2' ) echo "nav-tab-active"; ?>">Section Two Options</a>
        </h2>
        <?php $current_tab = $_GET['tab'];
        switch ($current_tab)
            {
            case '2' : pluginname_tab2(); break;
            default: pluginname_tab1();
            } ?>
    </div>
    <?php
}
?>

ejemplo de trabajo mínimo .

    
pregunta Eques 18.10.2013 - 10:56

3 respuestas

4

Primera patada en tu devolución de llamada de validación cambiando el register_setting() a

register_setting( 'pluginname_options', 'pluginname-settings', 'pluginname_validate' );

Y luego actualiza tu función de validación para hacer algo. A continuación, se muestra el estado actual de las opciones y, a continuación, solo se actualizan las partes de la matriz que se envían. Cuando está en una pestaña y haga clic en "Actualizar", solo se publica la información en la pestaña. Por lo tanto, la matriz (como está escrito) solo tiene 2 teclas, y la información de la otra pestaña se purga.

function pluginname_validate($input)
    {
    $options_array = get_option('pluginname-settings');

    if( isset( $input['optionname-one'] ) )
         $options_array['optionname-one'] = sanitize_text_field( $input['optionname-one'] );

    if( isset( $input['optionname-two'] ) )
         $options_array['optionname-two'] = sanitize_text_field( $input['optionname-two'] );

    if( isset( $input['optionname-three'] ) )
         $options_array['optionname-three'] = sanitize_text_field( $input['optionname-three'] );

    if( isset( $input['optionname-four'] ) )
         $options_array['optionname-four'] = sanitize_text_field( $input['optionname-four'] );

    return $options_array;
    }

Introduje un poco de desinfección por diversión, el tipo de santización de datos depende de cuáles son sus opciones reales, pero siempre debe hacer algún tipo de desinfección.

    
respondido por el helgatheviking 20.10.2013 - 22:32
2

Hay dos formas:

  1. Pase el ID de la pestaña como campo oculto con su formulario y actualice solo los campos que pertenecen a esa pestaña.

  2. Separe los nombres de los campos de cada pestaña y combínelos en su devolución de llamada guardada.

respondido por el fuxia 20.10.2013 - 22:11
2

Entonces, supongamos que ha definido un parámetro para agregar cada opción a su propia pestaña. Así es como lo hago, por ejemplo:

'display_social_icons' => array(
    'name' => 'display_social_icons',
    'title' => __( 'Display Social Icons', 'oenology' ),
    'type' => 'checkbox',
    'description' => __( 'Display social icons in sidebar', 'oenology' ),
    'section' => 'social',
    'tab' => 'general',
    'since' => '1.2',
    'default' => true
),

Luego, cuando sale la página de configuración, determina la pestaña actual:

$currenttab = oenology_get_current_tab();
$settings_section = 'oenology_' . $currenttab . '_tab';
// Defining $currenttab left out for brevity

... luego imprima cada pestaña por separado:

do_settings_sections( $settings_section );

Luego, utiliza los botones de envío / reinicio específicos de la pestaña:

<?php submit_button( __( 'Save Settings', 'oenology' ), 'primary', 'theme_oenology_options[submit-' . $currenttab . ']', false ); ?>
<?php submit_button( __( 'Reset Defaults', 'oenology' ), 'secondary', 'theme_oenology_options[reset-' . $currenttab . ']', false ); ?>

Ahora, dentro de su devolución de llamada de validación, puede determinar qué pestaña enviar / restablecer está seleccionada:

    $tabs = oenology_get_settings_page_tabs();

    // Determine what type of submit was input
    $submittype = 'submit';        
    foreach ( $tabs as $tab ) {
            $resetname = 'reset-' . $tab['name'];
            if ( ! empty( $input[$resetname] ) ) {
                    $submittype = 'reset';
            }
    }

    // Determine what tab was input
    $submittab = 'varietals';        
    foreach ( $tabs as $tab ) {
            $submitname = 'submit-' . $tab['name'];
            $resetname = 'reset-' . $tab['name'];
            if ( ! empty( $input[$submitname] ) || ! empty($input[$resetname] ) ) {
                    $submittab = $tab['name'];
            }
    }

... y luego actúe solo sobre ese subconjunto de opciones, a medida que avance por su lista blanca.

(He dejado un montón de código aquí, ya que esto es solo una prueba de concepto. Si desea ver un ejemplo funcional, marque aquí .

    
respondido por el Chip Bennett 20.10.2013 - 23:21

Lea otras preguntas en las etiquetas