WordPress Custom Post Types in der Navigation

Diese Woche war sehr produktiv. Neben einigen spannenden Zend Framework 2 Projekten ist momentan auch ein größeres WordPress Projekt in der Pipeline, welches in Zusammenarbeit mit Kris und Max von RP07 Visuelle Medien und Elisa von Ozella Music entsteht. Um den Pflegeaufwand des WordPress Projekts zu minimieren, lautete eine Anforderung, dass Einträge mit einem spezifischen Custom Post Type automatisch als Untermenüpunkte in der Hauptnavigation der WordPress Seite erscheinen sollen. Normalerweise müssten diese Einträge manuell über die WordPress Naivigations-Menü Einstellungen einem Hauptmenüpunkt zugeordnet werden. Bei entsprechend vielen Einträgen kann das schon sehr nervig sein.
 

Was sind eigentlich Custom Post Types in WordPress?

Viele Themes und Plugins erweitern die WordPress Software dahingehend, dass neben den bereits vorhandenen Seiten- und Blogeinträgen weitere Einträge mit spezifischen Eigenschaften möglich sind. Zum Beispiel könnte ein Event Plugin einen Custom Post Type mit dem Namen „events“ etablieren. Diese Event Einträge könnten dann auch zusätzliche Eingabemöglichkeiten wie ein Datum, Angaben zum Veranstaltungsort und weitere Informationen enthalten. Custom Post Types sind ein großartiges Werkzeug, um die WordPress Software zu erweitern.

Custom Post Type Einträge als Untermenüpunkte

Wenn wir nun bei dem Event Beispiel für unsere Custom Post Types bleiben, müsste man diese über die Menü Einstellungen einzeln Stück für Stück einem Hauptmenüpunkt zuordnen, wenn diese als Untermenüpunkte erscheinen sollen. Wäre es nicht viel praktischer, wenn die gespeicherten Events ganz automatisch als Untermenüpunkte in der Navigation angezeigt werden, ohne dass man diese einzeln zuordnen muss? Gut, dann hier mal ein Code Beispiel, wie man das anstellen kann.

function mmn_add_events_to_nav_menu_objects( $aSortedMenuItems, $aArguments ) {
    global $post;
    $oPost = $post;

    foreach ( $aSortedMenuItems as $oMenuItem ) {
        if ( $oMenuItem->type == 'custom' && $oMenuItem->post_type == 'Veranstaltungen' ) {
            $aArguments = [
                'orderby'       => 'post_title',
                'order'         => 'ASC',
                'post_type'     =>  'event',
            ];

            $aChildren = get_posts( $aArguments );

            $iParentMenuItemID = $oMenuItem->ID;
            $iTermID = $oMenuItem->object_id;

            $iCurrent = $iCurrentInChildren = $i = 0;

            foreach ( $aChildren as $oChild ) {
                if ( $oPost->ID == $oChild->ID && ( is_single() || is_page() ) ) {
                    $iCurrent = 1;
                    $iCurrentInChildren = 1;
                }

                $oChild->ID = count( $aSortedMenuItems );
                $oChild->menu_item_parent = $iParentMenuItemID;
                $oChild->post_type = 'nav_menu_item';
                $oChild->url = $oChild->guid;
                $oChild->title = $oChild->post_title;
                $oChild->menu_order = $i++;
                $oChild->object = 'post';
                $oChild->type = 'post_type';
                $oChild->type_label = 'Post';
                $oChild->target = '';
                $oChild->attr_title = '';
                $oChild->description = '';
                $oChild->xfn = '';
                $oChild->current = $iCurrent;

                $oChild->classes = [
                    'menu-item',
                    'menu-item',
                    'menu-item-type-post_type',
                ];

                if ( $iCurrent ) {
                    $oChild->classes[] = 'current-menu-item';
                    $oChild->classes[] = 'current_post_item';
                }
                
                if ( !in_array( 'menu-item-has-children', $oMenuItem->classes ) ) {
                    $oMenuItem->classes[] = 'menu-item-has-children';
                }
                
                array_push( $aSortedMenuItems, $oChild );   
            }
        }
    }
    
    return $aSortedMenuItems;
}
add_filter( 'wp_nav_menu_objects', 'mmn_add_events_to_nav_menu_objects', 10, 2 );

Kurz erklärt, was dieser Code eigentlich macht. Die Funktion wird in den Hook wp_nav_menu_objects eingehakt. Mit diesem Hook kann man die sortierten Elemente der Navigation filtern. Mit unserer Funktion durchlaufen wir alle Menü Elemente und suchen nach dem individuellen Menü Element mit dem Namen Veranstaltungen. Dieses Menü Element ist unser Hauptmenüpunkt, dem wir alle Einträge des Custom Post Types „event“ unterordnen möchten. Also werden in Zeile 13 alle Events in alphabetisch sortierter Reihenfolge ausgelesen. Alle ermittelten Events werden durchlaufen und als Untermenüpunkt dem Menüpunkt „Veranstaltungen“ hinzugüfügt. Dabei ordnen wir dem Kind-Elment alle benötigten Eigenschaften zu und beachten, ob es sich bei dem Kindelement eventuell um die aktuell angezeigte Seite handelt. In Zeile 52 sagen für dem Hauptmenüpunkt noch, dass er Untermenüpunkte besitzt und ordnen die entsprechende CSS Klasse zu. Am Ende liefern wir den neu Strukturierten Menü-Baum dann aus.
 

Fazit

Die dargestellte Funktion ist leider nicht komplett dynamisch, weil der Name des Menüpunktes hardcodiert in der Funktion steht. Allerdings erfüllt sie ihren Zweck und erspart das manuelle Zuordnen von Custom Post Types. Um die Funktion komplett dynamisch zu gestalten müsste man eine zusätzliche Meta Box in der Menü Maske im WordPress Backend einstellen, die einen zusätzlichen Typen für Menüpunkte etabliert. Als Option für diesen zusätzlichen Typen müsste man die Namen des Custom Post Types eingeben und schon hätten wir das ganze Ding voll dynamisch. Eventuell veröffentliche ich das ja mal als WordPress Plugin hier im Blog. Schauen wir mal …

So und jetzt ab ins Wochenende mit Euch!

1 Gedanke zu „WordPress Custom Post Types in der Navigation“

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.