Vom: 08.11.2012

Pimcore: eine Page in mehreren Navigationen verwenden

Pimcore stellt eine komfortable Möglichkeit zur Verfügung, einer Webseite eine strukturierte Dokumentenhierarchie zu verleihen. Diese Struktur kann automatisiert ausgelesen und sowohl in eine Navigation für die Webseite selbst als auch in sinnvolle und "sprechende" URLs verarbeitet werden. So ist die URL zu einer Seite "Impressum" folgerichtig "/impressum", und falls die Seite in einem Unterverzeichnis steckt dann "/unterverzeichnis/impressum". Häufiger hatten wir hier das Problem, dass auf der Webseite mehrere, voneinander getrennte Navigationen gewünscht sind. Diese kann man in Pimcore dann ganz leicht in Unterordnern zusammenfassen und jeden individuell auslesen und in eine Navigation verwandeln. Dies stellt aus Suchmaschinensicht aber nicht das Optimum dar, da mit jedem Unterpfad die Relevanz der Seite sinkt, von der "merkwüdigen" URL wie "/kopfnavigation/impressum" ganz zu schweigen. Wir haben daher mit Hilfe der Eigenschaften, die in Pimcore jeder Seite vergeben werden können, eine Lösung entwickelt. Folgende Ausgangssituation: Es existieren drei Navigationen:

  1. Die Kopfnavigation
  2. Die Linke Navigation
  3. Die Hauptnavigation

Zudem gibt es im Fuß der Seite die Gesamtnavigation in der jeder mögliche Navigationspunkt nochmal aufgeführt ist: In Pimcore sind diese Seiten in einer flachen Hierarchie untergebracht, um möglichst kurze URLs zu produzieren: In der Umsetzung bedienen wir uns der Zend_Navigation, welche uns sehr viel Arbeit abnimmt. Mit dem pimcoreNavigation() View Helper stellt uns Pimcore eine komfortable Möglichkeit zur Verfügung, eine fertige Zend_Navigation aus dem Dokumentenbaum zu erzeugen. Dies erreicht man durch Aufrufen der Methode getNavigation($currentDocument, $navStartNode) des View Helpers. $currentDocument stellt dabei das Dokument dar, das in der Navigation als "aktiv" markiert werden soll. In unserem Zusammenhang ist das $this->document. Die Variable $navStartNode beschreibt das Dokument, dessen Kinder die einzelnen Links werden. In unserem Fall ist das "/home".

      $navStartNode = Document::getById(1);
      $gesamte_nav = $this->view->pimcoreNavigation()->getNavigation($this->document, $navStartNode);

Aus dieser Navigation erzeugen wir nun die anderen, wir müssen jeder Seite nur noch die Information mitgeben, in welcher Navigation sie zusätzlich noch erscheinen soll. Dies erreichen wir mit den Eigenschaften der Seite. Praktisch hierfür ist es, eine vorgefertige Eigenschaft zu definieren, aus der dann nur noch ausgewählt werden muß. Hier ist das eine "select" Eigenschaft mit den Werten "Kopf,Links,Haupt": Diese Eigenschaft kann man nun jeder Seite zuweisen: Diese Information kann nun bequem ausgewertet werden, um die einzelnen Navigationen zu erzeugen. Hierbei lesen wir jede Zend_Navigation_Page aus der Navigation aus und werten die Eigenschaft "navigation" des Documents der Page aus. Abhängig vom Inhalt wird eine Seite gegebenenfalls einer weiteren Navigation zugewiesen:

      $kopf_nav  = new Zend_Navigation();
      $linke_nav = new Zend_Navigation();
      $haupt_nav = new Zend_Navigation();

      foreach ($gesamte_nav as $page) {
        $newpage = clone $page;
        $nav_property = trim($page->getDocument()->getProperty("navigation"));
        if     ($nav_property == "Kopf")  $kopf_nav->addPage($newpage);
        elseif ($nav_property == "Haupt") $haupt_nav->addPage($newpage);
        elseif ($nav_property == "Links") $linke_nav->addPage($newpage);
      }

      $this->view->gesamte_nav = $gesamte_nav;
      $this->view->kopf_nav    = $kopf_nav;
      $this->view->linke_nav   = $linke_nav;
      $this->view->haupt_nav   = $haupt_nav;

Ganz wichtig hierbei ist es, $page vor der Zuweisung durch addPage() mit dem clone keywords zu kopieren (Zeile 6), da Zend_Navigation_Container der Seite beim addPage()-Vorgang ein neues Parent zuweist und damit der Gesamt-Navigation entziehen würde. Die so erzeugten Navigationen können im Layout nun bequem ausgegeben werden:

echo $this->navigation()->menu()->renderMenu($this->kopf_nav, array("maxDepth" => 0));