Ajout de champs aux éléments de menu WordPress – Plugin personnalisé

Publié: 2021-05-19

Dans un article précédent, nous avons examiné comment vous pouvez ajouter votre propre champ personnalisé aux éléments de menu à l'aide du crochet d'action wp_nav_menu_item_custom_fields qui a été introduit dans WordPress 5.4. Nous avons détaillé deux itinéraires pour y parvenir; en ajoutant du code personnalisé à functions.php ou en utilisant un plugin WordPress.

Dans cet article, nous allons recréer le même champ mais cette fois nous le ferons en créant notre propre plugin à partir de zéro.

Commençons.

Création de plugins

Nous n'entrerons pas dans les détails de base de la création d'un plugin WordPress car cela a été couvert dans notre article détaillé "Comment créer votre premier plugin WordPress". Un guide étape par étape'. Nous allons passer à la création de notre dossier de plugins sous le dossier wp-content/plugin/ . Ensuite, nous nommerons notre dossier de plug-in personnalisé "menu-item-field-creator" et à l'intérieur de celui-ci, nous créerons un fichier appelé menu-item-field-creator.php .

Après cela, nous ouvrirons ce fichier avec notre éditeur de texte préféré et ajouterons le code ci-dessous. Ce code a pour effet d'introduire le plugin dans le noyau de WordPress.

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */

Comme vous pouvez le noter, nous avons défini le nom et la description du plugin car nous voulons qu'ils soient affichés dans la zone du plugin d'administration. Pour les besoins de cet exemple, nous ne définirons aucun autre champ d'en-tête.

Une fois ces étapes terminées, dirigeons-nous vers notre section Plugins dans la zone d'administration et vérifions si le plugin est correctement affiché.

Ensuite, nous allons insérer notre premier code fonctionnel qui établira notre classe principale et quelques fonctions.

La manière simple

Le moyen le plus simple de faire fonctionner ce plugin est d'insérer le code que nous avons écrit dans notre article précédent dans le fichier PHP principal du plugin afin que le contenu final ressemble à ceci :

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ /** * Add the field. */ function pr_menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } add_action( 'wp_nav_menu_item_custom_fields', 'pr_menu_item_sub', 10, 2 ); /** * Save input. */ function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } add_action( 'wp_update_nav_menu_item', 'save_menu_item_sub', 10, 2 ); /** * Show the Menu Field Value. */ function show_menu_item_sub( $title, $item ) { if ( is_object( $item ) && isset( $item->ID ) ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); if ( ! empty( $menu_item_sub ) ) { $title .= '<p class="menu-item-sub">' . $menu_item_sub . '</p>'; } } return $title; } add_filter( 'nav_menu_item_title', 'show_menu_item_sub', 10, 2 );

À ce stade, si vous activez le plugin, vous devriez trouver que cela fonctionne très bien. Il existe cependant un moyen d'obtenir les mêmes résultats en utilisant un style de codage différent.

Utilisation de la programmation orientée objet

Pour obtenir les mêmes résultats dans une approche plus orientée objet, comme nous l'avons décrit dans notre article connexe, veuillez suivre les instructions ci-dessous.

Pour commencer, videz le contenu du fichier PHP principal de votre plugin, à l'exception du commentaire d'en-tête et insérez ces lignes :

 class MyCP_Menu_Item_Field_Creator { } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator();

Ce que nous avons fait avec ce code jusqu'à présent est de définir la classe wrapper MyCP_Menu_Item_Field_Creator qui contiendra l'ensemble des fonctionnalités. Enfin, nous instancions un objet.

Il est très important de se rappeler que le nom de la classe principale que vous définissez sera disponible dans le monde entier et que vous devez donc vous assurer qu'il est unique et qu'il n'y a aucune chance qu'un autre plugin ou thème utilise le même nom. C'est pourquoi il est recommandé d'utiliser un préfixe personnalisé tel que MyCP_ que nous avons utilisé ci-dessus.

À l'intérieur de la classe, nous allons maintenant ajouter certaines fonctionnalités. Le contenu final du fichier PHP principal de notre plugin ressemblera à ceci :

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_action( 'nav_menu_item_title', array( $this, 'show_menu_item_sub' ), 10, 2 ); } public function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } public function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } public function show_menu_item_sub( $title, $item ) { if ( is_object( $item ) && isset( $item->ID ) ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); if ( ! empty( $menu_item_sub ) ) { $title .= '<p class="menu-item-sub">' . $menu_item_sub . '</p>'; } } return $title; } } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator();

Nous avons supprimé les préfixes des noms des méthodes car nous avons maintenant un préfixe de classe à la place.

Dans la fonction __construct , nous avons défini les crochets que nous avons utilisés ainsi que leurs fonctions de rappel qui s'exécuteront. Ensuite, nous avons introduit la fonction de rappel menu_item_sub qui affichera le champ de saisie où l'utilisateur administrateur peut remplir le sous-titre de l'élément.

Après cela, nous enregistrons l'entrée avec la méthode save_menu_item_sub et enfin, avec le rappel show_menu_item_sub , nous affichons les valeurs, si disponibles, dans le menu frontal.

Agrandir le déambulateur

Dans l'exemple ci-dessus, nous avons inclus le champ de menu personnalisé dans le titre de l'élément de menu, sans modifier la sortie HTML des données de l'arborescence du menu. Mais que se passe-t-il si nous voulons ajouter le champ de sous-titre en tant qu'élément HTML séparé, tel qu'un élément <div> en dehors du lien de l'élément de titre ?

C'est là que nous devons travailler à nouveau avec la classe Walker. Comme nous l'avons vu dans notre article "Se familiariser avec la classe WordPress Walker", en étendant le Walker, vous pouvez personnaliser la structure d'une donnée arborescente. Dans ce cas, ce sera le menu.

Cela signifie bien sûr que nous n'avons qu'à modifier notre code lié à l'affichage frontal de notre champ personnalisé. Alors allons-y et remplaçons tout le code par celui-ci :

 <?php /* Plugin Name: Menu Item Field Creator Description: My custom plugin to create menu item fields */ class MyCP_Menu_Item_Field_Creator { public function __construct() { add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'menu_item_sub' ), 10, 2 ); add_action( 'wp_update_nav_menu_item', array( $this, 'save_menu_item_sub' ), 10, 2 ); add_filter( 'wp_nav_menu_args', array( $this, 'menu_item_sub_custom_walker' ) ); } public function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php } public function save_menu_item_sub( $menu_id, $menu_item_db_id ) { if ( isset( $_POST['menu_item_sub'][ $menu_item_db_id ] ) ) { $sanitized_data = sanitize_text_field( $_POST['menu_item_sub'][ $menu_item_db_id ] ); update_post_meta( $menu_item_db_id, '_menu_item_sub', $sanitized_data ); } else { delete_post_meta( $menu_item_db_id, '_menu_item_sub' ); } } public function menu_item_sub_custom_walker( $args ) { if ( class_exists( 'My_Custom_Nav_Walker' ) ) { $args['walker'] = new My_Custom_Nav_Walker(); } else { echo 'DOES NOT EXIST'; } return $args; } } $mycp_menu_item_field_creator = new MyCP_Menu_Item_Field_Creator(); if ( ! class_exists( 'My_Custom_Nav_Walker' ) ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { public function start_el( &$output, $item, $depth=0, $args=[], $id=0 ) { $menu_item_sub = get_post_meta( $item->ID, '_menu_item_sub', true ); $output .= '<li class="' . implode( ' ', $item->classes ) . '">'; if ( $item->url && $item->url != '#' ) { $output .= '<a href="' . $item->url . '">'; } else { $output .= '<span>'; } $output .= $item->title; if ( $item->url && $item->url != '#' ) { $output .= '</a>'; } else { $output .= '</span>'; } if ( ! empty( $menu_item_sub ) ) { $output .= '<div class="menu-item-sub">' . $menu_item_sub . '</div>'; } } } }

Vous avez peut-être remarqué que nous avons supprimé la méthode show_menu_item_sub et travaillé différemment avec la structure des éléments de menu frontaux. Nous avons introduit notre classe Walker personnalisée My_Custom_Nav_Walker en dehors de notre classe principale et via notre méthode menu_item_sub_custom_walker nous avons changé la valeur par défaut de l'argument 'walker' en My_Custom_Nav_Walker . De cette façon, la sortie HTML du menu que nous avons fournie dans notre Walker personnalisé s'appliquera à notre frontal.

Vérifions les résultats.

Comme nous pouvons le voir, notre description est cette fois placée en dehors du href du lien de l'élément de menu comme nous l'avions prévu.

Aller plus loin

Avant de conclure, il convient de mentionner que nous avons délibérément utilisé l'exemple "Sous-titre" car il est simple à faire et à comprendre.

Si vous voulez vous pousser, nous vous suggérons de créer vos propres scénarios à expérimenter. Essayez par exemple de créer une sortie différente qui permettra à l'utilisateur Admin de définir quel rôle d'utilisateur est autorisé à afficher l'élément de menu.

Comme indice de départ, nous vous fournirons la sortie. Remplacer la méthode de sortie actuelle (illustrée ci-dessous)

 function menu_item_sub( $item_id, $item ) { $menu_item_sub = get_post_meta( $item_id, '_menu_item_sub', true ); ?> <div> <span class="subtitle"><?php _e( 'Subtitle', 'menu-item-sub' ); ?></span><br /> <input type="hidden" class="nav-menu-id" value="<?php echo $item_id; ?>" /> <div class="logged-input-holder"> <input type="text" name="menu_item_sub[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $menu_item_sub ); ?>" /> </div> </div> <?php }

avec celui-ci:

 function PREFIX_Menu_Item_Roles() { global $wp_roles; $display_roles = apply_filters( 'nav_menu_roles', $wp_roles->role_names ); if ( ! $display_roles ) return; ?> <p class="field-nav_menu_logged_in_out nav_menu_logged_in_out nav_menu_logged_in_out-thin"> <fieldset> <legend><?php _e( 'Display Mode', 'nav-menu-roles' ); ?></legend> <label for="edit-menu-item-role_logged_in"> <input type="radio" class="edit-menu-item-logged_in_out" value="in" name="menu-item-role_logged_in" /> <?php _e( 'Logged In Users', 'nav-menu-roles' ); ?><br/> </label> <label for="edit-menu-item-role_logged_out"> <input type="radio" class="edit-menu-item-logged_in_out" value="out" name="menu-item-role_logged_out" /> <?php _e( 'Logged Out Users', 'nav-menu-roles' ); ?><br/> </label> <label for="edit-menu-item-role_everyone"> <input type="radio" class="edit-menu-item-logged_in_out" value="" name="menu-item-role_everyone" /> <?php _e( 'Everyone', 'nav-menu-roles' ); ?><br/> </label> </fieldset> </p> <?php }

Essayez maintenant de créer une méthode qui enregistre les modifications avec une autre qui affiche la valeur actuelle/enregistrée en utilisant les crochets corrects.

Conclusion

Personnaliser un menu WordPress peut être frustrant tant que vous n'êtes pas au courant des outils à votre disposition pour le faire. J'espère que cet article vous a donné un aperçu de ce qu'il est possible de réaliser et des moyens de mettre en œuvre des tâches comme celle-ci.

Voir également

  • Ajout de champs personnalisés aux éléments de menu WordPress