3 approches pour ajouter des champs configurables à votre plugin WordPress

Publié: 2022-03-10
Résumé rapide ↬ Quiconque a créé un plugin WordPress comprend la nécessité de créer des champs configurables pour modifier le fonctionnement du plugin. Il existe d'innombrables utilisations pour les options configurables dans un plugin , et presque autant de façons d'implémenter lesdites options. Vous voyez, WordPress permet aux auteurs de plugins de créer leur propre balisage dans leurs pages de paramètres. En tant qu'effet secondaire, les pages de paramètres peuvent varier considérablement d'un plugin à l'autre. Dans cet article, nous allons passer en revue trois façons courantes de rendre votre plugin configurable. Nous allons commencer par créer une page de paramètres et créer nos champs en utilisant l'API de paramètres WordPress par défaut. Je vous expliquerai ensuite comment configurer vos champs avec un gestionnaire personnalisé. Enfin, je vais vous montrer comment intégrer un super plugin de champs configurables Advanced Custom Fields (ACF) dans votre propre plugin.

Quiconque a créé un plugin WordPress comprend la nécessité de créer des champs configurables pour modifier le fonctionnement du plugin. Il existe d'innombrables utilisations pour les options configurables dans un plugin , et presque autant de façons d'implémenter lesdites options. Vous voyez, WordPress permet aux auteurs de plugins de créer leur propre balisage dans leurs pages de paramètres. En tant qu'effet secondaire, les pages de paramètres peuvent varier considérablement d'un plugin à l'autre.

Dans cet article, nous allons passer en revue trois façons courantes de rendre votre plugin configurable. Nous allons commencer par créer une page de paramètres et créer nos champs en utilisant l'API de paramètres WordPress par défaut.

Lectures complémentaires sur SmashingMag :

  • Étendre WordPress avec des champs personnalisés
  • Hacks de champs personnalisés pour WordPress
  • Extension des champs personnalisés avancés avec vos propres contrôles
  • Le guide complet des types de publication personnalisés

Je vous expliquerai ensuite comment configurer vos champs avec un gestionnaire personnalisé. Enfin, je vais vous montrer comment intégrer un super plugin de champs configurables Advanced Custom Fields (ACF) dans votre propre plugin.

Plus après saut! Continuez à lire ci-dessous ↓

Comme il s'agit d'un long article, voici une table des matières avec des liens vers chacune des principales sections :

  • Création de notre page de plugins et de paramètres
  • Approche 1 : Utilisation de la fonctionnalité WordPress intégrée
  • Approche 2 : Configurer un formulaire et un gestionnaire personnalisés
  • Approche 3 : Intégrer ACF (Advanced Custom Fields) dans votre plugin

Pour des exemples de code, veuillez consulter le référentiel que j'ai mis en place pour accompagner ce message.

Création de notre page de plugins et de paramètres

La première chose que nous devons faire est de configurer notre plugin et de créer une page de paramètres. Les trois approches décrites dans cet article commencent par la structure du plugin ci-dessous. Cette structure de plugin est orientée objet , il peut donc y avoir quelques différences dans votre propre code si votre plugin est écrit de manière procédurale. Portez une attention particulière au format de la fonction de rappel dans les actions et les filtres.

 /* Plugin Name: Smashing Fields Plugin description: >- Setting up configurable fields for our plugin. Author: Matthew Ray Version: 1.0.0 */ class Smashing_Fields_Plugin { // Our code will go here } new Smashing_Fields_Plugin();

Dans notre classe, nous allons ajouter un crochet d'action pour ajouter la page des paramètres :

 public function __construct() { // Hook into the admin menu add_action( 'admin_menu', array( $this, 'create_plugin_settings_page' ) ); }

Vous pouvez voir que le rappel de notre action est create_plugin_settings_page , créons donc cette méthode. Remarque : j'ai configuré les arguments en tant que variables nommées distinctes pour donner un contexte à notre code, mais vous pouvez simplement placer les valeurs directement dans la fonction pour économiser de la mémoire.

 public function create_plugin_settings_page() { // Add the menu item and page $page_title = 'My Awesome Settings Page'; $menu_title = 'Awesome Plugin'; $capability = 'manage_options'; $slug = 'smashing_fields'; $callback = array( $this, 'plugin_settings_page_content' ); $icon = 'dashicons-admin-plugins'; $position = 100; add_menu_page( $page_title, $menu_title, $capability, $slug, $callback, $icon, $position ); }

Jetez un œil au codex WP pour add_menu_page pour plus d'informations.

Cette fonction créera notre page ainsi que l'élément de menu. Les parties importantes ici sont les arguments de slug, de capacité et de rappel. Le slug que nous utiliserons plus tard pour enregistrer nos champs, alors notez-le quelque part. Vous pouvez modifier la capacité pour permettre à différents niveaux d'utilisateurs d'accéder à votre page de paramètres. Quant au rappel, nous créerons cette méthode sous peu. Notez que vous pouvez également mettre une classe dashicon directement dans la fonction pour changer l'icône du menu. Le dernier argument est la position de l'élément de menu dans le menu ; jouez avec ce nombre pour trouver l'endroit dans le menu où vous souhaitez que vos paramètres tombent. Remarque : vous pouvez utiliser des valeurs décimales pour éviter les conflits avec d'autres éléments de menu.

Notre prochaine étape consiste à créer la méthode de rappel plugin_settings_page_content pour notre page de paramètres.

 public function plugin_settings_page_content() { echo 'Hello World!'; }

Si vous enregistrez votre plugin et actualisez le panneau d'administration de WordPress, vous devriez voir ce qui suit :

Disposition de départ pour la page des paramètres
L'état de départ de la page des paramètres. (Voir la grande version)

Vous pouvez voir que votre page de paramètres est un élément de menu de niveau supérieur. Vous préférerez peut-être le laisser ainsi en fonction des besoins de votre page de paramètres. Cependant, vous souhaiterez peut-être également que les paramètres de votre plug-in soient placés sous un autre élément de menu. Dans ce cas, vous changerez simplement la dernière ligne de la méthode create_plugin_settings_page comme suit :

 add_submenu_page( 'options-general.php', $page_title, $menu_title, $capability, $slug, $callback );

Ici, nous changeons la fonction add_menu_page en add_submenu_page et préfixons un nouvel argument. Cet argument est l'élément de menu parent sous lequel se trouvera la nouvelle page de paramètres. Dans la documentation add_submenu_page , vous pouvez voir une assez bonne liste des éléments de menu parents et de leurs slugs. Vous pouvez également voir que nous n'avons plus les deux derniers arguments, $icon et $position . Puisque nous sommes maintenant dans la section sous-menu, nous n'avons plus de contrôle sur la position de l'élément. De plus, les sous-menus n'ont pas d'icônes à leur disposition, il n'y a donc pas besoin de cet argument.

Si vous enregistrez ce nouveau code, vous verrez que notre page de paramètres s'affichera sous l'élément de menu Paramètres :

La page du sous-menu est maintenant sous les paramètres
La page des paramètres a maintenant été placée sous le menu Paramètres. (Voir la grande version)

Dans de nombreux cas, l'endroit le plus approprié pour ajouter une page de paramètres de plugin est sous l'élément Paramètres. Dans le codex WordPress, il explique que la section Paramètres est utilisée pour "Afficher les options de plug-in que seuls les administrateurs doivent afficher". Cependant, ce n'est qu'une ligne directrice, pas une règle.

Maintenant que nous avons configuré notre page de paramètres et que nous savons comment déplacer les éléments, nous pouvons commencer à travailler sur les champs. Le travail que nous avons fait jusqu'à présent sera réutilisé pour les différentes méthodes ci-dessous.

Approche 1 : Utilisation de la fonctionnalité WordPress intégrée

Avant d'entrer trop profondément dans le code, passons en revue certains des avantages et des inconvénients de l'utilisation de cette approche.

Avantages

  • Facile à intégrer dans les pages de paramètres existantes
  • La désinfection est faite pour vous
  • Peu susceptible de casser puisque le code est géré par WordPress
  • Peut être utilisé à la fois pour les thèmes et les plugins
  • Flexible, sécurisé et extensible

Les inconvénients

  • La validation des données personnalisées est manuelle
  • Les types de champs avancés (répéteurs, cartes, téléchargements, etc.) sont plus difficiles à mettre en œuvre

Quand devriez-vous utiliser cette approche ?

Cette approche est suffisamment flexible pour pouvoir être personnalisée pour des pages de paramètres très simples ou très avancées. Vous pouvez utiliser cette méthode dans la plupart des situations si cela ne vous dérange pas de faire certaines choses manuellement.

Commencer

En utilisant cette approche, nous devrons suivre le même balisage que les propres pages d'options de WordPress utilisent. Nous devrions modifier notre méthode plugin_settings_page_content comme suit :

 public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="post" action="options.php"> <?php settings_fields( 'smashing_fields' ); do_settings_sections( 'smashing_fields' ); submit_button(); ?> </form> </div> <?php }

Le balisage ci-dessus provient directement du codex WordPress sur la création de pages d'options. Le nom de la méthode doit correspondre au nom de rappel que nous avons mis dans la fonction add_menu_page ci-dessus. Le wrapper div est en fait le même qu'un formulaire WordPress par défaut et tirera les styles de ces sections. La balise de form pointe vers le gestionnaire de formulaire d'options par défaut pour WordPress.

Les trois lignes de PHP font plusieurs choses :

  • La fonction settings_fields est essentiellement une référence pour le reste de nos champs. L'argument de chaîne que vous mettez dans cette fonction doit correspondre à la variable $slug que nous avons configurée plus tôt - ce sera dans tous les champs que nous enregistrerons plus tard dans le plugin. Cette fonction génère également quelques entrées masquées pour le nonce, l'action de formulaire et quelques autres champs pour la page d'options.
  • La fonction suivante, do_settings_sections , est un espace réservé pour les sections et les champs que nous enregistrerons ailleurs dans notre plugin.
  • La dernière fonction, submit_button , affichera l'entrée de soumission, mais elle ajoutera également des classes en fonction du statut de la page. Il peut y avoir d'autres arguments que vous voudrez passer dans la fonction submit_button ; elles sont décrites dans le codex.

Si nous actualisons notre page de paramètres, nous devrions obtenir quelque chose qui ressemble à ceci :

Page de paramètres WordPress vide
Notre page de paramètres avant d'enregistrer des sections et des champs.

ça s'annonce un peu clairsemé ! Commençons à configurer les champs maintenant.

Sections et champs

WordPress sépare ses pages d'options en sections. Chaque section peut avoir une liste de champs qui lui sont associés. Nous devons enregistrer une section dans notre plugin avant de pouvoir commencer à ajouter nos champs. Ajoutez le code suivant à votre fonction constructeur :

 add_action( 'admin_init', array( $this, 'setup_sections' ) );

Ce crochet configurera les sections de notre page. Voici le code pour le rappel :

 public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', false, 'smashing_fields' ); }

Le premier argument est un identifiant unique pour la section et nous l'utiliserons pour les champs que nous souhaitons attribuer à la section. Ces identifiants doivent être uniques pour toutes les nouvelles sections de cette page. L'argument suivant est le titre qui est généré au-dessus de la section - vous pouvez en faire ce que vous voulez. Le troisième argument est le rappel. En ce moment, je l'ai défini sur false , mais nous y reviendrons sous peu. Le quatrième argument est la page d'options à laquelle les options seront ajoutées (la variable $slug du précédent).

Alors pourquoi y a-t-il un false dans notre rappel ? Eh bien, quelque chose qui n'est pas très clair lors de la configuration des options WordPress à l'aide de leur documentation est que plusieurs sections peuvent partager un rappel. Souvent, lorsque vous configurez un rappel, il existe une relation 1 pour 1 entre le crochet et le rappel. Donc, juste pour un exemple, essayons de créer trois sections avec le même rappel :

 public function setup_sections() { add_settings_section( 'our_first_section', 'My First Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_second_section', 'My Second Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); add_settings_section( 'our_third_section', 'My Third Section Title', array( $this, 'section_callback' ), 'smashing_fields' ); }

Ces trois sections ont le rappel section_callback défini dans ce troisième emplacement d'argument. Si nous créons ensuite une méthode qui correspond à ce rappel et y déposons un "Hello World" :

 public function section_callback( $arguments ) { echo '

Bonjour le monde

'; }

on obtient quelque chose qui ressemble à ceci :

Trois sections partageant la même fonction de rappel
Trois sections partageant le même rappel.

Je sais ce que vous pensez : "Pourquoi diable voudrais-je avoir le même texte dans toutes mes sections ?" La réponse est que vous ne le feriez probablement pas. C'est là que nous pouvons être un peu délicats avec la fonction add_settings_section . Si vous regardez la documentation de cette fonction, vous verrez que dans la partie Notes de la page, la fonction de rappel se verra attribuer un tableau d'arguments directement corrélés aux arguments de notre crochet. Si vous entrez et var_dump( $arguments ) , vous verrez tous les arguments passés dans notre fonction.

Nous pouvons ensuite écrire un simple commutateur dans notre rappel pour modifier le texte en fonction de l'ID qui lui est transmis :

 public function section_callback( $arguments ) { switch( $arguments['id'] ){ case 'our_first_section': echo 'This is the first description here!'; break; case 'our_second_section': echo 'This one is number two'; break; case 'our_third_section': echo 'Third time is the charm!'; break; } }

Nous avons maintenant un texte personnalisé pour chaque section que nous pouvons modifier en une seule fonction !

Texte personnalisé sous chaque section
Texte personnalisé sous chaque section.

Bien sûr, vous pouvez également spécifier des rappels uniques pour ces sections, mais cette approche vous permet de consolider votre code en une seule fonction. Cette idée fonctionne de la même manière pour la configuration des champs. Nous pouvons faire en sorte que tous nos champs partagent un rappel et qu'il produise le type de champ correct en fonction des arguments que nous transmettons. Ajoutons les champs à notre méthode constructeur. Placez ce code juste après le crochet de nos sections dans le constructeur :

 add_action( 'admin_init', array( $this, 'setup_fields' ) );

Puisque vous connaissez déjà l'exercice, je vais juste vous donner le rappel de notre action :

 public function setup_fields() { add_settings_field( 'our_first_field', 'Field Name', array( $this, 'field_callback' ), 'smashing_fields', 'our_first_section' ); }

Les arguments de cette fonction sont similaires à ceux de la fonction sections. Le premier argument est l'identifiant unique du champ. La seconde est l'étiquette qui apparaît à côté du champ. Dans le troisième argument, vous pouvez voir que j'appelle la méthode field_callback ; nous allons créer ce rappel en une seconde. La quatrième est la page d'options que nous voulons utiliser (notre $slug de tout à l'heure). Le cinquième argument est l' identifiant unique de la section à laquelle nous voulons affecter ce champ.

Voici le code du rappel dans notre troisième argument :

 public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; }

Ici, je copie simplement l'identifiant unique du champ dans le nom, l'ID et notre fonction get_option . Voyons à quoi ressemble notre page avec notre nouveau champ attaché :

Notre page de paramètres avec notre premier champ.
La page de configuration avec notre premier champ attaché.

Génial, nous avons notre terrain sur la page ! Essayez d'y ajouter du contenu et appuyez sur enregistrer les modifications, j'attendrai ici…

L'AS-tu fait? Si vous avez tout fait jusqu'à présent, vous devriez avoir une erreur disant quelque chose comme ERROR: options page not found , ou similaire. La raison pour laquelle cela se produit est en fait une fonctionnalité de sécurité de WordPress.

Vous voyez, sans cette fonctionnalité, un utilisateur pourrait aller dans le HTML et changer le nom d'un champ en tout ce qu'il voulait, appuyer sur Enregistrer, et il entrerait cette option dans la base de données avec le nom qui lui a été donné (en supposant que c'était un champ valide nom de l'option). Cela pourrait permettre à n'importe quel utilisateur de modifier les options sur d'autres pages (même celles auxquelles il ne pouvait normalement pas accéder) en entrant simplement le nom correct dans le champ et en appuyant sur Enregistrer - pas cool.

Ce problème est résolu en ajoutant une fonction appelée register_setting . À moins que vous ne disiez spécifiquement à WordPress, "Hey, ce champ est autorisé à être enregistré sur cette page", WordPress ne mettra pas à jour un champ dans la base de données. Donc, sous notre balisage de champ, nous ajouterons cette nouvelle fonction. Voici à quoi ressemble le rappel après avoir ajouté le code :

 public function field_callback( $arguments ) { echo '<input name="our_first_field" type="text" value="' . get_option( 'our_first_field' ) . '" />'; register_setting( 'smashing_fields', 'our_first_field' ); }

Le premier argument de la nouvelle fonction est la page d'options sur laquelle nous voulons enregistrer le champ (le $slug de tout à l'heure) et le deuxième argument est le champ que nous voulons enregistrer. Maintenant, essayez de mettre à jour le champ - cela a fonctionné !

Toutes nos félicitations! Vous venez d'enregistrer votre premier champ à l'aide de l'API WordPress Settings. Et maintenant, que se passe-t-il si nous voulons avoir différents types de champs au lieu de simplement du texte ? Revoyons notre rappel de champ et parlons de cette variable $arguments transmise à notre fonction.

Arguments de terrain

Si nous entrons dans notre callback de champ et var_dump( $arguments ) nous obtiendrons un tableau vide. Ce qui donne? Dans notre rappel de section, nous avons reçu un tas de choses sur la section. Eh bien, il se passe quelque chose de différent ici. Si vous consultez la documentation de add_settings_field , un cinquième argument peut être passé à la fonction. Cette variable est directement corrélée à la variable $arguments dans notre rappel. Nous allons donc vouloir y mettre nos nouveautés.

Si nous regardons l'un des champs par défaut dans une page de paramètres WordPress, nous pouvons voir qu'il y a plusieurs zones que nous pouvons ajouter à notre champ pour obtenir une mise en forme par défaut. Voici une capture d'écran du champ fuseau horaire dans la page des paramètres généraux :

Le champ de fuseau horaire WordPress
Le champ de fuseau horaire WordPress. (Voir la grande version)

En utilisant ce champ comme point de départ, passons en revue les données que nous voulons transmettre dans notre rappel de champ.

  • L'identifiant unique
  • Le libellé du champ (Fuseau horaire dans l'exemple)
  • Dans quelle section il doit aller
  • Le type de champ (texte, textarea, select, etc.)
  • Dans le cas où il y a plusieurs options, nous voudrons celles-ci
  • Peut-être un espace réservé si le type de champ en prend un en charge
  • Texte d'aide (à droite du champ dans l'exemple)
  • Texte supplémentaire (sous le champ dans l'exemple)
  • Peut-être une sélection par défaut s'il y en a une

À partir de cette liste, nous pouvons configurer un tableau associatif de champs et de valeurs que nous pouvons transmettre à notre rappel :

 public function setup_fields() { $fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ) ); foreach( $fields as $field ){ add_settings_field( $field['uid'], $field['label'], array( $this, 'field_callback' ), 'smashing_fields', $field['section'], $field ); register_setting( 'smashing_fields', $field['uid'] ); } }

Donc, la première chose que nous avons ici est une variable appelée $fields qui contiendra tous les champs que nous voulons créer. À l'intérieur de ce tableau, nous avons un autre tableau qui contient les données spécifiques pour chaque champ. J'ai configuré les données pour qu'elles correspondent exactement à notre liste ci-dessus. Ensuite, je parcoure chaque champ (nous en ajouterons plus sous peu) dans le tableau, j'ajoute le champ et l'enregistre. À la fin de la fonction add_settings_field , j'ajoute également tout le tableau de données pour ce champ spécifique afin que nous puissions faire certaines choses dans la fonction de rappel. Jetons un coup d'œil à cette fonction de rappel ici :

 public function field_callback( $arguments ) { $value = get_option( $arguments['uid'] ); // Get the current value, if there is one if( ! $value ) { // If no value exists $value = $arguments['default']; // Set to our default } // Check which type of field we want switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; } // If there is help text if( $helper = $arguments['helper'] ){ printf( '<span class="helper"> %s</span>', $helper ); // Show it } // If there is supplemental text if( $supplimental = $arguments['supplemental'] ){ printf( '<p class="description">%s</p>', $supplimental ); // Show it } }

Dans l'exemple ci-dessus, nous faisons plusieurs choses. Nous définissons les valeurs par défaut pour les champs s'ils sont vides et ajoutons l'aide et le texte supplémentaire. Cependant, la partie la plus importante de notre code est l'instruction switch. Dans cette déclaration, nous allons décrire comment nos arguments seront traités en fonction du type de champ que nous voulons.

Par exemple, si nous avons un champ de texte, nous n'avons pas besoin d'avoir plusieurs options. Cependant, une liste déroulante <select> doit avoir des options pour fonctionner correctement. Puisque nous avons déjà configuré des types de texte, exécutons ce code et voyons ce que nous obtenons.

Notre champ rempli, y compris l'espace réservé
Notre champ rempli, y compris le texte de l'espace réservé. (Voir la grande version)

Lorsque vous chargez la page des paramètres de votre plugin, vous devriez voir le champ supérieur de cette image. Le bas est ce que vous verrez si vous supprimez le contenu du champ (c'est-à-dire l'espace réservé). Si je devais supprimer l' helper ou supplimental de notre tableau de champs, ils devraient disparaître sur la page des paramètres. Nous pouvons également modifier l'argument de section et déplacer le placement du champ dans les sections.

OK, nous avons donc des champs de texte ; que diriez-vous de certains types de champs plus complexes ? Jetons un autre coup d'œil à notre instruction switch et ajoutons l'option pour les zones de texte et les sélections simples :

 switch( $arguments['type'] ){ case 'text': // If it is a text field printf( '<input name="%1$s" type="%2$s" placeholder="%3$s" value="%4$s" />', $arguments['uid'], $arguments['type'], $arguments['placeholder'], $value ); break; case 'textarea': // If it is a textarea printf( '<textarea name="%1$s" placeholder="%2$s" rows="5" cols="50">%3$s</textarea>', $arguments['uid'], $arguments['placeholder'], $value ); break; case 'select': // If it is a select dropdown if( ! empty ( $arguments['options'] ) && is_array( $arguments['options'] ) ){ $options_markup = '; foreach( $arguments['options'] as $key => $label ){ $options_markup .= sprintf( '<option value="%s" %s>%s</option>', $key, selected( $value, $key, false ), $label ); } printf( '<select name="%1$s">%2$s</select>', $arguments['uid'], $options_markup ); } break; }

Dans le code ci-dessus, vous remarquerez plusieurs différences entre chacun des types de champs. Bien que les zones de texte soient fonctionnellement similaires aux champs de texte normaux, elles nécessitent un balisage différent. Les listes déroulantes sélectionnées sont un tout autre animal à cause des options. Nous devons parcourir les options et définir les valeurs, les états sélectionnés et les étiquettes. Notre balisage est donc radicalement différent.

Maintenant que nous avons mis à jour notre fonction de rappel, voyons comment les données du champ ont changé :

 $fields = array( array( 'uid' => 'our_first_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'text', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_second_field', 'label' => 'Awesome Date', 'section' => 'our_first_section', 'type' => 'textarea', 'options' => false, 'placeholder' => 'DD/MM/YYYY', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => '01/01/2015' ), array( 'uid' => 'our_third_field', 'label' => 'Awesome Select', 'section' => 'our_first_section', 'type' => 'select', 'options' => array( 'yes' => 'Yeppers', 'no' => 'No way dude!', 'maybe' => 'Meh, whatever.' ), 'placeholder' => 'Text goes here', 'helper' => 'Does this help?', 'supplemental' => 'I am underneath!', 'default' => 'maybe' ) );

Voici trois champs, chacun utilisant un type de champ différent dans notre plugin. Le premier que nous avons déjà parcouru. Le second est notre nouveau champ textarea . Nous pouvons passer les mêmes paramètres avec le tableau (à l'exception de l'UID), mais un simple changement de notre type et nous obtiendrons une textarea à la place. Le dernier champ de ce tableau est la liste déroulante de sélection. La principale mise à jour ici est l'ajout du tableau d'options. Nous ajoutons un tableau associatif simple avec la clé du tableau comme valeur d'option HTML, et l'étiquette. En utilisant ce tableau, voici à quoi ressemblent nos champs :

Notre page de paramètres une fois les champs remplis
Notre page de paramètres avec des champs. (Voir la grande version)

Presque fini!

Nous avons maintenant une page de paramètres de plugin fonctionnelle. Nous avons configuré les sections de la page, les options, tous les rappels et enregistré les champs. La seule chose qui reste est d'obtenir nos valeurs de réglage ailleurs. Croyez-le ou non, nous l'avons déjà fait. En haut de notre rappel de champ, vous pouvez voir que nous vérifions la valeur de la base de données :

 $value = get_option( $arguments['uid'] );

Nous pouvons utiliser le même code dans notre plugin (ou thème) et simplement passer l' uid dans la fonction. Donc, si je voulais obtenir la valeur de our_first_field , j'écrirais simplement :

 get_option('our_first_field')

Hé hop ! Nous avons notre super plugin et nos super paramètres ! Évidemment, nous n'avons configuré que quelques types de champs, mais j'en ai parcouru et ajouté d'autres dans le référentiel de code pour cette approche (en particulier les champs de texte, les mots de passe, les nombres, les zones de texte, les listes déroulantes de sélection, les sélections multiples, les boutons radio et les cases à cocher).

Approche 2 : Configurer un formulaire et un gestionnaire personnalisés

Dans le passé, cette approche était le seul moyen d'ajouter des pages de paramètres. Avant WordPress 2.7, les auteurs de plugins devaient créer leurs propres formulaires et gestionnaires personnalisés. Cela a évidemment conduit à beaucoup de bugs et d'incohérences entre les plugins. Bien que cette approche soit quelque peu obsolète, elle reste une option viable dans certains cas.

Avantages

  • Vous pouvez soumettre le formulaire à des gestionnaires personnalisés et distants
  • Vous pouvez contourner certaines des restrictions intégrées de l'API Settings

Les inconvénients

  • La compatibilité doit être maintenue par le développeur
  • Doit être nettoyé et validé manuellement

Quand devriez-vous utiliser cette approche ?

Utilisez cette approche lorsque vous devez absolument disposer d'un gestionnaire personnalisé ou d'une interface hautement personnalisée. Vous pouvez probablement vous en sortir avec l'approche 1 dans la plupart des cas, mais vous avez plus de flexibilité avec la validation et la gestion en utilisant cette méthode.

Commencer

Avant d'entrer dans les détails, nous devons proposer un scénario dans lequel nous utiliserions un gestionnaire personnalisé. Par souci de simplicité, créons un formulaire qui vérifiera un nom d'utilisateur et une adresse e-mail. Nous pourrions extraire les données d'une base de données ou même d'un serveur distant. Dans ce cas, je vais configurer un tableau avec des noms d'utilisateur et des adresses e-mail valides pour que nous puissions vérifier. Nous stockerons ensuite les valeurs de champ saisies par l'utilisateur et les stockerons dans la base de données.

Création du formulaire

Comme je l'ai mentionné précédemment, nous suivrons les mêmes étapes que nous avons suivies dans "Création de notre page de plugins et de paramètres". Pour cette approche, nous allons configurer nos champs à l'aide d'un balisage HTML statique. Nous ajouterons ce code au rappel de la fonction plugin_settings_page_content comme ceci :

 public function plugin_settings_page_content() { ?> <div class="wrap"> <h2>My Awesome Settings Page</h2> <form method="POST"> <table class="form-table"> <tbody> <tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="" class="regular-text" /></td> </tr> </tbody> </table> <p class="submit"> <input type="submit" name="submit" class="button button-primary" value="Check My Info!"> </p> </form> </div> <?php }

Vous pouvez voir ci-dessus que nous ajoutons simplement du code HTML statique pour nos champs. Nous dupliquons le balisage des pages de paramètres de base de WordPress. Nous omettons également l'action de formulaire afin qu'elle soumette le formulaire à la page actuelle, par opposition au gestionnaire options.php par défaut.

Avant d'écrire notre gestionnaire personnalisé, ajoutons quelques fonctionnalités de sécurité rapides. La première chose que nous devrions faire est de mettre un nonce dans notre formulaire. Les nonces protégeront contre les tentatives de falsification de requêtes intersites, ce qui est similaire à l'usurpation d'utilisateur ou aux attaques de relecture. Mettons le nonce dans notre HTML :

 <form method="POST"> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

Le wp_nonce_field ajoutera quelques champs cachés à notre formulaire ; le nonce et le référent. Nous reviendrons sur le nonce lorsque nous parcourrons le code du gestionnaire.

Ensuite, nous devons ajouter un champ pour détecter quand le formulaire a été mis à jour. Nous pouvons le faire en ajoutant simplement un champ caché en haut de notre formulaire :

 <form method="POST"> <input type="hidden" name="updated" value="true" /> <?php wp_nonce_field( 'awesome_update', 'awesome_form' ); ?> <table class="form-table">

Nous pouvons maintenant mettre un extrait de code en haut de notre page pour détecter quand notre formulaire est soumis et nous envoyer à notre gestionnaire personnalisé :

 public function plugin_settings_page_content() { if( $_POST['updated'] === 'true' ){ $this->handle_form(); } ?> <div class="wrap"> <h2>My Awesome Settings Page</h2>

Ici, nous vérifions simplement si le champ caché updated à jour a été soumis et, si c'est le cas, nous appelons une méthode dans notre plugin appelée handle_form . C'est là que nous pouvons commencer à écrire notre gestionnaire personnalisé.

Création du gestionnaire

Il y a quelques choses que nous devons vérifier dans le gestionnaire avant de gérer réellement les données du formulaire. Nous devons d'abord vérifier si notre nonce existe et est valide :

 public function handle_form() { if( ! isset( $_POST['awesome_form'] ) || ! wp_verify_nonce( $_POST['awesome_form'], 'awesome_update' ) ){ ?> <div class="error"> <p>Sorry, your nonce was not correct. Please try again.</p> </div> <?php exit; } else { // Handle our form data } }

Le code ci-dessus vérifie que le nonce est correct. S'il n'est pas valide, nous envoyons à l'utilisateur un message expliquant pourquoi le formulaire n'a pas été mis à jour. Si le nonce existe et est correct, nous pouvons gérer notre formulaire. Écrivons maintenant le code de notre gestionnaire de formulaire (ce code remplacera le commentaire dans l'extrait ci-dessus) :

 $valid_usernames = array( 'admin', 'matthew' ); $valid_emails = array( '[email protected]', '[email protected]' ); $username = sanitize_text_field( $_POST['username'] ); $email = sanitize_email( $_POST['email'] ); if( in_array( $username, $valid_usernames ) && in_array( $email, $valid_emails ) ){ update_option( 'awesome_username', $username ); update_option( 'awesome_email', $email );?> <div class="updated"> <p>Your fields were saved!</p> </div> <?php } else { ?> <div class="error"> <p>Your username or email were invalid.</p> </div> <?php }

Passons en revue le code dans cette section. Les deux premières lignes sont les tableaux de noms d'utilisateur/e-mails valides que nous allons vérifier. Ces valeurs de tableau peuvent être remplies de n'importe où.

Les deux lignes suivantes sont les valeurs que notre utilisateur a saisies dans le formulaire. Nous utilisons les fonctions de désinfection intégrées que WordPress nous offre. Cette étape est importante pour éviter plusieurs vulnérabilités avec les formulaires Web. Ensuite, nous vérifions si les valeurs fournies par les utilisateurs sont dans notre tableau de valeurs acceptables. Si tel est le cas, mettez à jour les options de formulaire dans la base de données. Cette étape pourrait également être remplacée par un mécanisme de stockage personnalisé. Nous donnons également à l'utilisateur un message indiquant que ses champs ont été enregistrés. Si l'entrée de l'utilisateur est invalide, nous le lui disons.

La dernière chose que nous devons faire est d'afficher les champs stockés dans le formulaire après leur saisie. Nous ferons cela de la même manière que nous récupérerions ces champs ailleurs dans le plugin : avec la fonction get_option . Voici les champs après avoir ajouté le code correct :

 <tr> <th><label for="username">Username</label></th> <td><input name="username" type="text" value="<?php echo get_option('awesome_username'); ?>" class="regular-text" /></td> </tr> <tr> <th><label for="email">Email Address</label></th> <td><input name="email" type="text" value="<?php echo get_option('awesome_email'); ?>" class="regular-text" /></td> </tr>

Nous sommes maintenant prêts à tester notre formulaire. Essayez de saisir le nom d'utilisateur admin et l'adresse e-mail [email protected] . Vous devriez obtenir ce qui suit sur votre formulaire :

Les champs enregistrés après avoir saisi les valeurs correctes
Les champs enregistrés après avoir saisi les valeurs correctes. (Voir la grande version)

Si vous essayez de définir l'un des champs sur une valeur non valide, vous devriez recevoir un message d'erreur et les champs ne devraient pas être mis à jour à cause de notre gestionnaire personnalisé.

C'est tout pour notre deuxième approche ! Vous avez maintenant configuré un formulaire personnalisé et un gestionnaire pour gérer les champs de votre plug-in. Le code complet de cette approche se trouve dans le référentiel de cet article. Passons maintenant à notre approche finale.

Approche 3 : Intégrer ACF (Advanced Custom Fields) dans votre plugin

Si vous n'avez pas encore utilisé ACF d'Elliot Condon, laissez-moi vous présenter. ACF est un merveilleux gestionnaire de terrain pour WordPress. L'une des meilleures choses à ce sujet est l'interface de configuration sur le terrain. Il est assez facile de faire tourner des champs pour un certain nombre de pages différentes dans WordPress (telles que des articles, des pages, des utilisateurs, des taxonomies, même leurs propres pages d'options intégrées). Vous pensez peut-être "Je ne peux pas intégrer le plugin de quelqu'un d'autre dans le mien - c'est louche !" mais M. Condon comprend le sort de ses collègues développeurs et a prévu cela dans son plugin. Vous pouvez consulter sa documentation sur ce sujet, mais je vais en reprendre une partie ici. Passons en revue les règles.

  1. Premièrement, si vous distribuez un plugin gratuit, vous devez utiliser la version gratuite d'ACF. C'est pour que les gens ne puissent pas obtenir la version PRO de votre plugin gratuit - ce ne serait pas cool. Vous pouvez utiliser la version PRO dans les plugins et thèmes premium sans problème, assurez-vous simplement d'acheter la licence développeur.
  2. Deuxièmement, ne modifiez pas les informations de copyright d'ACF. Donnez du crédit à l'homme !
  3. Enfin, ne distribuez pas la clé de licence avec votre plugin.

Maintenant, les avantages et les inconvénients de cette approche :

Avantages

  • Très facile à intégrer dans les thèmes et plugins
  • Vous pouvez profiter des champs avancés qui font partie d'ACF
  • Les mises à jour de code et de sécurité sont gérées par l'équipe ACF
  • ACF a d'excellents addons et un support si vous êtes bloqué
  • La configuration de vos champs est super simple grâce à l'interface utilisateur de configuration des champs

Les inconvénients

  • Accès limité au balisage
  • Crée une dépendance pour votre plugin ou thème
  • Pour maintenir ACF à jour, vous devez le maintenir à jour dans vos fichiers de plugin/thème (plus d'informations ci-dessous)

Quand devriez-vous utiliser cette approche ?

Lorsque vous souhaitez créer une interface de paramètres avancés très rapidement et que vous n'avez pas besoin de personnaliser l'apparence.

Commencer

For this approach I will show you how to set up the options page for the free version of ACF. To view a guide on setting up the PRO version check out the ACF documentation. To get started we will be adding ACF to our plugin directory. First, download the latest version of ACF and unzip its contents. In your plugin directory create a (Voir la grande version)

Again, we will follow the steps we did in “Creating Our Plugin And Settings Page”. Before we get into that, though, we should include ACF in our plugin.

Include ACF In Your Plugin

It's actually pretty easy to include ACF in your plugin – there are only three steps. First we have to include the main ACF file with PHP. Add the following code to the bottom of our constructor function:

 include_once( plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/acf.php' );

If you refresh the admin you should see a new menu item titled Custom Fields . Before we go into that page and start setting up our fields we need to update a couple of paths in ACF. We need to tell ACF to look for its front-end assets and file includes in our plugin directory instead of its normal place. Add these two hooks to your constructor:

 add_filter( 'acf/settings/path', array( $this, 'update_acf_settings_path' ) ); add_filter( 'acf/settings/dir', array( $this, 'update_acf_settings_dir' ) );

And the callbacks for those hooks:

 public function update_acf_settings_path( $path ) { $path = plugin_dir_path( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $path; } public function update_acf_settings_dir( $dir ) { $dir = plugin_dir_url( __FILE__ ) . 'vendor/advanced-custom-fields/'; return $dir; }

The first callback updates the include paths for the PHP files within the ACF plugin. The second updates the URIs for the ACF assets. Now we can set up our fields.

Configuring Your Fields

Now comes the fun part: the ACF field configuration UI. Add a title and any fields you'd like in your form. There is a great walkthrough of what everything on this page does in the ACF documentation. Here's how I have set up mine:

ACF fields configured
My ACF fields in the configuration UI. (Voir la grande version)

Once you are ready hit the Publish button on the right and your fields will be saved. Now we have to get the fields we set up into our plugin. Right now they only exist in the database. On the left-hand navigation, click the Tools item. On the new page, select the field group we just created and hit Generate Export Code . This will create a chunk of PHP code that we can now include in our plugin.

To add the options, we need to add a method call to our constructor. Add this line to the end of your constructor after our ACF include:

 $this->setup_options();

Then we can create the method that will wrap our options:

 public function setup_options() { if( function_exists( 'register_field_group' ) ) { register_field_group(array ( 'id' => 'acf_awesome-options', 'title' => 'Awesome Options', 'fields' => array ( array ( 'key' => 'field_562dc35316a0f', 'label' => 'Awesome Name', 'name' => 'awesome_name', 'type' => 'text', 'default_value' => ', 'placeholder' => ', 'prepend' => ', 'append' => ', 'formatting' => 'html', 'maxlength' => ', ), array ( 'key' => 'field_562dc9affedd6', 'label' => 'Awesome Date', 'name' => 'awesome_date', 'type' => 'date_picker', 'date_format' => 'yymmdd', 'display_format' => 'dd/mm/yy', 'first_day' => 1, ), array ( 'key' => 'field_562dc9bffedd7', 'label' => 'Awesome WYSIWYG', 'name' => 'awesome_wysiwyg', 'type' => 'wysiwyg', 'default_value' => ', 'toolbar' => 'full', 'media_upload' => 'yes', ), ), 'location' => array ( array ( array ( 'param' => 'options_page', 'operator' => '==', 'value' => 'smashing_fields', ), ), ), 'menu_order' => 0, 'position' => 'normal', 'style' => 'default', 'label_placement' => 'top', 'instruction_placement' => 'label', 'hide_on_screen' => ', 'active' => 1, 'description' => ', )); } }

Now that we have our fields ready to go, we can add them to the settings page.

Modifying The Settings Page Code

To add the fields we just created to the page we will need to update our plugin_settings_page_content method.

Previously, we set up the form tag for our page. In this case we will let ACF do that part for us. Here is what our updated function should look like:

public function plugin_settings_page_content() { do_action('acf/input/admin_head'); // Add ACF admin head hooks do_action('acf/input/admin_enqueue_scripts'); // Add ACF scripts $options = array( 'id' => 'acf-form', 'post_id' => 'options', 'new_post' => false, 'field_groups' => array( 'acf_awesome-options' ), 'return' => admin_url('admin.php?page=smashing_fields'), 'submit_value' => 'Update', ); acf_form( $options ); }

Les deux premières lignes de notre fonction ajoutent les scripts et les styles dont nous aurons besoin pour les champs de paramètres. Après cela, nous configurons les options de notre formulaire. Vous remarquerez peut-être que la valeur de l'argument field_groups correspond à l'ID de notre fonction register_field_group . Pour voir les autres paramètres de configuration, consultez la documentation acf_form . La dernière ligne de notre fonction va en fait rendre le formulaire.

Si vous essayez de charger la page des paramètres maintenant, vous pouvez voir que la page est en fait cassée. En effet, ACF a besoin de localiser quelques variables pour JavaScript. Pour ce faire, nous devons ajouter un autre crochet à notre constructeur :

 add_action( 'admin_init', array( $this, 'add_acf_variables' ) );

Maintenant, nous devons configurer le rappel :

 public function add_acf_variables() { acf_form_head(); }

Vous pouvez essayer d'ajouter du contenu et de sauvegarder et cela devrait fonctionner comme nos deux autres approches. Voici à quoi notre page devrait ressembler :

Formulaire ACF terminé
Notre formulaire ACF rempli. (Voir la grande version)

Il y a juste quelques éléments de nettoyage dont nous avons besoin :

  • Vous voudrez peut-être masquer le fait que vous utilisez ACF pour votre plugin. Si tel est le cas, vous devez masquer l'élément de menu Champs personnalisés . Vous pouvez le faire en ajoutant cet extrait à votre fonction constructeur :

     add_filter( 'acf/settings/show_admin', '__return_false' );
  • Nous devrions supprimer la version de la base de données de notre groupe de champs. Allez simplement dans la section des champs personnalisés et appuyez sur le bouton de la corbeille. Cette étape est facultative car elle n'affectera que l'environnement dans lequel vous avez construit le plugin, mais elle pourrait introduire des problèmes si vous testez votre plugin sur le même environnement.

Utilisation des champs ACF dans votre plugin

Pour obtenir les champs ACF que vous avez créés, il vous suffit d'utiliser la fonction par défaut ACF get_field . La première option doit être l'identifiant unique du champ et le second argument doit être 'option' . Voici comment nous obtiendrions le champ Awesome Date :

 get_field( 'awesome_date', 'option' )

Et c'est tout. Vous avez maintenant configuré un plugin avec les paramètres ACF ! Vous pouvez afficher le code de cette approche dans le référentiel.

Conclusion

Alors voilà : trois façons de rendre vos plugins configurables. J'aimerais entendre parler des plugins que vous pouvez créer en utilisant ces méthodes. Encore une fois, j'ai mis en place un référentiel qui héberge le code de chacune de ces approches. N'hésitez pas à les bifurquer et à les personnaliser pour répondre à vos propres besoins.

En ce qui concerne mes préférences personnelles pour ces approches, j'ai tendance à pencher vers l'approche 1. Je préfère conserver le moins de dépendances possible dans mes plugins et vous pouvez personnaliser le balisage pour thématiser la page des paramètres pour les projets personnalisés. Pour les prototypes rapides ou les projets où j'ai besoin de configurer des champs très avancés, j'utiliserai ACF - mais cela ajoute un niveau de complexité à la gestion des mises à jour des plugins.

Il convient également de mentionner la proposition d'une API Fields par Scott Clark. Bien qu'il s'agisse encore d'un travail en cours, l'API permettrait essentiellement aux développeurs de plugins et de thèmes d'utiliser la même interface que l'API Customizer pour créer des champs de paramètres dans d'autres zones du panneau d'administration.

Alternatives ACF

Comme indiqué dans les commentaires ci-dessous, et pour donner aux développeurs d'autres options similaires à l'approche ACF, vous pouvez consulter certaines alternatives qui peuvent offrir différentes fonctionnalités. Si vous en avez d'autres, veuillez les soumettre dans les commentaires ci-dessous ! Les voici sans ordre particulier :

  • CMB2 par WebDevStudios
  • Meta Box par Tran Ngoc Tuan Anh (Rilwis)