Les éléments de menu, les pages et les taxonomies (hiérarchiques) sont tous des exemples de données avec une structure semblable à une arborescence: les termes peuvent avoir parents, enfants et frères et soeurs. Généralement, nous aimerions refléter cette structure dans le balisage HTML. Pour l'affichage d'un menu, par exemple, nous voulons que le code HTML soit constitué d'une liste de liens de "niveau supérieur", avec des listes imbriquées de leurs enfants, contenant elles-mêmes des listes imbriquées de leurs enfants, etc. Ce tutoriel vous guidera à travers un cours fourni par WordPress, ce qui rend la production de cette annotation extrêmement simple..
La classe walker est une classe abstraite conçue pour aider à parcourir et à afficher les éléments ayant une structure hiérarchique (ou arborescente). Ce n'est pas vraiment 'faire' (dans le sens de générer du HTML) n'importe quoi. Il trace simplement chaque branche de votre arbre: il doit être étendu par d'autres classes qui lui indiquent quoi faire pour chaque élément rencontré. WordPress fournit ses propres classes d'extension, telles que:
Walker_Nav_Menu
- pour afficher le HTML pour les menus de navigationWalker_Page
- pour afficher une liste de pagesWalker_Catégorie
- pour afficher une liste de termes de taxonomie.Chacune de ces classes étend la classe Walker en dictant simplement ce que la classe doit afficher à chaque élément et à chaque niveau de l’arbre. Afin de démystifier cette classe, nous allons examiner ses principales méthodes et quelques exemples d'utilisation. La classe elle-même peut être trouvée ici.
Marche
marcher ($ éléments, $ max_depth)
La classe walker est lancée avec la méthode walk et c'est cette méthode qui renvoie le code HTML une fois qu'il a été généré. Il accepte deux arguments:
$ max_depth
- définit combien de générations nous explorons$ args
. Ceci est ensuite passé à d'autres méthodes de la classeLa méthode de la marche sélectionne les éléments «de niveau supérieur» - ceux sans parents - et les place dans un tableau. Le reste, les enfants, sont placés dans un deuxième tableau où la clé est l'identifiant de son parent (c'est un tableau à deux dimensions, un parent pouvant avoir plusieurs enfants):
$ children_elements = array ('1' => array () // Tableau d'éléments correspondant aux enfants de 1, '4' => array () // Tableau d'éléments correspondant aux enfants de 4);
Il parcourt ensuite chacun des éléments parents et applique la méthode. display_element
.
Display_Element
display_element ($ element, & $ children_elements, $ max_depth, $ depth = 0, $ args, & $ output)
Comme le nom le suggère display_element
est responsable de l'affichage d'un élément dans notre arbre. En fait, il appelle plusieurs fonctions pour le faire. Ces fonctions sont délibérément laissées vides dans la classe Walker - et ce sont ces dernières qui sont modifiées dans les classes étendues, car elles déterminent le code HTML réel renvoyé. Ceux-ci inclus:
start_lvl
- une fonction pour retourner le code HTML pour le début d'un nouveau niveau. Dans le cas de listes, ce serait le début d’une nouvelle "sous-liste" et il incomberait donc de renvoyer le message.
étiquetteend_lvl
- appelé quand on a fini un niveau. Dans l'exemple du menu de navigation, cette fonction est chargée de terminer la sous-liste avec une balise de liste de fermeture.
start_el
- la fonction responsable d'afficher l'élément actuel sur lequel nous sommes. Dans le cas des menus, cela signifie que le
tag et le lien de l'article.end_el
- la fonction appelée après qu'un élément et tous ses enfants ont été affichés. Pour notre exemple de menu, cela signifie retourner une fermeture
Alors qu'est-ce que display_element
fait réellement? C'est en fait là que se déroule toute la magie de la classe Walker. Voyons d'abord quels arguments il est donné:
élément $
- c'est l'élément que nous sommes actuellement sur notre arbre$ enfants_elements
- un étalage de tout éléments enfants (pas seulement les enfants de l'élément mentionné ci-dessus). C'est le deuxième tableau formé dans le marche
méthode et les clés sont les identifiants du parent.$ max_depth
- jusqu'où nous sommes autorisés à explorer$ profondeur
- à quelle distance nous sommes actuellement$ args
- arguments optionnels (mentionnés précédemment)$ sortie
- Le HTML jusqu'à présent. Ceci est ajouté à mesure que nous explorons plus d'arbres. le display_element
méthode premiers appels start_el
qui est responsable de l'affichage de l'élément. Cela dépend exactement du contexte. Pour un menu déroulant, il peut être ou pour un menu de navigation, il peut
. Notez qu'il n'y a pas encore de balise de fermeture. Si cet élément a des enfants, nous devons d'abord les afficher pour qu'ils soient imbriqués dans cet élément…
Ensuite, il vérifie si l'élément actuel sur lequel nous nous trouvons a des enfants et si nous n'avons pas atteint la profondeur maximale. Si oui, nous explorons chacun des enfants à tour de rôle en appelant display_element
pour chacun d'eux (avec l'argument de profondeur incrémenté de un). De cette façon, le display_element
se appelle récursivement jusqu'à atteindre le fond.
Supposons que nous ayons atteint le "bas" (un élément sans enfant ou avec la profondeur maximale), alors il appelle end_el
qui ajoute la balise de fermeture. Là l'instance actuelle de display_element
se termine et nous revenons au parent qui applique display_element
au prochain enfant, jusqu'à ce que nous ayons traité chacun de ses enfants. Lorsque le parent n'a plus d'enfants, nous remontons dans l'arbre, et ainsi de suite jusqu'à ce que chaque branche soit explorée. Confus? C'est un diagramme qui, j'espère, clarifiera les choses:
L'utilisation de la classe Walker facilite l'affichage des données hiérarchiques personnalisées. Supposons que vous ayez un tableau d'objets avec 'étiquette
','parent_id
' et 'object_id
'propriétés que vous souhaitez afficher une liste. Ceci peut maintenant être facilement accompli avec une classe très simple:
Remarque: La classe d'extension est chargée de définir où trouver l'ID d'un élément et celui de son parent.
class Walker_Simple_Example étend Walker // Définit les propriétés de l'élément qui donne l'ID de l'élément actuel et son parent var $ db_fields = array ('parent' => 'parent_id', 'id' => 'object_id'); // Affiche le début d'un niveau. Par exemple '
Vous pouvez étendre les classes de promeneur pour modifier le contenu affiché, modifier le code HTML généré ou même empêcher l’affichage de certaines branches. Fonctions telles que:
wp_nav_menu
wp_list_pages
wp_list_categories
Fournissez une option pour spécifier votre propre classe Walker personnalisée - vous permettant de modifier leur apparence avec une relative facilité en spécifiant votre propre classe de marcheur personnalisée. Dans de nombreux cas, il est en fait plus facile d’étendre une extension walker appropriée que la classe Walker elle-même..
Supposons que vous souhaitiez avoir un (sous) menu secondaire lié à votre menu principal. Cela peut prendre la forme de liens qui se trouvent juste en dessous de votre menu principal ou dans une barre latérale qui montre uniquement les éléments de menu "descendants" de la "page de premier niveau" en cours. Par exemple, dans le diagramme ci-dessus, si nous sommes dans les sous-pages "Archive", "Auteur" ou "Actualités", nous aimerions afficher tous les liens ci-dessous "Archives". Puisque Walker_Nav_Menu
fait la plupart de ce que nous voulons, nous étendrons cette classe plutôt que la classe Walker. Cela nous épargne beaucoup d’efforts, puisque le Walker_Nav_Menu
ajoute les classes appropriées ('actuel
','ancêtre actuel
'etc) aux liens pertinents. Nous étendrons le Walker_Nav_Menu
classe walker pour modifier légèrement la logique et l'empêcher d'afficher des liens de niveau supérieur ou l'un des descendants des pages "non-root".
Tout d’abord, dans vos fichiers modèles, nous utiliserons le wp_nav_menu ()
fonctionner deux fois, en montrant le même emplacement du thème (Je l'appellerai 'primaire
'). Si vous n’avez pas encore de thème enregistré, vous devriez lire cet article. Quel que soit le thème que vous utilisez, vous devez enregistrer un menu à cet emplacement. Nous allons afficher ce menu deux fois. Tout d’abord, là où vous voulez que votre menu de premier niveau apparaisse:
wp_nav_menu (array ('theme_location' => 'primaire', 'profondeur' => 1));
Ensuite, avec un lecteur personnalisé, pour afficher uniquement les pages enfants (pertinentes)..
wp_nav_menu (array ('theme_location' => 'primaire', 'walker' => nouveau SH_Child_Only_Walker (), 'profondeur' => 0));
Tout d'abord, nous ne voulons pas afficher les parents de haut niveau. Rappelons que la fonction responsable de l'ouverture tag et le lien est
start_el
et la fonction responsable de la fermeture la balise est
end_el
. Nous vérifions simplement si nous sommes au niveau des parents. Si nous le faisons, nous ne faisons rien. Sinon, nous continuons 'comme d'habitude' et appelons la fonction à partir du Walker_Nav_Menu
classe.
// N'imprime pas les éléments de niveau supérieur function start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_el (& $ output, $ item, $ depth, $ args); fonction end_el (& $ sortie, $ item, $ profondeur = 0, $ args = array ()) if (0 == $ profondeur) return; parent :: end_el (& $ output, $ item, $ depth, $ args);
Nous étendons la display_element
. Cette fonction est responsable de voyager dans les branches. Nous voulons l'arrêter si nous sommes au plus haut niveau et non sur le lien racine actuel. Pour vérifier si la branche sur laquelle nous nous trouvons est «actuelle», nous vérifions si l'élément a l'une des classes suivantes: 'élément de menu actuel
','current-menu-parent
','ancre du menu actuel
'.
// ne suit qu'une fonction de branche display_element ($ element, & $ enfants_elements, $ max_depth, $ profondeur = 0, $ args, & $ sortie) // Vérifie si l'élément en tant qu '"élément actuel" classe $ current_element_markers = array ( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Si l'élément a une classe 'courante', c'est un ancêtre de l'élément actuel $ ancestor_of_current =! Empty ($ current_class); // S'il s'agit d'un lien de niveau supérieur et non du lien actuel ou de l'ancêtre de l'élément de menu actuel, arrêtez-vous ici. if (0 == $ depth &&! $ ancestor_of_current) return; parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Nous étendons maintenant la start_lvl
et end_lvl
les fonctions. Ceux-ci sont responsables de la sortie du code HTML qui encapsule un niveau (dans ce cas, le
Mots clés). Si nous sommes au premier niveau, nous ne voulons pas afficher ces balises (après tout le contenu ne sera pas affiché).
// N'emballe pas la fonction de niveau supérieur start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_lvl (& $ output, $ depth, $ args); function end_lvl (& $ output, $ profondeur = 0, $ args = array ()) if (0 == $ profondeur) return; parent :: end_lvl (& $ output, $ depth, $ args);
Ce cours en entier:
class SH_Child_Only_Walker étend Walker_Nav_Menu // Ne lancez pas la fonction de niveau supérieur start_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_lvl (& $ output, $ depth, $ args); // Ne mettez pas fin à la fonction de niveau supérieur end_lvl (& $ output, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: end_lvl (& $ output, $ depth, $ args); // N'imprime pas les éléments de niveau supérieur function start_el (& $ output, $ item, $ depth = 0, $ args = array ()) if (0 == $ depth) return; parent :: start_el (& $ output, $ item, $ depth, $ args); fonction end_el (& $ sortie, $ item, $ profondeur = 0, $ args = array ()) if (0 == $ profondeur) return; parent :: end_el (& $ output, $ item, $ depth, $ args); // ne suit qu'une fonction de branche display_element ($ element, & $ enfants_elements, $ max_depth, $ profondeur = 0, $ args, & $ sortie) // Vérifie si l'élément en tant qu '' élément courant 'classe $ current_element_markers = array ('current-menu-item', 'current-menu-parent', 'current-menu-ancestor'); $ current_class = array_intersect ($ current_element_markers, $ element-> classes); // Si l'élément a une classe 'courante', c'est un ancêtre de l'élément actuel $ ancestor_of_current =! Empty ($ current_class); // S'il s'agit d'un lien de niveau supérieur et non du lien actuel ou de l'ancêtre de l'élément de menu actuel, arrêtez-vous ici. if (0 == $ depth &&! $ ancestor_of_current) retourne parent :: display_element ($ element, & $ children_elements, $ max_depth, $ depth, $ args, & $ output);
Une fois que vous avez compris le fonctionnement de la classe de programme, vous pouvez l’étendre (ou les extensions existantes de WordPress) pour modifier l’affichage de vos données hiérarchiques. Par exemple, vous pouvez: