WordPress: Kind- & Enkel-Seiten in der Navigation

WordPress: Kind- und Enkel-Seiten in der Navigation Setzt man WordPress als “klassisches” CMS ein, dann sehen die Layouts vergleichsweise häufig so aus, dass die Hauptnavigation sich oben im Kopfbereich befindet.

Hier werden dann zum Beispiel die Hauptpunkte (Elternseiten) ausgegeben. In der Seitenleiste – manchmal rechts, manchmal links – befindet sich die Unternavigation (Submenü) mit den entsprechenden Unterpunkten (Kindseiten). Gibt es für den jeweiligen Hauptpunkt keine Unterpunkte dann wird natürlich nichts angezeigt.

So lange sich das ganze lediglich auf zwei Ebenen abspielt ist alles in Ordnung. Zuerst gibt man die Elternseiten in der horizontalen Hauptnavigation aus:

<div id="hauptnavi">
    <ul>
        <?php wp_list_pages('title_li=&sort_column=menu_order&depth=1'); ?>
    </ul>
</div>

Der Parameter depth=1 beschränkt die Ausgabe auf Menüpunkte der ersten Ebene. Um jetzt nur die Kindseiten des aktuellen Menüpunktes in der Sidebar anzuzeigen nutze ich folgenden Code:

<ul>
    <?php
      if($post->post_parent) { //Die Seite ist "Kind-Seite"
        wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->post_parent);
      }
      elseif(wp_list_pages("child_of=".$post->ID."&echo=0")) { //Die Seite hat "Kinder"
        wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->ID);
      }
    ?>
</ul>

So lange es lediglich zwei Ebenen gibt – 1. Ebene ist die Hauptnavi und 2. Ebene sind die Kind-Seiten in der Seitenleiste – ist alles wunderbar. Wenn allerdings die dritte Ebene (Enkel-Seiten) hinzu kommt, dann wird es problematisch.

[adrotate group=”4″]

Zwar werden auch die passenden Enkel-Seiten in der Sidebar aufgelistet, aber das ist nicht immer erwünscht. Manchmal wird gewünscht dass die eine Seite 3. Ordnung (Enkel) erst erscheint, wenn die entsprechende Seite 2. Ordnung (Kind) aufgerufen wurde. Diesen Wunsch kann man sehr schnell u. a. in CSS lösen:

#sidebar .children {display: none;}
#sidebar .current_page_item .children {display: block;}

Aber wenn man dann die Enkel-Seite aufruft, dann verschwinden die Kind-Seiten (2. Ordnung) und die Enkel-Seiten befinden sich alleine in der Sidebar. Das ist gelinde gesagt unpraktisch. Wir haben dann gestern recherchiert und vor allem im WordPress-Forum einige weitere Ansätze gefunden, aber keiner der Code-Beispiele hat so funktioniert wie gewünscht.

WordPress: Simple Section Navigation Widget
Simple Section Navigation

Irgendwann hat dann meine bessere Hälfte das Plugin Simple Section Navigation Widget gefunden. Und diese WordPress-Erweiterung hat das Problem mit den Seiten der 3. Ebene sehr gut gelöst.

Ruft man einen Hauptpunkt in der horizontalen Navigation auf, dann werden in der Sidebar, so fern vorhanden, die Unterseiten 2. Ordnung aufgelistet. Ruft man dann einen Seite 2. Ordnung auf, dann werden, ebenfalls falls vorhanden, die Seiten 3. Ordnung aufgelistet.

Und wenn man dann die Seiten 3. Ordung anklickt, dann verschwindet nichts. Sehr fein. 🙂

Es gibt allerdings einen Haken … wäre ja sonst auch langweilig. In der Sidebar erscheint über dem Menü noch einmal zusätzlich die jeweils übergeordnete Seite als Überschrift auf. Eine direkte Lösung gibt es dafür leider nicht, aber CSS ist auch hier unser Freund und Helfer.

Wenn man das Widget für Simple Section Navigation in der functions.php definiert, dann kann man der Widget-Überschrift auch ein Klassen-Attribut vergeben:

<?php
register_sidebar(array('name'=>'navigation',
    'before_widget' => '<div class="sidebar-element">',
    'after_widget' => '</div>',
    'before_title' => '<h3 class="simple-nav">',
    'after_title' => '</h3>',
));
?>

Anschließend kann man dann bei Bedarf die Überschrift, die sich aus der jeweils übergeordneten Seite bildet, ausblenden:

.simple-nav {display: none;}

Das wars. Ich hoffe man kann meinen Ausführungen folgen. Wenn nicht einfach die Kommentarfunktion bemühen.:-)

Wir arbeiten seit 20 Jahren mit WordPress und bieten diverse Dienst­leistungen rund um das System an. Kontaktiere uns für weitere Informationen oder für ein Angebot.

Verwandte Beiträge:

13 Kommentare

  1. Hi Vlad,

    sehr nette Exkursion zum Thema Unterseiten in WordPress einstellen ..
    Danach habe ich schon oft gesucht & es mit dem Plugin “Navigo” gelöst. Dieses beherscht auch Expandierende Menüs.

    Vielen Dank für Deinen Artikel 😀

  2. Ich mach’s mit dem Uralt-Plugin Navigo und der dortigen “dynamic”-Einstellung, die mir Bäume bis in die x-te Ebene öffnet, aber nur die Kind-Ebene (also Generation1) stets offen lässt. Geht super 🙂

  3. Danke für den Plugin-Tipp: ist eine geniale Kombination aus “navigo” und “Wenderhost Subpage Widget”. Das Thema ist “WP-als-CMS-Einsetzer” absolut essentiell 🙂

  4. Über das Problem war ich auch einst gestolpert und hab mir einen Hack einfallen lassen der ohne Plugin funktioniert. Das klappt dann auch mit den Ur-Enkeln wie hier zu sehen ist.

    Erstaunlich find ich das WP da nix von Haus aus liefert, wo es sonst mit Klassen nur so um sich schmeißt 😐

  5. Hi.

    Weil’s gerade so schön zum Thema passt:

    Ich bastele gerade an einem plugin (für 3.1) mit dem man per shortcode im description oder xfn Feld der nativen WP-Menüs diverse Dinge für native WP-Menüs automatisieren kann – also z.B. automatisierte Anzeige von Child-Seiten und Grandchild-Seiten der angegebenen Parent-Seite.

    Wäre jemand interessiert, das mal zu testen, und mir ein paar Rückmeldungen zu geben bevor ich es (in vier Wochen oder so…) veröffentliche?

  6. Danke für die ausführliche Erläuterung. So was in der Art brauche ich nächste Woche für ein Kundenprojekt und bis dato habe ich solche Dinge immer etwas anders gelöst. Werde mir diese Möglichkeit aber mal zu Gemüte führen 😉

  7. Einwandfrei!

    Saß gerade vor einem Projekt mit genau diesem “Problem” und konnte mich zum Glück an diesen Artikel erinnern.

    Hat super geklappt und tut was es tun soll. DANKE!

  8. Hallo,

    ein Freund von mir hat genau dieses Problem ganz einfach mit folgendem Code lösen können, keine Plugins sind dafür nötig:

    post_parent);
    if($top->post_parent) { //Die Seite ist "Enkel-Seite"
    wp_list_pages('sort_column=menu_order&title_li=&child_of='.$top->post_parent);
    }
    else
    {

    if($post->post_parent) { //Die Seite ist "Kind-Seite"
    wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->post_parent);
    }

    elseif(wp_list_pages("child_of=".$post->ID."&echo=0")) { //Die Seite hat "Kinder"
    wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->ID);

    }
    }

    ?>

  9. Hallo,

    ein Freund von mir hat genau dieses Problem ganz einfach mit folgendem Code lösen können, keine Plugins sind dafür nötig:

    post_parent);
    if($top->post_parent) { //Die Seite ist "Enkel-Seite"
    wp_list_pages('sort_column=menu_order&title_li=&child_of='.$top->post_parent);
    }
    else
    {

    if($post->post_parent) { //Die Seite ist "Kind-Seite"
    wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->post_parent);
    }

    elseif(wp_list_pages("child_of=".$post->ID."&echo=0")) { //Die Seite hat "Kinder"
    wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->ID);

    }
    }

    ?>

    Grüße

  10. Leider wird immer der erste Teil des Codes abgeschnitten, warum auch immer.

    Noch mal ein versuch hier für den Anfang:


    post_parent);
    if($top->post_parent) { //Die Seite ist "Enkel-Seite"

  11. Ich hab es über die get_post_ancestors() gelöst:

    $ancestors = get_post_ancestors( $post); // Schreibt ein Array mit den Elternelementen
    if( is_array($ancestors)) {
    /*letzten Key des Arrays auslesen, dort steht das letzte Elternelement*/
    end($ancestors);
    $last = key($ancestors);
    
    echo '<ul>'; // umgebendes HTML-Element für die Liste
    
    /* Wenn kein Elternelement vorhanden ist -> Kind-Elemente von dieser Seite ausgeben */
    if(!$last) {
    	wp_list_pages('sort_column=menu_order&title_li=&child_of='.$post->ID);
    }
    /* Wenn diese Seite Elternelemente hat, dann ist sie ein Kind-Element -> Kind-Elemente der letzten Elternseite ausgeben (funktioniert dann auch in der dritten, vierten, fünften Ebene */
    else {
    	wp_list_pages('sort_column=menu_order&title_li=&child_of='.$ancestors[$last]);
    }
    echo '</ul>'; // umgebendes HTML-Element schließen
    }

Kommentare sind geschlossen.