Quels sont les avantages de l'API Settings?

13

Permettez-moi de préfacer cela en disant que je ne travaille presque jamais avec WordPress - en fait, la dernière fois que j'ai fait un site dans WordPress était de retour pendant la 2.2. Hier, j'ai tout gâché et j'ai posé plusieurs questions ici pour essayer de faire fonctionner un plugin de menu de base.

J'ai maintenant le plugin entièrement fonctionnel et se comporte exactement comme je m'y attendais, j'ai donc décidé d'apporter des modifications mineures ici et là pour ajouter des fonctionnalités et la compatibilité - y compris en utilisant l'API Settings. Cependant, un très court moment dans la lecture des didacticiels sur cette API et je suis devenu assez confus, puis cette confusion n'a fait que s'approfondir en lisant la suite et en essayant de mettre en œuvre les exemples - ce qui a été rendu encore plus difficile par le fait que mon plugin est implémenté en tant que classe. .

À moins que je ne fasse quelque chose de mal, d'après ce que je comprends, l'utilisation de l'API Paramètres nécessite la création d'une nouvelle fonction PAR RÉGLAGE. Cela signifie 3 à 5 fonctions pour le plugin moyen, et jusqu'à des centaines pour des plugins plus avancés. Il semble tout simplement ridicule d'écrire ces nombreuses fonctions (et de développer un système de nommage pour éviter de les confondre) alors que vous pourriez tout aussi facilement importer toutes les $_POSTvariables applicables dans un tableau et renoncer à tout le bordel.

Je suis peut-être démodé, mais à moins qu'il y ait quelque chose à gagner, je ne vois pas la raison de tripler ou quadrupler la quantité de code que j'écris. Voici comment j'ai géré les options avant d'essayer d'ajouter l'API Paramètres:

    function __construct() {
        /* constructor stuff */
        $this->options = $this->db_options = get_option( 'de-menu-options' );
        if( $this->options === false ){
            $this->options = $this->defaults;
        }
        if (is_admin()) {
            add_action('admin_menu', array(&$this, 'admin_menu'));
        }   
        /* more stuff */

        // When WordPress shuts down we store changes to options
        add_action('shutdown', array(&$this, 'update'));
    }

    public function admin_menu() {
        add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options'));
        add_option('de-menu-options', $this->options);
    }

    public function options() {
        if (!current_user_can('manage_options')) {
            wp_die( __('You do not have sufficient permissions to access this page.') );
        }
        if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
            // These options are saved to the database at shutdown
            $this->options = array(
                "columns" => $_POST["de-menu-columns"],
                "maintenance" => $_POST["de-menu-maintenance"]
            );
            echo 'DE Menu options saved';
        }
?>

<div class="wrap">
    <h2>DE Menu Plugin</h2>
    <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
        <?php settings_fields('de-menu-options'); ?>
        <input type="checkbox" name="de-menu-maintenance" />
        <label for="de-menu-columns">Columns:</label>
        <input type="text" name="de-menu-columns" value="<?php echo $this->options['columns']; ?>" />
        <p class="submit">
        <input type="submit" name="de-menu-submit" value="Update Options »" />
        </p>
    </form>
</div>
<?php
    }

    function update() {
        // By storing all changes at the end we avoid multiple database calls
        $diff = array_diff( $this->options, $this->db_options );
        if( !empty( $diff )  ){
            update_option('de-menu-options', $this->options);
        }
    }

Maintenant, avec l'API des paramètres, j'ai quelque chose de plus comme ceci:

    function __construct() {
        /* constructor stuff */
        // Do I load options? Will they be loaded for me? Who knows?
        if (is_admin()) {
            add_action('admin_menu', array(&$this, 'admin_menu'));
            add_action('admin_init', array(&$this, 'admin_init'));
        }   
        /* more stuff */
        // Settings API should update options for me... I think
    }

    public function admin_menu() {
        add_options_page('DE Menu Options', 'DE Menu', 'manage_options', 'de-menu-options', array(&$this, 'options'));
        add_option('de-menu-options', $this->options);
    }

    public function admin_init() {
        register_setting('de-menu-options','de-menu-options',array(&$this,'validate'));
        add_settings_section('de-menu-main-options', 'Main Settings', 'options_section', 'de-menu-options');
        add_settings_field('de-menu-maintenance', 'Maintenance Mode', array(&$this,'options_maintenance'), 'de-menu-options', 'de-menu-main-options');
        add_settings_field('de-menu-columns', 'Columns', array(&$this,'options_columns'), 'de-menu-options', 'de-menu-main-options');
    }

    public function options() {
        if (!current_user_can('manage_options')) {
            wp_die( __('You do not have sufficient permissions to access this page.') );
        }
        if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
            // These options are saved to the database at shutdown
            $this->options = array(
                "columns" => $_POST["de-menu-columns"],
                "maintenance" => $_POST["de-menu-maintenance"]
            );
            echo 'DE Menu options saved';
        }
?>

<div class="wrap">
    <h2>DE Menu Plugin</h2>
    <form method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
        <?php settings_fields('de-menu-options'); ?>
        <?php do_settings_sections('de-menu-options'); ?>
        <p class="submit">
        <input type="submit" name="de-menu-submit" value="Update Options »" />
        </p>
    </form>
</div>
<?php
    }

    public function options_section() {
        echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
    }

    public function options_maintenance() {
        echo "<input id='de-menu-maintenance' name='options[maintenance]' type='checkbox' />";
    }

    public function options_columns() {
        echo "<input id='de-menu-columns' name='options[columns]' type='checkbox' value=".$this->options['columns']."/>";
    }

    function validate($options) {
        return $options; // I guess?
    }

Il est probablement douloureusement évident à partir des barres de défilement que le code est déjà plus long avec seulement deux options. Il est tout aussi évident, d'après les commentaires, que je ne comprends pas tout à fait ce que je fais. Ensuite, il faut avoir 5 nouvelles fonctions (et n'en supprimer qu'une seule) pour accomplir tout cela.

Alors, quel avantage retirez-vous de tout ce travail supplémentaire?

stevendesu
la source
Ne les utilisez pas dans de tels cas. Je pense qu'ils sont destinés aux débutants PHP, qui ont besoin de 3-4 options dans leur plugin / thème. C'est l'une des "fonctionnalités" qui n'aurait jamais dû être implémentée ... C'est fondamentalement une API pour une autre API :)
onetrickpony
3
J'utilise l'API des paramètres pour tout ce que j'écris, tout dépend de la façon dont vous l'utilisez, notez que vous pouvez utiliser l'API sans même l'utiliser add_settings_sectionet add_settings_field, ces deux fonctions ajoutent plus que tout à du ballonnement à votre code, évitez celles-ci et vous évitez le ballonnement ..
t31os
1
Je fais la même chose que t3los: enregistrez le paramètre lui-même, puis je code simplement les formulaires en HTML sur ma page de paramètres. Si vous voulez voir un moyen très simple de le faire et conserver le code pour plus tard, consultez le plugin WordPress SEO de Yoast.
chrisguitarguy

Réponses:

8

Mon point de vue est que l'objectif principal et l'avantage de l'API Settings est la structure .

Il permet de conserver des configurations de paramètres complexes:

  • ordonné (logique d'inscription et sections);
  • sécurisé (nonces, rappels de validation);
  • extensible (s'accrochant à une autre page ou permettant d'être accroché).

Comme pour tout frais généraux structurels, il bénéficie à des cas d'utilisation plus complexes et à des cas moins simples.

Vous pouvez donc mettre en œuvre tout ce que l'API Settings fait sans l'utiliser. La question est de savoir si vous pouvez accomplir cela de manière aussi fiable, sécurisée et extensible.

Rarst
la source
J'ai finalement obtenu ma page Paramètres fonctionnant avec l'aide de ce tutoriel: alisothegeek.com/2011/01/wordpress-settings-api-tutorial-1 et avec l'aide des instructions de commutateur et des fonctions d'assistance, je dois dire que les choses sont maintenant plus ordonnées dans mon code (ce qui est bien puisque je prévois de passer de mes deux paramètres de test à 15-20 paramètres au total).
stevendesu
1
@steven_desu yep, la blague en cours est que tous ceux qui utilisent l'API Settings écrivent un cadre pour cela. :) Les fonctions d'aide de couple sont presque inévitables. Notez également que l'API Settings n'est pas considérée comme finalisée et qu'il est (vague) prévu de l'améliorer à l'avenir (je pense qu'elle a été mentionnée dans le contexte des plans 3.3).
Rarst
1
J'espère certainement que cela s'est amélioré. Honnêtement, je ne vois aucun avantage à l'API Paramètres, mais plutôt chaque avantage dont je profite maintenant est le résultat du cadre que j'ai emprunté pour cela. J'aime que tous les éléments du formulaire soient maintenant générés dynamiquement avec la même apparence ... mais ce n'est pas l'API Paramètres. J'aime que les paramètres par défaut et l'enregistrement des paramètres soient gérés par les mêmes définitions ... mais ce n'est pas l'API Paramètres. J'aime que jQuery rend non seulement les formulaires jolis, mais est progressivement amélioré - mais j'ai dû coder manuellement l'amélioration progressive ...
stevendesu
5

Si vous utilisez correctement les rappels, vous n'avez pas besoin de tout le code redondant. Voici comment j'implémente l'API Settings, d'une manière complètement évolutive .

Avantages (entre autres):

  • L'API des paramètres force le nettoyage des données utilisateur non fiables.
  • L'API des paramètres force les options à être enregistrées en tant que tableau d'options, ce qui entraîne une seule entrée de base de données wp_options, plutôt que des entrées de base de données discrètes pour chaque option
  • L'API des paramètres facilite le renforcement de la sécurité du formulaire des paramètres
  • L'API des paramètres facilite l'interface utilisateur d'administration cohérente avec l'interface d'administration principale, résultant en une meilleure expérience utilisateur
Chip Bennett
la source
Donc, cela impose essentiellement des normes de sécurité et d'esthétique que je suivais déjà sans son aide? Je vais cependant lire le tutoriel que vous avez lié. Si cela rend l'API Paramètres aussi simple que le codage manuel des formulaires (ou plus facile), j'accepterai cette réponse
stevendesu
Savez-vous que le code source que vous avez indiqué implémente les fonctions oenology_get_settings_by_tab()et oenology_get_default_optionssans jamais les définir au préalable? Je pensais que c'était assez mauvais à 209 lignes de code (après avoir supprimé les commentaires et les lignes vides), mais une fois ces fonctions définies, ce sera encore plus long ... Pour quatre options?
stevendesu
Ils sont définis ailleurs. Le oenology_get_settings_by_tab()n'est pas vraiment pertinent pour ce que vous faites. Mais vous devez définir votre balisage de champ de formulaire quelque part , tout comme vous devez valider / désinfecter les entrées utilisateur d'une manière ou d' une autre , donc si vous le faites correctement, vous aurez également le même code.
Chip Bennett
0

Merci d'avoir posté ça, je me demandais exactement la même chose. Beaucoup de fonctions.

Pour les réduire, vous pouvez stocker vos options sous forme de tableaux. Wordpress sérialise les données pour vous. Cela économise du code (ou fonctionne de toute façon), mais aggrave les données. Par exemple, si vous souhaitez trier, modifier manuellement, exporter, etc., vos tables, elles auront ces valeurs sérialisées. D'un autre côté, votre plugin ajoute moins d'entrées au tableau des options et elles sont plus faciles à nettoyer.

Voici donc votre code refait. Quelques notes:

  • Mon exemple montre à la fois des options simples (de_w, de_h) et une option de tableau (de_width_height).
  • Toujours désinfecter les entrées utilisateur. J'ai utilisé des entiers dans l'exemple car ils sont faciles à désinfecter.
  • Vous n'avez pas besoin de $ _POST, nonces, check_admin_referer (), update_option (), etc., lorsque vous utilisez l'API Settings.
  • L'enregistrement se produit au chargement de la page suivante, pas à l'arrêt. WP fait ensuite une redirection vers votre page. Donc, pour déboguer, imprimer une sortie et appeler wp_die () dans l'une des fonctions de validation.
  • L'action du formulaire est toujours "options.php". Voilà comment fonctionne l'API Paramètres. N'utilisez rien d'autre. Eh bien, vous pouvez utiliser admin_url ('options.php') si vous le souhaitez.
  • WP imprimera le message de sauvegarde pour vous.
  • Améliorations non incluses ici: utilisation <label>pour l'accessibilité. Utilisation de add_settings_error (), settings_error (), qui gèrent les messages ainsi que les erreurs. C'est souvent la seule raison d'avoir des fonctions de validation distinctes pour chaque option. Vous pouvez voir ci-dessous validate_w () et validate_h () pourrait être une fonction. J'ai cherché à résumer la messagerie, mais je ne me souviens pas d'avoir suffisamment d'informations dans le rappel de validation. Comme dans quel domaine vous travaillez.
  • Les fonctions de rappel de validation obtiennent une valeur brute $ _POST de l'API Settings. J'aime nommer le paramètre comme tel, $ raw. Pour l'option tableau, vous obtenez un tableau, comme par magie.
  • Edit: $ this is better than & $ this.

Code:

<?php
$foo= new de_Foo();
class de_Foo {
function __construct() {
    if (is_admin()) {
        add_action('admin_menu', array($this, 'admin_menu'));
        add_action('admin_init', array($this, 'admin_init'));
    } 
}
public function admin_menu() {
    add_options_page(
       'DE Menu Options',
       'DE Menu',
       'manage_options',
       'de-menu-options',
       array($this,'xoxptions')
    );
    // add_option('de-menu-options', $this->options);
}
public function admin_init() {
 register_setting(
      'de-menu-settings-group',
      'de_w',
      array($this, 'validate_w')
 );
 register_setting(
      'de-menu-settings-group',
      'de_h',
      array($this, 'validate_h')
 );
 register_setting(
      'de-menu-settings-group',
      'de_width_height',
      array($this, 'validate_width_height')
 );
 add_settings_section(
      'de-menu-settings-section-size',
      'Size',
      array($this, 'settings_section_size_render'),
      'de-menu-options'
 );
 add_settings_field(
      'de_w',
      'W',
      array($this, 'w_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_h',
      'H',
      array($this, 'h_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
 add_settings_field(
      'de_width_height',
      'Width / Height',
      array($this, 'width_height_render'),
      'de-menu-options',
      'de-menu-settings-section-size'
 );
}
public function options() {
    if (!current_user_can('manage_options')) {
        wp_die( __('You do not have sufficient permissions to access this page.') );
    }
////////////////////////////
// no no no
////////////////////////////
//         if ( !empty($_POST) && check_admin_referer('de-menu-options') ) {
//             // These options are saved to the database at shutdown
//             $this->options = array(
//                 "columns" => $_POST["de-menu-columns"],
//                 "maintenance" => $_POST["de-menu-maintenance"]
//             );
//             echo 'DE Menu options saved';
//         }
////////////////////////////
?>
<div class="wrap">
<h2>DE Menu Plugin</h2>
<form method="post" action="<?php echo admin_url('options.php'); ?>">
    <?php settings_fields('de-menu-settings-group'); ?>
    <?php do_settings_sections('de-menu-options'); ?>
    <p class="submit">
    <input type="submit" name="de-menu-submit" value="Update Options" />
    </p>
</form>
</div>
<?php
}
public function settings_section_size_render() {
    echo '<p>' . __('Main description of this section here.','de-menu-lang') . '</p>';
}
public function w_render() {
 $w= esc_attr( get_option('de_w') );
 echo "<p><input name='de_w' value='$w'></p>\n";
}
public function h_render() {
 $h= esc_attr( get_option('de_h') );
 echo "<p><input name='de_h' value='$h'></p>\n";
}
public function width_height_render() {
 $width_height= get_option('de_width_height', array());
 $width= esc_attr( @$width_height['width'] );
 $height= esc_attr( @$width_height['height'] );
 echo "<p>Width: <input name='de_width_height[width]' value='$width'></p>\n";
 echo "<p>Height: <input name='de_width_height[height]' value='$height'></p>\n";
}
function validate_w($raw) {
 return (int)$raw;
}
function validate_h($raw) {
 return (int)$raw;
}
function validate_width_height($raw) {
 is_array($raw) or $raw= array();
 $result= array();
 $result['width']= (int)@$raw['width'];
 $result['height']= (int)@$raw['height'];
 return $result;
}
}
kitchin
la source