API de paramètres avec exemples de tableaux

32

J'utilise le livre de développement du plugin Wrox WordPress comme référence principale pour démarrer avec un nouveau plugin et je comprends que tous les paramètres peuvent être sauvegardés sous 1 tableau, mais le livre ne donne pas d'exemple et tous les éléments Je trouve que sur le Web semble si différent d’un exemple à l’autre. La seconde partie d'un post de Konstantin me rapproche mais j'aimerais vraiment en voir plus exemple complet avec plusieurs champs.

    
posée Bjorn 20.05.2013 - 02:51
la source

1 réponse

31

Réponse courte: vos valeurs d'attribut name doivent utiliser le schéma option_name[array_key] . Alors, quand vous utilisez…

<input name="option_name[key1]">
<input name="option_name[key2]">

… vous obtenez un tableau comme valeur d'option dans votre fonction de validation:

array (
    'key1' => 'some value',
    'key2' => 'some other value'
)

PHP le fait pour vous, ce n’est pas une fonctionnalité de WordPress. :)

Comment faire en sorte que cela fonctionne avec l'API de paramètres?

Disons que nous voulons cette page d’options et que toutes les valeurs doivent être stockées dans une option et validées dans une fonction.

  

Lapagedesoptions

Nousavonsbesoinducrochetadmin_menuetdedeuxfonctions:unepourenregistrerlapage,unepourafficherlerésultat.

add_action('admin_menu','t5_sae_add_options_page');functiont5_sae_add_options_page(){add_options_page('T5SettingsAPIExample',//$page_title,'T5SAE',//$menu_title,'manage_options',//$capability,'t5_sae_slug',//$menu_slug't5_sae_render_page'//Callback);}functiont5_sae_render_page(){?><divclass="wrap">
        <h2><?php print $GLOBALS['title']; ?></h2>
        <form action="options.php" method="POST">
            <?php 
            settings_fields( 'plugin:t5_sae_option_group' );
            do_settings_sections( 't5_sae_slug' ); 
            submit_button(); 
            ?>
        </form>
    </div>
    <?php
}

Le formulaire action doit être options.php , sinon la validation ne sera pas appelée. Regardez la source PHP de wp-admin/options-permalink.php - il y a un piège caché do_settings_sections('permalink'); - mais cela ne fonctionne pas car la forme action est fausse.

Maintenant, revenons à notre page personnalisée. Nous le faisons mieux que WordPress.

Enregistrer les paramètres, les sections et les champs

Nous accrochons admin_init lorsque nous en avons besoin et appelons une fonction d'enregistrement.

if ( ! empty ( $GLOBALS['pagenow'] )
    and ( 'options-general.php' === $GLOBALS['pagenow']
        or 'options.php' === $GLOBALS['pagenow']
    )
)
{
    add_action( 'admin_init', 't5_sae_register_settings' );
}

La partie importante ici est la suivante: $GLOBALS['pagenow'] doit être options-general.php (pour la sortie) ou options.php (pour la validation). N'appelez pas tout le code suivant sur chaque demande. La plupart des tutoriels et presque tous les plugins se trompent.

OK, inscrivons-nous comme un fou:

  1. Nous récupérons les valeurs des options de notre page et les analysons en fonction de certaines valeurs par défaut. Assez basique.

  2. Nous enregistrons un groupe de paramètres avec le nom plugin:t5_sae_option_group . J'aime les noms préfixés, ils sont plus faciles à trier et à comprendre de cette façon.

  3. Ensuite, nous enregistrons deux sections, 1 et 2.

  4. Et nous ajoutons trois sections, deux pour la première section, une pour la seconde. Nous passons le nom de l’option et la valeur échappée aux fonctions de rappel pour chaque champ. Les gestionnaires de sortie ne doivent pas modifier les données, mais juste ajouter du code HTML.

function t5_sae_register_settings()
{
    $option_name   = 'plugin:t5_sae_option_name';

    // Fetch existing options.
    $option_values = get_option( $option_name );

    $default_values = array (
        'number' => 500,
        'color'  => 'blue',
        'long'   => ''
    );

    // Parse option values into predefined keys, throw the rest away.
    $data = shortcode_atts( $default_values, $option_values );

    register_setting(
        'plugin:t5_sae_option_group', // group, used for settings_fields()
        $option_name,  // option name, used as key in database
        't5_sae_validate_option'      // validation callback
    );

    /* No argument has any relation to the prvious register_setting(). */
    add_settings_section(
        'section_1', // ID
        'Some text fields', // Title
        't5_sae_render_section_1', // print output
        't5_sae_slug' // menu slug, see t5_sae_add_options_page()
    );

    add_settings_field(
        'section_1_field_1',
        'A Number',
        't5_sae_render_section_1_field_1',
        't5_sae_slug',  // menu slug, see t5_sae_add_options_page()
        'section_1',
        array (
            'label_for'   => 'label1', // makes the field name clickable,
            'name'        => 'number', // value for 'name' attribute
            'value'       => esc_attr( $data['number'] ),
            'option_name' => $option_name
        )
    );
    add_settings_field(
        'section_1_field_2',
        'Select',
        't5_sae_render_section_1_field_2',
        't5_sae_slug',  // menu slug, see t5_sae_add_options_page()
        'section_1',
        array (
            'label_for'   => 'label2', // makes the field name clickable,
            'name'        => 'color', // value for 'name' attribute
            'value'       => esc_attr( $data['color'] ),
            'options'     => array (
                'blue'  => 'Blue',
                'red'   => 'Red',
                'black' => 'Black'
            ),
            'option_name' => $option_name
        )
    );

    add_settings_section(
        'section_2', // ID
        'Textarea', // Title
        't5_sae_render_section_2', // print output
        't5_sae_slug' // menu slug, see t5_sae_add_options_page()
    );

    add_settings_field(
        'section_2_field_1',
        'Notes',
        't5_sae_render_section_2_field_1',
        't5_sae_slug',  // menu slug, see t5_sae_add_options_page()
        'section_2',
        array (
            'label_for'   => 'label3', // makes the field name clickable,
            'name'        => 'long', // value for 'name' attribute
            'value'       => esc_textarea( $data['long'] ),
            'option_name' => $option_name
        )
    );
}

Tous les gestionnaires de rappel des sections et des champs seront appelés automatiquement lorsque nous appellerons do_settings_sections( 't5_sae_slug' ); dans notre page. Nous l'avons déjà fait, nous avons donc besoin de…

Imprimer les champs

Notez comment les attributs name sont construits: le option_name transmis est la première partie, la clé du tableau suit entre crochets [] .

function t5_sae_render_section_1()
{
    print '<p>Pick a number between 1 and 1000, and choose a color.</p>';
}
function t5_sae_render_section_1_field_1( $args )
{
    /* Creates this markup:
    /* <input name="plugin:t5_sae_option_name[number]"
     */
    printf(
        '<input name="%1$s[%2$s]" id="%3$s" value="%4$s" class="regular-text">',
        $args['option_name'],
        $args['name'],
        $args['label_for'],
        $args['value']
    );
    // t5_sae_debug_var( func_get_args(), __FUNCTION__ );
}
function t5_sae_render_section_1_field_2( $args )
{
    printf(
        '<select name="%1$s[%2$s]" id="%3$s">',
        $args['option_name'],
        $args['name'],
        $args['label_for']
    );

    foreach ( $args['options'] as $val => $title )
        printf(
            '<option value="%1$s" %2$s>%3$s</option>',
            $val,
            selected( $val, $args['value'], FALSE ),
            $title
        );

    print '</select>';

    // t5_sae_debug_var( func_get_args(), __FUNCTION__ );
}
function t5_sae_render_section_2()
{
    print '<p>Makes some notes.</p>';
}

function t5_sae_render_section_2_field_1( $args )
{
    printf(
        '<textarea name="%1$s[%2$s]" id="%3$s" rows="10" cols="30" class="code">%4$s</textarea>',
        $args['option_name'],
        $args['name'],
        $args['label_for'],
        $args['value']
    );
}

Oh, j'ai introduit une fonction t5_sae_debug_var() . La voici:

function t5_sae_debug_var( $var, $before = '' )
{
    $export = esc_html( var_export( $var, TRUE ) );
    print "<pre>$before = $export</pre>";
}

Utile pour voir si nous avons obtenu ce que nous espérions.

Maintenant, cela fonctionne plutôt bien, il suffit d’une chose:

Valider le tableau d'options

Comme nous avons utilisé la notation entre crochets, notre valeur est un tableau. Il suffit de parcourir chaque élément et de le valider.

function t5_sae_validate_option( $values )
{
    $default_values = array (
        'number' => 500,
        'color'  => 'blue',
        'long'   => ''
    );

    if ( ! is_array( $values ) ) // some bogus data
        return $default_values;

    $out = array ();

    foreach ( $default_values as $key => $value )
    {
        if ( empty ( $values[ $key ] ) )
        {
            $out[ $key ] = $value;
        }
        else
        {
            if ( 'number' === $key )
            {
                if ( 0 > $values[ $key ] )
                    add_settings_error(
                        'plugin:t5_sae_option_group',
                        'number-too-low',
                        'Number must be between 1 and 1000.'
                    );
                elseif ( 1000 < $values[ $key ] )
                    add_settings_error(
                        'plugin:t5_sae_option_group',
                        'number-too-high',
                        'Number must be between 1 and 1000.'
                    );
                else
                    $out[ $key ] = $values[ $key ];
            }
            elseif ( 'long' === $key )
            {
                $out[ $key ] = trim( $values[ $key ] );
            }
            else
            {
                $out[ $key ] = $values[ $key ];
            }
        }
    }

    return $out;
}

C’est plutôt moche; Je n’utiliserais pas ce code en production. Mais il fait ce qu’il devrait: il renvoie un tableau validé de valeurs. WordPress sérialise le tableau, le stocke sous notre nom d’option dans la base de données et le renvoie sans numéro de série, lorsque nous appelons get_option() .

Tout cela fonctionne, mais c'est compliqué, nous obtenons des balises à partir de 1998 ( <tr valign="top"> ) et de nombreux licenciements.

Utilisez les paramètres de l'API lorsque vous devez. Vous pouvez également utiliser admin_url( 'admin-post.php' ) comme action de formulaire (regardez son source) et créer la page de paramètres complète avec votre propre code, probablement plus élégant.

En fait, vous devez le faire lorsque vous écrivez un plug-in réseau, car les paramètres de l'API ne fonctionnent pas dans cet environnement.

Il y a aussi des cas particuliers et des parties incomplètes que je n’ai pas mentionnées ici - vous les trouverez quand vous en aurez besoin. :)

    
réponse donnée fuxia 21.05.2013 - 01:17
la source

Lire d'autres questions sur les étiquettes