0251 / 590 837 15
info@a-coding-project.de
;

PHP Breadcrumb erstellen

Code & Blog Logo

Code & Blog Logo

Um eine Breadcrumb-Navigation zu erstellen müssen wir erstmal wissen, welche Seite zu welcher Seite gehört. Dies geschieht in unserem Fall durch die Tabelle cms_pages, in welcher alle Seiten gespeichert werden. Sie bekommt nun eine Weitere Spalte, wo der Besitzer (owner) steht. Das heißt, hier muss nachher die ID der Übergeordneten Seite angegeben werden. Ist die Seite auf dem höchsten Level, also wenn sie keine Überseiten hat, bekommt sie hier eine -1.

Wir benötigen für das Hinzufügen der Spalte den folgenden Query:

ALTER TABLE `cms_pages`
ADD `owner` INT DEFAULT '-1' NOT NULL

Wenn wir nun schonmal in der Datenbank sind, können wir auch noch 2 weitere Testseiten hinzufügen, die beide einen Besitzer haben:

INSERT INTO `cms_pages` ( `id` , `alias` , `title` , `owner` )
VALUES (
'', 'testseite2', 'Testseite 2', '1'
), (
'', 'testseite3', 'Testseite 3', '2'
);

Diese Seiten sollten natürlich auch existieren. Also legen wir nochmal 2 Seiten mit Testinhalt an.

testseite2.htm (Verzeichnis content/articles):

<h1>Testseite 2</h1>

und testseite3.htm:

<h1>Testseite 3</h1>

Nun müssen wir in der Klasse page den Besitzer als Property hinzufügen. Dafür machen wir als erstes 2 neue Properties. Einmal $ownerid und einmal $owner. Es sind 2, da der owner vielleicht manchmal gar nicht benötigt wird und somit erstmal nur die id eingetragen wird. Hier erstmal die neuen 2 Properties:

var $ownerid = -1;
var $owner = false;

Um die id nun zu laden, müssen wir diese auch in der Funktion loadProperties auslesen. Die neue Funktion sieht nun so aus:

  function loadProperties($alias){
    global $dbpraefix;
    $res = mysql_query("SELECT id,title,owner FROM ".$dbpraefix."pages 
                        WHERE alias = '".$alias."'");
    if($row = mysql_fetch_row($res)){
      $this->id = $row[0];
      $this->title = $row[1];
      $this->ownerid = $row[2];
      $this->alias = $alias;
    }
  }

So, jetzt haben wir schonmal die ID. Nun brauchen wir noch eine Funktion, welche uns den Besitzer als Objekt zurückgibt. Damit das Objekt nicht immer wieder neu ausgelesen werden muss, wird es in die Property $owner geschrieben. Nur wenn diese auf false steht, wird der Owner ausgelesen. Hier ist der Code:

function getOwner(){
    global $dbpraefix;
    if(!$this->owner){
      $res = mysql_query("SELECT alias FROM ".$dbpraefix."pages 
                          WHERE id = '".$this->ownerid."'");
      if($row = mysql_fetch_row($res)){
        $this->owner = new Page();
        $this->owner->loadProperties($row[0]);
      }
    }
    return $this->owner;
  }

Jetzt haben wir schonmal den Owner. Also fehlt nur noch die wirkliche Breadcrump Funktion. Diese wird erstmal in dieser Klasse(page) als 2-Dimensionaales Array zurückgegeben und später in der Klasse sys ausgegeben. Das ganze ist eine rekursive Funktion, dass heißt, das sie sich selbst wiedrr aufruft. Denn wir brauchen auch alle übergeordneten Seiten und nicht bloß eine. Die Funktion getBreadcrump der Klasse page sieht so aus:

  function getBreadcrump(){
    if(!$this->owner) $this->getOwner();
    if($this->owner){
      $breadcrump = $this->owner->getBreadcrump();
    }
    $breadcrump[] = array($this->alias,$this->title);
    return $breadcrump;
  }

Als nächstes gibt es eine Funktion (in der Klasses sys) die die Breadcrump Navigation ausgibt. Sie hatfolgende Parameter:

  • $separator: Gibt den Code an, der zwischen den Einträge ausgegeben werden soll (z.B. das “ -> „.
  • $class: Gibt die Klasse für die Breadcrump Navigation an. So kann diese später per CSS gestaltet werden.
  • $idpraefix: Gibt den ersten Teil der id der Elemente wieder. Der zweite Teil ist eine laufende Nummer. Dadurch kann per CSS oder JavaScript jedes Element der Breadcrump eigens angesprochen werden.

In der Funktion holen wir uns erstmal die Breadcrump als Array aus der aktuellen Seite. Danach gehen wir mit einer While schleife und einen Zähler alle Einträge durch. Hier nehmen wir keine foreach Schleife, da wir den Zähler und die Anzahl der Elemente benötigen, damit der letzte Separator nicht gesetzt wird. Die komplette Funktion ist diese:

function displayBreadcrump($separator,$class,$idpraefix){
    global $currentpage;
    $i = 1;
    $breadcrump = $currentpage->getBreadcrump();
    while($i <= count($breadcrump)){
      echo "<a href="".$breadcrump[$i-1][0].".htm" class="".$class."" 
            id="".$idpraefix.$i."">".$breadcrump[$i-1][1]."</a>";
      if($i < count($breadcrump)){
        echo $separator;
      }
      $i++;
    }
  }

Jetzt muss diese Funktion nur noch aufgerufen werden. Dies geschieht natürlich in der index.php unseres Skins. Ihr neuer Quellcode sieht so aus:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml/" xml:lang="de">
  <head>
    <?PHP
      sys::includeHeader();
    ?>
  </head>
  <body>
    <?PHP
      sys::displayBreadcrump(" -&gt; ","breadcrump","bc");
      sys::includeContent();
    ?>
  </body>
</html>

Zum Testen ruft nun bitte die Seite testseite3.htm auf. Hier sollte nun eine Breadcrump navigation erscheinen. Klickt doch mal ein bisschen rum, um zu sehen, ob auch alles Klappt.

Hier ist die Testseite 3 bei mir (sieht hat sich jedoch ggfl. schon wieder geändert):

http://cms.stevieswebsite.de/testseite3.htm

Verwandte Themen

Kommentare

Akini schrieb am 28.10.2009:

Hi, bei mir besteht das Problem, dass er die testseite3.htm nicht öffnen möchte. Ich kann sie nur öffnen wenn ich den kompletten pfad angebe. Kann mir jemand sagen was ich falsch gemacht habe, bin alles schon drei mal durchgegangen und habe immer noch keinén Fehler gefunden. mfg Akini

Stefan Wienströer schrieb am 29.10.2009:

Hast Du evtl. kein Mod Rewrite, oder hast Du vielleicht vergessen, die .htaccess zu erstellen?

Floh schrieb am 27.06.2010:

Hi, ich hab mich bisher an deine Anleitung gehalten und es hat bisher auch alles geklappt nur jetzt bekomme ich, wenn ich die testseite3.htm aufrufe, oder generell irgendeine Testseite aufrufe das hier: Fatal error: Call to undefined method sys::displayBreadcrump() in C:xampplitehtdocssystemskinsdefaultindex.php on line 11 Ich habe die Funktion "displayBreadcrump", wie beschrieben in die sys.php Datei im system Ordner geschrieben, oder besser gesagt reinkopiert.

Floh schrieb am 27.06.2010:

K, hab meinen Fehler gefunden, ich hatte die klassen sys und page jeweils zu früh mit } geschlossen, sodass die ganzen anderen Funktionen nicht berücksichtigt wurden.

C0dR schrieb am 16.11.2010:

muss es nicht heißen testseite2.PHP usw? Weil es wird ja beim filtern eine Php draus gemacht

Stefan Wienströer schrieb am 17.11.2010:

Nein, in den Links wird dabei die Endung drangehangen (.htm)

Flotze schrieb am 05.12.2010:

Erstmal ein dickes Lob an diesen Blog. Wirklich interessant geschrieben und gut erklärt. Ich bin jeden Schritt genau durchgegangen und hab alles nach Anleitung gemacht. Wenn ich jedoch jetzt nach Schritt 20 meine Seite aufrufen möchte, kommt immer die Fehlermeldung "Objekt nicht gefunden". Ich arbeite mit xampp lokal auf meinem Rechner. Wenn ich da jetzt meine testseite.php (liegt so im Ordner content/articles) aufrufen möchte muss ich ja in meinem Browser localhost/testcms/testseite3.htm eintippen oder??

Stefan Wienströer schrieb am 06.12.2010:

Hast du Mod-Rewrite?

Flotze schrieb am 06.12.2010:

.htaccess?? Ja hab ich

Stefan Wienströer schrieb am 06.12.2010:

Mod Rewrite ist ne Erweiterung für den Apache. Aber egal. Das Problem liegt vermutlich daran, dass das CMS bis zu der Stelle noch nicht für Unterverzeichnisse ausgelegt war (mittlerweile ist das anders). Schreib mal stattdessen folgendes in die .htaccess: RewriteEngine on RewriteCond %{REQUEST_URI} /(.*).htm RewriteRule (.*) /testcms/index.php?include=%1

Flotze schrieb am 06.12.2010:

Hab ich. Hat sich nichts geändert. Was muss ich den genau in meinem Browser eingeben?? localhost/testcms/testseite2.php?? Oder mit htm-Endung?? Nämlich auch wenn ich den ersten Einstiegspunkt nehme funktioniert es bei mir nicht

Stefan Wienströer schrieb am 06.12.2010:

Mit htm meldeung. Wenns immer noch nicht klappt mach mal ne Datei mit <?PHP echo phpinfo(); ?>, öffne sie im Browser und schick den Inhalt an mich (Mail-Adresse im Impressum)

HeSa schrieb am 11.03.2011:

Also ich versuche dein Tutorial gerade nachzuvollziehen, jedoch mit ein paar kleinen Änderungen in der Struktur, ich habe aber auch ein anderes Ziel als nur ein Tut^^ Nun taucht bei den beiden Testseiten ein Problem auf, solange die beiden Testseiten die Endung .htm haben, sagt er, Seite/Objekt nicht gefunden. Wenn ich sie umbenenne, dann werden sie angezeigt, allerding funktioniert hier nichts mit dem klicken, ich sehe lediglich den Link zur aktuellen Seite, jedoch nicht den Ursprung (Owner) dieser, also kann ich nicht nachvollziehen, wo hier die Navigation passen soll. Fehlermeldungen bekomme ich nicht. mein geändertes Praefix funktioniert, der Content-Ordner ist der gleiche wie bei dir, lediglich der Skin-Ordner heisst bei mir templates und liegt im Hauptverzeichnis.

MeRo schrieb am 30.03.2011:

Hey, auch von mir erstmal bissl Geschleime, echt schönes Tutorial soweit. Mir als Anfänger gefällt es sehr gut und hilft ohne große Vorahnung von MySQL und PHP sehr beim Verständnis. Habe bis jetzt alle Schritte durchgearbeitet. Hat soweit auch alles gefunzt, nur bekomme ich nach diesem Schritt einen Fehler und zwar: Warning: include(content/articles/.php) [function.include]: failed to open stream: No such file or directory in C:xampphtdocseclipse_workspaceCMSsystemclassespage.php on line 21 Warning: include() [function.include]: Failed opening 'content/articles/.php' for inclusion (include_path='.;C:xamppphpPEAR') in C:xampphtdocseclipse_workspaceCMSsystemclassespage.php on line 21 Ich rufe es über die URL: http://localhost/eclipse_workspace/CMS/index.php?include=testseite3.htm auf, weiß nicht ob das evtl schon mein Fehler ist, wenn ich es mit ../CMS/testseite3.htm aufrufe meldet sich XAMPP und fragt nach meinen Login Daten was aber auch nichts ändert. Hoffe mir kann wer helfen damit ich das Tutorial weiter verfolgen kann. Gruß MeRo

jULiM schrieb am 17.05.2011:

@MeRo entferne mal das ".htm" aus dem Link... Dann sollte es wieder laufen ;)

Cengiz schrieb am 22.06.2011:

Also mit "testseite2.php" und "testseite3.php" statt der Endung "html" funktioniert es. So ist zumindest bei mir auch in der .htaccess definiert.

Willy schrieb am 03.09.2011:

Lieber Stefan, heute wollte ich es auch wissen: Bevor ich mit Contao u. ä. beginne, wollte ich mich lernend an den Sinn des CMS heranwagen. Bekam über Suchmaschine Dein Tutorium feilgeboten. Herzlichen Dank! Bis hierher lernte ich sehr viel! Auch wenn ich wahrscheinlich nie ein eigenes CMS aus Zeitgründen schaffe, weitet das Tutorium den Blick dafür. Jetzt meine Anmerkungen: Schön wäre es, wenn unten nach jedem Teil ein Link "Weiter" oder so stünde, damit man nicht immer wieder ins Inhaltsverzeichnes muss. Übrigens erhalte ich hier zwei Warnings, nämlich: Warning: Page::include(content/articles/errors/404.php) [page.include]: failed to open stream: No such file or directory in /blabla/Sites/wifer_cms/system/classes/page.php on line 47 Warning: Page::include() [function.include]: Failed opening 'content/articles/errors/404.php' for inclusion (include_path='.:/Applications/MAMP/bin/php5/lib/php') in /blabla/Sites/wifer_cms/system/classes/page.php on line 47 Eine ähnliche Warnmeldung befindet sich auch im Video. Wo steckt die Ursache? Danke nochmals, Willy.

Willy schrieb am 04.09.2011:

AHA! Warnungen resultieren aus Eintrag in /system/classes/filterfilename.php. Gruß Willy.

Lucas schrieb am 04.10.2011:

Hallo, Ich verzweifle bald. Wenn ich meine Testseite3 aufrufe, bekomme ich immer die Meldung Fatal error: Cannot redeclare Page::loadProperties() in /mnt/web9/20/60/52388760/htdocs/mein-cms/system/classes/page.php on line 49 Kann mir jemand helfen?

Stefan Wienströer schrieb am 04.10.2011:

Hi, schau mal nach, ob du die funktion loadProperties in der Datei system/classes/page.php nicht versehentlich doppelt eingefügt hast. Gruß Stefan

Andreas schrieb am 22.10.2011:

Heißt es nicht eigentlich "Breadcrumb"? :-) Was bedeutet überhaupt "$this-&gt;"? Gruß Andreas

Cedric schrieb am 10.11.2011:

"$this-&gt;" kommt aus der OOP

Cedric schrieb am 10.11.2011:

Hy, Du hast oben diesen Test “ So, jetzt haben wir schonmal die ID. Nun brauchen wir noch eine Funktion, welche uns den Besitzer als Objekt zurückgibt. Damit das Objekt nicht immer wieder neu ausgelesen werden muss, wird es in die Property $owner geschrieben. Nur wenn diese auf false steht, wird der Owner ausgelesen. Hier ist der Code:“ Und darunter eine Function script. Wo soll ich diese Funktion abspeichern? Danke Cedric

Stefan Wienströer schrieb am 10.11.2011:

In die Klasse Page natürlich ;-)

Cedric schrieb am 11.11.2011:

Danke habe da noch ein kleines Problem. wenn ich diesen Link nutze, http://cms.stevieswebsite.de/testseite3.htm erhalte ich diese Meldung. Error 404 - Not found Die angegebene Seite konnte nicht gefunden werden.

Stefan Wienströer schrieb am 11.11.2011:

Wenn du in der filterfilename vor dem Zuweisen der 404 mal den Filename ausgibst, was steht dort?