Se familiariser avec la classe WordPress Walker

Publié: 2020-11-27

Si vous n'êtes pas familier avec la classe Walker, préparez-vous à être étonné de voir à quel point elle peut être utile pour votre travail. La classe WordPress Walker a été implémentée dans WordPress 2.1 pour fournir aux développeurs un moyen de parcourir des structures de données arborescentes dans le but de rendre HTML. Dans cet article, nous étudierons le fonctionnement du paramètre walker et comment personnaliser les sorties dans les menus, les catégories et les commentaires.

Allons-y!

Aperçu de la classe Walker

Dans WordPress, nous voyons fréquemment des objets qui ont une structure hiérarchique tels que des menus de navigation, des listes de catégories ou des listes de commentaires

Comme vous le savez peut-être déjà, dans le cas d'une structure arborescente, certains éléments sont des parents et d'autres leurs enfants. "Post Subcategory 1" est un enfant de "Post Category 1", une réponse à un commentaire est un commentaire enfant du commentaire lui-même, et "Service 1" est un élément de menu enfant de l'élément "Services".

Le Walker est nommé en tant que tel car il "parcourt" simplement chaque objet ou tableau associatif et exécute une fonction à chaque nœud. Ce que nous aimerions réaliser avec cela, c'est la possibilité de répertorier les liens "de niveau supérieur", avec leurs éléments "enfants" de différentes manières en fonction de nos besoins spécifiques.

En d'autres termes, WordPress vous donne une structure standard <ul> <li> et vous pouvez personnaliser ses arguments, mais, en étendant le Walker, vous pouvez personnaliser la structure elle-même en modifiant son contenu HTML.

Le fichier principal lié à la classe Walker est wp-includes/class-wp-walker.php et il régit tous les types de données arborescentes que nous avons précédemment répertoriées.

Comme il s'agit d'une classe PHP abstraite, pour générer du HTML, elle doit être étendue par le développeur qui définira une version personnalisée de ses propriétés et méthodes. Étudions donc les classes enfants dans le fichier class-wp-walker.php une par une.

Cours enfants

Le $tree_type est une variable facultative qui vient dans un type ou un tableau de types et définit ce que la classe gère.

 public $tree_type = array( 'post_type', 'taxonomy', 'custom' );

Le $db_fields est une variable obligatoire et définit les champs de base de données à utiliser. Cette propriété est un tableau avec deux clés : 'parent' et 'id' dont les valeurs sont les noms des propriétés d'objet qui contiennent respectivement l'identifiant parent et l'identifiant de l'élément.

 public $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id', );

La propriété $max_pages est également optionnelle et son rôle est de spécifier le nombre maximum de pages parcourues par le parcours paginé.

 public $max_pages = 1;

Le $has_children est en fait explicite et a une valeur vraie ou fausse selon que l'élément actuel a des enfants.

 public $has_children;

La méthode start_lvl est exécutée à la racine d'un nouvel objet arborescent et prend les arguments $output, $depth et $args.

 public function start_lvl( &$output, $depth = 0, $args = array() ) {}

L'argument $output ajoute du contenu supplémentaire, $depth spécifie la profondeur de l'élément et $args est un tableau d'arguments supplémentaires.

La méthode end_lvl ferme toute balise précédemment ouverte par la méthode start_lvl.

 public function end_lvl( &$output, $depth = 0, $args = array() ) {}

La start_el (Start Element) est utilisée pour afficher la balise HTML d'ouverture de l'élément courant. Dans le cas d'un menu, par exemple, il s'agit généralement d'une balise <li>.

 public function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {}

La fonction end_el est appelée après que le Walker passe un élément avec tous ses enfants et renvoie une balise de fermeture.

 public function end_el( &$output, $object, $depth = 0, $args = array() ) {}

Le display_element affiche en fait les éléments de l'objet arbre. Il appelle start_el , start_lvl , display_element , end_lvl , end_el dans cet ordre. Voyons maintenant ses arguments.

  • $element : l'élément courant
  • $children_elements : tous les éléments enfants de l'objet arbre
  • $max_depth : la limite de profondeur maximale que nous pouvons explorer
  • $depth : Le niveau auquel nous sommes actuellement
  • $args : arguments optionnels supplémentaires
  • $output : La sortie HTML actuelle.

Nous allons maintenant démontrer un exemple pour chaque type de données en utilisant une installation WordPress avec le thème Twenty Twenty activé.

Personnalisation d'une structure de menu

La fonction wp_nav_menu() que WordPress utilise pour afficher les menus est incluse dans le fichier wp-includes/nav-menu-template.php . Dans ce fichier, WordPress appelle également la classe Walker_Nav_Menu autour de la ligne 605.

 function walk_nav_menu_tree( $items, $depth, $r ) { $walker = ( empty( $r->walker ) ) ? new Walker_Nav_Menu : $r->walker; return $walker->walk( $items, $depth, $r ); }

La classe Walker_Nav_Menu est définie dans le fichier wp-includes/class-walker-nav-menu.php et c'est essentiellement tout le contenu du fichier.

Afin d'afficher la sortie du menu, le code WordPress utilise les propriétés et les méthodes de la classe Walker_Nav_Menu décrites dans ce fichier.

Par exemple, corrigeons un problème bien connu auquel de nombreux développeurs sont confrontés, qui consiste à modifier l'élément des éléments de menu parent avec un lien personnalisé vide ('#') afin d'empêcher les visiteurs de cliquer dessus.

Pour nous permettre de comparer nos résultats, nous allons d'abord créer un clone du menu principal en ajoutant simplement le code ci-dessous dans le header.php juste après le début de l'élément <header> .

 <header class="header-footer-group" role="banner"> <?php wp_nav_menu( array( 'menu_class' => 'primary-menu reset-list-style' ) ); ?>

Ce que nous avons réellement fait ici a été de régénérer le menu principal et d'hériter de sa fonctionnalité de liste déroulante et de son CSS en ajoutant également ses classes primary-menu reset-list-style au nouveau menu.

Maintenant, dans notre fichier functions.php , nous allons créer une classe qui étend la classe Walker_Nav_Menu. Puisque nous voulons changer le type d'élément, nous allons remplacer la méthode start_el .

 if ( !class_exists('My_Custom_Nav_Walker') ) { class My_Custom_Nav_Walker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth=0, $args=[], $id=0) { $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>'; } } } }

Nous avons donc enveloppé chaque élément normalement avec une balise <li> puis, avec l'utilisation de l'instruction if, ajouté une étendue lorsqu'un lien est "#" et une balise <a> pour le reste.

Pour appliquer cela à notre menu, revenons au code de menu que nous avons ajouté précédemment et spécifions le paramètre walker :

 wp_nav_menu( array( 'walker' => new My_Custom_Nav_Walker, 'menu_class' => 'primary-menu reset-list-style' ) );

Maintenant, le résultat devrait ressembler à ceci :

Si vous survolez maintenant les "Services" dans l'élément de menu, aucun curseur en forme de main n'apparaîtra et cet élément de menu n'est pas non plus cliquable. Le sous-menu déroulant sera toujours affiché correctement cependant.

Personnalisation des catégories

Allez d'abord dans la zone d'administration et créez des catégories et sous-catégories de publications afin d'avoir une arborescence de catégories pour la démonstration.

Après cela, nous allons générer une liste de catégories en ajoutant ce code quelque part dans le header.php . Vous pouvez le mettre après le début de l'élément d'en-tête comme précédemment.

 <header class="header-footer-group" role="banner"> <?php wp_list_categories( array('hide_empty' => FALSE) ); ?>

La fonction est une fonction WordPress intégrée qui génère une sortie HTML d'une arborescence de catégories. Par défaut, il affiche uniquement les catégories qui contiennent des messages, c'est pourquoi nous avons utilisé l'option hide_empty pour afficher également les catégories vides et voir toute la hiérarchie aux fins de cet exemple.

Comme précédemment, nous pouvons créer une classe personnalisée dans functions.php pour étendre la classe Walker_Category par défaut décrite dans le fichier wp-includes/class-walker-category.php et appliquer nos modifications. Par exemple, nous ajouterons quelques icônes avant les noms de catégories en ajoutant ce code :

 if ( !class_exists('My_Category_tree_Walker') ) { class My_Category_tree_Walker extends Walker_Category { function start_el(&$output, $item, $depth=0, $args=array(),$current_object_id = 0) { $output.= '<li><a href="'.home_url('category/'.$item->slug).'"> <img src="http://path/to/mages/'.($item->slug).'.jpg"> '.esc_attr($item->name); } } }

Pour que cela fonctionne, vous devez bien sûr préparer des images appropriées et les enregistrer dans le dossier défini. Ces images devraient suivre un format de nom spécifique qui, dans cet exemple, serait "post-category-1", "post-subcategory-1", "post-category-3.jpg", etc.

Personnalisation des commentaires

La mise à jour du menu et de la liste des catégories est de loin la raison la plus courante pour laquelle vous pouvez personnaliser une classe Walker, mais vous devez parfois implémenter la même technique pour les commentaires. Si, par exemple, vous souhaitez modifier les méta-informations à côté de l'image Gravatar dans la section des commentaires, nous pouvons facilement le faire en étendant la classe Walker_Comment trouvée dans le fichier wp-includes/class-walker-comment.php.

Dans le fichier functions.php ajouter ce code

 if ( !class_exists('My_Comment_Walker') ) { class My_Comment_Walker extends Walker_Comment { protected function html5_comment( $comment, $depth, $args ) { $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> <<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>> <article class="comment-body"> <footer class="comment-meta"> <div class="comment-author vcard"> <?php if ( 0 != $args['avatar_size'] ) echo get_avatar( $comment, $args['avatar_size'] ); ?> <?php printf( __( '%s <span class="says">says:</span>' ), sprintf( '<span class="fn">%s</span>', get_comment_author_link( $comment ) ) ); ?> </div><!-- .comment-author --> <div class="comment-metadata"> <?php $user_id=$comment->user_id; ?> <p class="commenter-bio"><?php the_author_meta('description',$user_id); ?></p> <p class="commenter-url"><a href="<?php the_author_meta('user_url',$user_id); ?>" target="_blank"><?php the_author_meta('user_url',$user_id); ?></a></p> </div><!-- .comment-metadata --> <?php if ( '0' == $comment->comment_approved ) : ?> <p class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ); ?></p> <?php endif; ?> </footer><!-- .comment-meta --> <div class="comment-content"> <?php comment_text(); ?> </div><!-- .comment-content --> <?php comment_reply_link( array_merge( $args, array( 'add_below' => 'div-comment', 'depth' => $depth, 'max_depth' => $args['max_depth'], 'before' => '<div class="reply">', 'after' => '</div>' ) ) ); ?> </article><!-- .comment-body --> <?php } } }

Comme vous pouvez le remarquer en comparant le code about avec le contenu du Walker_Comment d'origine, le seul changement nécessaire était dans la méthode html5_comment qui génère essentiellement un commentaire au format HTML5.

Après cela, nous devons afficher la liste des commentaires en utilisant la fonction intégrée wp_list_comments avec les bons arguments pour afficher l'objet HTML en forme d'arborescence de commentaires.

 wp_list_comments( array( 'page' => 143, 'walker' => new My_Comment_Walker ));

Nous avons inséré le code dans la même ligne de header.php qu'auparavant et avons utilisé l'ID du message contenant les commentaires. Bien sûr, vous pouvez simplement remplacer le code lié au commentaire de votre modèle et ignorer l'option "page" afin qu'elle s'applique à toutes les sections de commentaires de vos articles.

Si vous actualisez l'interface de votre site Web maintenant, vous remarquerez les entrées d'informations supplémentaires (bio de l'auteur et URL de l'auteur) que nous avons ajoutées dans le code personnalisé ci-dessus.

Conclusion

J'espère que ce qui précède vous a donné un aperçu de l'utilisation de la classe WordPress Walker. Dans tous les exemples, nous avons appliqué les modifications directement aux fichiers du thème principal. Bien que cela convienne à des fins de démonstration, vous voudrez évidemment vous assurer que vous n'appliquez que des modifications à un thème enfant dans la pratique pour vous assurer que ces mises à jour ne sont pas écrasées lorsque WordPress ou le thème utilisé est mis à jour.