Sich mit der WordPress Walker-Klasse vertraut machen

Veröffentlicht: 2020-11-27

Wenn Sie mit der Walker-Klasse nicht vertraut sind, lassen Sie sich überraschen, wie hilfreich sie für Ihre Arbeit sein kann. Die WordPress Walker-Klasse wurde in WordPress 2.1 implementiert, um Entwicklern die Möglichkeit zu geben, baumartige Datenstrukturen zum Zweck des Renderns von HTML zu durchlaufen. In diesem Artikel werden wir untersuchen, wie der Walker-Parameter funktioniert und wie die Ausgaben in Menüs, Kategorien und Kommentaren angepasst werden können.

Lasst uns anfangen!

Überblick über die Walker-Klasse

In WordPress sehen wir häufig Objekte, die eine hierarchische Struktur haben, wie Navigationsmenüs, Kategorielisten oder Kommentarlisten

Wie Sie vielleicht bereits wissen, sind im Fall einer Baumdatenstruktur einige Elemente Eltern und andere ihre Kinder. „Post Subcategory 1“ ist ein untergeordnetes Element von „Post Category 1“, eine Antwort auf einen Kommentar ist ein untergeordneter Kommentar zum Kommentar selbst und „Service 1“ ist ein untergeordneter Menüpunkt des Elements „Services“.

Der Walker wird so benannt, weil er einfach durch jedes Objekt oder assoziative Array „wandert“ und an jedem Knoten eine Funktion ausführt. Was wir damit erreichen möchten, ist die Möglichkeit, die Links der „obersten Ebene“ mit ihren „untergeordneten“ Elementen auf unterschiedliche Weise gemäß unseren spezifischen Anforderungen aufzulisten.

Mit anderen Worten, WordPress gibt Ihnen eine Standard-<ul> <li>-Struktur und Sie können ihre Argumente anpassen, aber durch Erweitern des Walkers können Sie die Struktur selbst anpassen, indem Sie ihren HTML-Inhalt ändern.

Die Kerndatei, die sich auf die Walker-Klasse bezieht, ist wp-includes/class-wp-walker.php und regelt alle Arten von baumartigen Daten, die wir zuvor aufgelistet haben.

Da es sich um eine abstrakte PHP-Klasse handelt, muss sie zum Generieren von HTML vom Entwickler erweitert werden, der eine angepasste Version ihrer Eigenschaften und Methoden definiert. Sehen wir uns also nacheinander die untergeordneten Klassen in der Datei class-wp-walker.php an.

Kinderklassen

Der $tree_type ist eine optionale Variable, die in einem Typ oder Array von Typen kommt und definiert, was die Klasse handhabt.

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

$db_fields ist eine erforderliche Variable und definiert, welche Datenbankfelder verwendet werden sollen. Diese Eigenschaft ist ein Array mit zwei Schlüsseln: „parent“ und „id“, deren Werte die Namen der Objekteigenschaften sind, die die übergeordnete ID bzw. die Element-ID enthalten.

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

Die Eigenschaft $max_pages ist ebenfalls optional und ihre Rolle besteht darin, die maximale Anzahl von Seiten anzugeben, die der Paged Walker durchlaufen hat.

 public $max_pages = 1;

Das $has_children ist eigentlich selbsterklärend und hat einen wahren oder falschen Wert, je nachdem, ob das aktuelle Element Kinder hat.

 public $has_children;

Die Methode start_lvl wird auf der Wurzel eines neuen baumähnlichen Objekts ausgeführt und nimmt die Argumente $output, $depth und $args entgegen.

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

Das $output Argument hängt zusätzlichen Inhalt an, $depth gibt die Tiefe des Elements an und $args ist ein Array von zusätzlichen Argumenten.

Die end_lvl Methode schließt das Tag, das zuvor von der start_lvl-Methode geöffnet wurde.

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

Die Methode start_el (Startelement) wird verwendet, um das öffnende HTML-Tag für das aktuelle Element anzuzeigen. Im Falle eines Menüs ist es zum Beispiel normalerweise ein <li>-Tag.

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

Die Funktion end_el wird aufgerufen, nachdem der Walker ein Element mit allen seinen Kindern übergeben hat und ein schließendes Tag zurückgibt.

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

Das display_element zeigt tatsächlich die Elemente des Baumobjekts an. Es ruft start_el , start_lvl , display_element , end_lvl , end_el in dieser Reihenfolge auf. Werfen wir nun einen Blick auf seine Argumente.

  • $element : das aktuelle Element
  • $children_elements : alle untergeordneten Elemente des Baumobjekts
  • $max_depth : die maximale Tiefengrenze, die wir erkunden können
  • $depth : Das Level, auf dem wir uns gerade befinden
  • $args : zusätzliche optionale Argumente
  • $output : Die aktuelle HTML-Ausgabe.

Wir demonstrieren nun ein Beispiel für jeden Datentyp, indem wir eine WordPress-Installation mit aktiviertem Twenty Twenty-Design verwenden.

Anpassen einer Menüstruktur

Die Funktion wp_nav_menu(), die WordPress zum Anzeigen von Menüs verwendet, ist in der Datei wp-includes/nav-menu-template.php enthalten. In dieser Datei ruft WordPress um Zeile 605 herum auch die Klasse Walker_Nav_Menu auf.

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

Die Klasse Walker_Nav_Menu ist in der Datei wp-includes/class-walker-nav-menu.php und stellt im Grunde den gesamten Inhalt der Datei dar.

Um die Ausgabe des Menüs anzuzeigen, verwendet der WordPress-Code die Eigenschaften und Methoden der Walker_Nav_Menu-Klasse, die in dieser Datei beschrieben sind.

Lassen Sie uns zum Beispiel ein bekanntes Problem beheben, mit dem viele Entwickler konfrontiert sind, nämlich das Element für übergeordnete Menüelemente mit einem leeren benutzerdefinierten Link ('#') zu ändern, um Besucher daran zu hindern, darauf zu klicken.

Damit wir unsere Ergebnisse vergleichen können, erstellen wir zunächst einen Klon des Primärmenüs, indem wir einfach den folgenden Code in die header.php direkt nach dem Start des <header> -Elements einfügen.

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

Was wir hier tatsächlich getan haben, war, das Primärmenü neu zu generieren und seine Dropdown-Funktionalität und CSS zu erben, indem wir seine Klasse primary-menu reset-list-style ebenfalls zum neuen Menü hinzugefügt haben.

Jetzt erstellen wir in unserer Datei functions.php eine Klasse, die die Klasse Walker_Nav_Menu erweitert. Da wir den Elementtyp ändern möchten, überschreiben wir die Methode 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>'; } } } }

Also haben wir jedes Element normalerweise mit einem <li>-Tag umschlossen und dann unter Verwendung der if-Anweisung eine Spanne angehängt, wenn ein Link „#“ ist, und ein <a>-Tag für den Rest.

Um dies auf unser Menü anzuwenden, kehren wir zum zuvor hinzugefügten Menücode zurück und geben den Walker-Parameter an:

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

Nun sollte das Ergebnis so aussehen:

Wenn Sie nun den Mauszeiger über den Menüpunkt „Dienste“ bewegen, erscheint kein Handcursor und dieser Menüpunkt ist auch nicht anklickbar. Das Dropdown-Untermenü wird jedoch weiterhin korrekt angezeigt.

Anpassen von Kategorien

Gehen Sie zuerst in den Admin-Bereich und erstellen Sie einige Post-Kategorien und Unterkategorien, um einen Kategoriebaum für die Demonstration zu haben.

Danach generieren wir eine Kategorieliste, indem wir diesen Code irgendwo in die header.php . Sie können es wie bisher nach dem Beginn des Header-Elements platzieren.

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

Die Funktion ist eine eingebaute WordPress-Funktion, die eine HTML-Ausgabe eines Kategoriebaums generiert. Standardmäßig werden nur die Kategorien angezeigt, die Beiträge enthalten, weshalb wir die Option hide_empty verwendet haben, um auch die leeren Kategorien anzuzeigen und die gesamte Hierarchie für die Zwecke dieses Beispiels anzuzeigen.

Wie zuvor können wir eine benutzerdefinierte Klasse in functions.php erstellen, um die Standardklasse Walker_Category zu erweitern, die in der Datei wp-includes/class-walker-category.php beschrieben ist, und unsere Änderungen anwenden. Zum Beispiel werden wir einige Symbole vor den Kategorienamen hinzufügen, indem wir diesen Code hinzufügen:

 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); } } }

Dazu müssten Sie natürlich passende Bilder vorbereiten und in dem definierten Ordner speichern. Diese Bilder müssten einem bestimmten Namensformat folgen, das in diesem Beispiel „Post-Kategorie-1“, „Post-Unterkategorie-1“, „Post-Kategorie-3.jpg“ usw. wäre.

Anpassen von Kommentaren

Das Aktualisieren des Menüs und der Kategorienliste ist bei weitem der häufigste Grund, warum Sie eine Walker-Klasse anpassen könnten, aber manchmal müssen Sie die gleiche Technik auch für Kommentare implementieren. Wenn du beispielsweise die Metainformationen neben dem Gravatar-Bild im Kommentarbereich ändern möchtest, können wir dies ganz einfach tun, indem wir die Walker_Comment-Klasse erweitern, die sich in der Datei wp-includes/class-walker-comment.php befindet.

Fügen Sie diesen Code in der Datei functions.php hinzu

 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 } } }

Wie Sie beim Vergleich des About-Codes mit dem Inhalt des ursprünglichen Walker_Comment feststellen können, war die einzige notwendige Änderung in der html5_comment Methode, die im Wesentlichen einen Kommentar im HTML5-Format ausgibt.

Danach müssen wir die Kommentarliste anzeigen, indem wir die eingebaute Funktion wp_list_comments mit den richtigen Argumenten verwenden, um das baumähnliche HTML-Objekt der Kommentare anzuzeigen.

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

Wir haben den Code in dieselbe Zeile von header.php wie zuvor eingefügt und die ID des Beitrags verwendet, der die Kommentare enthält. Natürlich können Sie stattdessen einfach den kommentarbezogenen Code Ihrer Vorlage ersetzen und die Option „Seite“ überspringen, sodass sie für alle Ihre Artikelkommentarabschnitte gilt.

Wenn Sie Ihr Website-Frontend jetzt aktualisieren, werden Sie die zusätzlichen Info-Einträge (Autoren-Bio und Autoren-URL) bemerken, die wir oben im benutzerdefinierten Code hinzugefügt haben.

Fazit

Hoffentlich hat Ihnen das Obige einen Einblick in die Verwendung der WordPress Walker-Klasse gegeben. In allen Beispielen haben wir Änderungen direkt auf die zentralen Designdateien angewendet. Während dies für Demonstrationszwecke in Ordnung ist, sollten Sie natürlich sicherstellen, dass Sie in der Praxis nur Änderungen an einem untergeordneten Thema vornehmen, um sicherzustellen, dass diese Aktualisierungen nicht überschrieben werden, wenn entweder WordPress oder das verwendete Thema aktualisiert wird.