dynamicinternet Webdesign

Das Blog

Themen, Tutorials sowie Tipps & Tricks über Webdesign, (X)HTML und CSS, Programmierung, WordPress und was uns sonst noch bewegt.

RSS abonnieren

Eine Seitennavigation für die Sidebar

Wer WordPress für Firmenwebseiten einsetzt, hat meistens mit statischen Seiten zu tun, die in einem Hierarchie-Baum abgelegt sind. Um diese Seiten für den Nutzer erreichbar zu machen, gibt es viele Möglichkeiten.

In diesem Beitrag möchte ich ein Beispiel zeigen, in dem sich die Hauptseiten in einer horizontalen Navigation befinden. Die jeweiligen Unterseiten werden beim Klick auf die Hauptseite in der Sidebar angezeigt.

Zum besseren Verständnis nehmen wir folgende Seiten-Struktur:

  • Home
  • Software
    • Bildbearbeitung
      • Adobe Photoshop
      • Gimp
    • Content Managment Systeme
      • WordPress
      • Drupal
      • Joomla
  • Hardware
  • About us

Die Seiten Home, Software, Hardware und About us befinden sich in der horizonatlen Navigation. Wenn der Nutzer beispielsweise auf Software klickt, sollen in der Sidebar alle Unterseiten von Software angezeigt werden.

WorPress stellt für solche Aufgaben den Template Tag wp_list_pages() mit zahlreichen Parametern zur Verfügung. Da wir aber nicht alle Seiten angezeigt haben wollen, ist für uns der Parameter child_of interessant. Der Parameter child_of gefolgt von einer ID listet alle Unterseiten eben dieser Seite, wenn welche vorhanden sind.

<?php wp_list_pages('child_of='.get_the_ID().'&title_li=<h5>'.__('Pages').'</h5>'); ?>

Jetzt kommen wir zum eigentlichen Problem. Klickt man jetzt auf Content Managment Systeme in der Sidebar, erscheinen nur noch die Seiten WordPress, Drupal und Joomla. Die Übergeordneten Seiten sind weg. Logisch, es werden ja nur die Kinder der aktuellen Seite angezeigt und die ist Content Managment Systeme. Für unser Problem brauchen wir aber immer die oberste Seite. Auch da hilft WordPress weiter. Es gibt eine Funktion get_post_ancestors, die alle übergeordneten Seiten in einem Array zurückliefert. Probiert mal folgendes aus:

<?php
$my_page = get_the_ID();
$anchestors = get_post_ancestors($my_page);
var_dump($anchestors);
 
// Klick auf Software
array(0) { }
 
// Klick auf Content Managnet Systeme
array(1) { [0]=>  string(2) "63" }
// 63 ist die ID von Software
 
// Klick auf WordPress
array(2) { [0]=>  string(2) "65" [1]=>  string(2) "63" }
// 65 ist die ID von WordPress
?>

Das würde immer so weitergehen, je tiefer die Hierarchie verschachtelt ist. Wichtig für uns sind 2 Sachen: die oberste Seite steht immer am Ende des Arrays und es kann ein leeres Array zurück kommen. Also gehen wir einfach an das Ende des Arrays und für den Fall, das es keine übergeordnete Seite gibt, geben wir alle Unterseiten dieser Seite aus. Dazu schreiben wir eine Funktion in unserer functions.php, da sie dort einfacher zu pflegen ist und auch in mehreren Sidebars verwendet werden kann:

function wpe_highest_ancestor(){
    global $post;
    $page_ancestors = end($post->ancestors);
    if(!empty($page_ancestors)){
        $child_of = $page_ancestors;
    }else{
        $child_of = $post->ID;
    }
    return $child_of;
}

Jetzt wird diese Funktion in der Sidebar benutzt:

<ul class="sidebar">
  <?php wp_list_pages('child_of=' . wpe_highest_ancestor()); ?>
</ul>

Möchte man den Namen der obersten Seite mit in der Sidebar haben, kann man folgenden Code verwenden:

<ul class="sidebar">
  <?php
  $child_of = wpe_highest_ancestor();
  wp_list_pages('child_of='.$child_of.'&title_li=<h5>'.esc_attr(get_the_title($child_of)).'</h5>');
  ?>
</ul>

Wie man sieht, ist es relativ einfach, mit WordPress entsprechende Lösungen zu erzielen.

11 Kommentare
  1. Dieter sagt:

    Lieber Micha,

    bisher hatte ich für jede “statische” Hauptseite mit ihren Unterseiten eine eigene Sidebar eingebunden.

    Deine Lösung ist deutlich eleganter. Ich werde sie mal mit der Testinstallation ausprobieren. Wenn es klappt, ersetzt sie meine bisherige Krückenlösung.

    Vielen Dank für diese komfortablere Lösung.

    Ein frohes Neues Jahr wünschend
    Dieter

  2. Micha sagt:

    Danke Dieter und ebenfalls ein gesundes Neues Jahr!
    Eventuell mußt du Das Markup ändern, je nachdem, wie deine Sidebar aufgebaut ist. Aber das sollte für dich kein Problem darstellen.

  3. mike sagt:

    Ohweh, das hab ich schon ewig gesucht, bisher hab ich die Kinder immer per CSS ausgeblendet (Äusserst umständlich bei starker Verschachtelung…). Vielen Dank, und schönes Neues!

  4. Micha sagt:

    Danke mike.
    Dir auch ein gesundes Neues Jahr!

  5. Dieter sagt:

    Eventuell mußt du Das Markup ändern, je nachdem, wie deine Sidebar aufgebaut ist. Aber das sollte für dich kein Problem darstellen.

    Micha,
    Du traust mir mehr zu als ich mir selbst. ;-)
    Gruß
    Dieter

  6. Vielen Dank für den Hinweis mit get_post_ancestors.

    Hast Du noch einen Tipp, für folgendes Problem? Um in Deinem Beispiel zu bleiben, möchte ich bei einem Click auf CMS, soll ab CMS der gesamte Subbaum angezeigt werden, aber ohne “Eltern” oder “SChwestern” von CMS.

    Eine Beschreibung meiner Frage findest auch im Wordpress-Forum

  7. Micha sagt:

    Da Dirnbocher: Wenn ich dich richtig verstanden habe, mußt du meine Funktion verwenden, aber ohne array_reverse. Dann ist $page_ancestors[0] die nächst übergeordnete Seite. Probiers mal.

    function wpe_highest_ancestor(){
    global $post;
    $page_ancestors = get_post_ancestors($post->ID);
    if(!empty($page_ancestors[0])){
    $child_of = $page_ancestors[0];
    }else{
    $child_of = $post->ID;
    }
    return (int) $child_of;
    }

  8. Micha sagt:

    Achtung Update. Ich habe den Code optimiert. War mein Fehler, jetzt wird nicht mal mehr die Datenbank beansprucht.

  9. Agy sagt:

    Mensch das hab ich vor kurzem mal gesucht und damals allerdings deinen Beitrag nicht gefunden.

    Werd ich mir gleich mal abspeichern.

    Dankeschön!

  10. mike sagt:

    Hi Micha, das klang -für mich – doch etwas einfacher als ich das raff.
    Kurzfassung: ich bekomme es nicht hin.

    Dein 2. Codeblock; sehe ich das richtig, dass der a: in die sidebar muss, und b: dass ich die ids alle manuell anfassen muss? Oder “war” dieser Code nur zum Probieren?
    Wenn ich deinen (3.) Code in die functions.php und den 4. Code in die Sidebar packe, bekomme ich keine Ausgabe. Was mach ich falsch?

    Um die Sache noch etwas zu verkomplizieren; wäre es nicht günstiger, über Deine Methode gleich das Page-widget zu hacken?

  11. Micha sagt:

    @mike: Codeblock 2 ist nur zum testen der Ausgabe. Code 3 in die functions.php und Code 4 oder 5 in die Sidebar.

    Du machst nichts falsch. Du hast nur bevor der Code der Sidebar ausgeführt wird, eine andere Post global. Damit stimmt die eigentlich erwartete Post ID nicht mehr und es kommt zu keiner Ausgabe. Ich hatte das hier auch einmal.
    Du kannst mich gerne anrufen (Impressum).

1 Pingback
  1. Aktuelle Links (gespeichert vom 26.12.2009 bis zum 03.01.2010) « Der Webanhalter
Einen Kommentar schreiben