Es sind gerne mal die kleinen Dinge, die einem am meisten Kopfzerbrechen bereiten. Im Fallbeispiel gabe es einen Inhaltstypen für Stellenangebote, der immer mal wieder über eine Importfunktion neu befüllt wird. Dem übergeordnet war eine Seite, mitten im Hauptmenü, und hier sollten automatisch die grade aktuellen Stellenangebote in einem Untermenü gelistet sein.
Ein Item hinten dran hängen, dafür kann man gut den wp_get_nav_menu_items filter bemühen, der die Menüpunkte als String zurückgibt. Doch wir wollten ja einen Menüpunkt irgendwo in der Mitte ansprechen.
Wegen eines Punkts den ganzen Walker umschreiben…? Dafür müsste ich mich auch um den Menüaufruf kümmern, damit der weiß, welchen Walker er nehmen muss. Über den wp_nav_menu_objects filter ein paar stdClass-Elemente dynamisch hinzufügen? Das wird spätestens dann zum Problem, wenn der post-status eines Items überprüft wird, oder sich herausstellt, dass das stdClass-Element keine WP_Post-Instanz ist.
Und woran erkennt man eigentlich „seinen“ Menüpunkt? …
Menüpunkt auffindbar machen
Klar hat jeder Menüpunkt seine individuelle ID. Doch je nach Umgebung (Wirkbetriebs-, Test- oder Entwicklungsumgebung) unterschied sich diese. So entschied ich mich für ein Datum, das sich durch eine Eingabe festlegen lässt. Der gesuchte Menüpunkt bekommt daher eine CSS-Klasse. Das macht man in den Design-Einstellungen unter Menü, lässt sich dort Ansicht anpassen
anzeigen, und wählt unter Erweiterte Menüeigenschaften anzeigen
mit einem Häkchen CSS-Klassen
aus. Ansicht anpassen
wieder schließen.
Nun ins Menü der Wahl gehen, in unserem Beispiel ist es das Hauptmenü (primary
). Dem Menüpunkt eine Klasse geben (zum Beispiel „karriere“).
Das Menü speichern, und ggf. im Quellcode vergewissern, dass die Klasse vorhanden ist.
Das Jobmenü anlegen
Für den Fall, dass es keine Jobs gibt, soll die Funktion false zurückgeben. Der Hauptmenüpunkt soll ja nur zum Parent werden, wenn da wirklich was kommt.
function my_prefix_get_jobs_menu() {
$args = array(
'post_status' => 'publish',
'post_type' => 'job',
'fields' => 'ids'
);
$items = get_posts( $args );
if ( $items ) {
$submenu = '<ul class="sub-menu">';
foreach( $items as $post_id ) {
$submenu .= sprintf( '<li class="menu-item"><a class="menu-link" href="%s">%s</a></li>', esc_url( get_permalink($post_id) ), esc_html( get_the_title($post_id) ) );
}
$submenu .= '</ul>';
return $submenu;
}
return false;
}
Das Untermenü anhängen
Statt einen neuen Walker zu schreiben, nutzen wir den Filter im Output der start_el-Funktion im original-Walker_Nav_Menu.
function my_prefix_menu_item_custom_output( $item_output, $item, $depth, $args ) {
if ( $args->theme_location != 'primary' ) return $item_output;
if ( empty( $item->classes ) || !in_array( 'karriere', $item->classes ) ) {
return $item_output;
}
$item_output .= my_prefix_get_jobs_menu();
return $item_output;
}
add_filter( 'walker_nav_menu_start_el', 'my_prefix_menu_item_custom_output', 10, 4 );
Die Elternklasse hinzufügen (optional)
Unser Menüpunkt hat von Natur aus ja keine Untermenüpunkte, daher fehlt ihm die entsprechende Klasse, vor der die meisten Menüs Hauptmenüpunkte kennzeichnen, sodass man auf einen Blick erkennt, dass darunter noch was kommt.
Im letzten Schritt wird dem Menüpunkt eine menu-item-has-children
-Klasse hinzugefügt (die Klasse kann je nach Theme abweichen, daher vorher im Quellcode nachsehen, welche CSS-Klasse Elternelemente im Menü auszeichnet).
Dieser Schritt ist optional, und in erster Linie kosmetischer Natur. Da der Link ja bereits eine eindeutig wiederzuerkennende Klasse hat, könnte er auch direkt danach via CSS angesprochen werden. In unserem Fall verwendet das Parent-Theme seinen eigenen Walker, und fügt allen Eltern-Elementen einen Dropdown-Bedienungs-Button für Mobiles hinzu. Durch das Hinzufügen der Klasse über den wp_nav_menu_objects
-Filter bekam auch „unser“ Element alles, womit auch die anderen Eltern ausgestattet sind.
function my_prefix_add_menu_parent_class( $items, $args ) {
if ( $args->theme_location != 'primary' || false === my_prefix_get_jobs_menu() ) return $items;
foreach ( $items as &$item ) {
if ( in_array( 'karriere', $item->classes ) ) {
$item->classes[] = 'menu-item-has-children';
}
}
return $items;
}
add_filter( 'wp_nav_menu_objects', 'my_prefix_add_menu_parent_class', 10, 3 );
Das geht mit allen Inhaltstypen die veröffentlicht sind, aber auch Kategorien, und sofern erwünscht, natürlich auch unter mehreren Menüpunkten, mit einer jeweils individuellen CSS-Klasse.
Schreibe einen Kommentar