© svetabelaya/Shutterstock.com
Teil 2: Routen, Navigation und Seiten

CMS-Funktionen für Symfony-Applikationen


Der Verweis auf eine andere Seite gehört zu den Grundpfeilern des Internets. Einen Link auf einer Seite kann ich mühelos kopieren und weiterleiten. Es ist ja nur ein Stück Text. In diesem Artikel werden wir sehen, dass man solche Verweise gar abdrucken kann. Mit diesem kleinen Element wird das WWW zu dem Medium, wie wir es kennen. Es verbindet Webseiten miteinander und ermöglicht einen grenzenlosen Austausch.

Mir fehlt das Talent eines Poeten, die Einleitung hätte ein Lobgesang an das Internet werden können. Denn ohne den Verweis und dessen Einfachheit wäre das Internet nie zu dem geworden, was es heute ist. Doch wen interessiert es? Meine technische Sichtweise auf die Welt beeinflusst die Struktur des URL einer Seite immens, doch wie sieht es beim Nutzer aus? Der Browser hat dafür extra ein Eingabefeld eingerichtet, doch es wird für viel mehr als nur die Eingabe eines Suchbegriffs verwendet.

Im ersten Teil dieser Reihe haben wir uns einfache Textblöcke angeschaut. Solange sie in ihrer Verschachtelung keine Tiefe besitzen, könnte man diese Blöcke auch ohne CMS-Unterstützung ablegen, verwalten und ausspielen. Doch mit Anforderungen wie der Übersetzbarkeit, einer Verschachtelung der Blöcke und einem einheitlichen Weg der Ausspielung und Verwaltung bin ich als Entwickler froh über Tools, die mich hier bei der Struktur unterstützen. Genau über diesen Weg sind wir zum Symfony CMF gelangt – jenem Content-Management-Framework, das uns auch in diesem Teil der Artikelreihe mit Funktionen versorgen wird.

Am Anfang war der URL

Vielleicht ein wenig pathetisch, doch die Beweggründe hinter der Einleitung sollen die Relevanz des URLs hervorheben. Für den Nutzer verliert der URL mehr und mehr an Bedeutung. Im Browser kann man kaum noch zwischen der Funktion eines Suchfelds und der Navigationsleiste unterscheiden. Ich habe sogar Nutzer kennen lernen dürfen, deren Navigationsleiste gänzlich ausgeblendet war. Das Anwählen einer Seite geschieht nur noch über Lesezeichen oder die Eingabe eines Suchbegriffs, da die bevorzugte Suchmaschine als Startseite eingerichtet ist. Dazu kommt, dass in neuen Applikationen ein Schalter Hurra die Seite erscheint im Dark Theme nicht mehr von einem Verweis unterscheidbar ist. Links werden als Buttons umgestaltet, Buttons leiten den Nutzer weiter auf eine andere Seite.

Doch diese Seiten – hinter jeder versteckt sich im Grunde eine eigene Ressource – brauchen eine eindeutige Adresse. Wenn wir diese Adresse in eine Aktion unserer Webseite umwandeln wollen, ist das der Punkt, an dem für mich das Routing anfängt. Auch wenn es immer mehr an Relevanz verliert, kann ich z. B. den Adressen meiner Seiten folgendermaßen die Struktur eines URLs geben:

  • Als Homepage: http://meine-seite.de/ oder http://meine-seite.de/de

  • Als wichtige Seiten in der ersten Ebene: http://meine-seite.de/eine-wichtige-seite oder http://meine-seite.de/die-firma

  • Zusammenfassen aller Services unter „/services“: http://meine-seite.de/services/lesen, http://meine-seite.de/services/schreiben oder http://meine-seite.de/services/schlafen

Diese Struktur kann man sich vorstellen wie Ordner auf einem PC. Der Inhalt der Seite kann ein einzelnes Dokument sein, das in einem Ordner liegt. Die Struktur der Inhaltsablage muss aber nicht zwingend mit der Struktur der URLs übereinstimmen. Natürlich ist es für den Contentmanager am einfachsten, wenn er eine parallele Struktur hat und im Idealfall vom Routing gar nichts bemerkt, doch allein der Fall, dass ich eine Seite mehrfach verlinken muss (Canonical Link nicht vergessen), hebt diese Vereinfachung schon wieder auf. Das heißt aber: Wir haben zwei Bäume – also Strukturen – die für die CMS-Funktionen benötigt werden. Auch hier kann man sich wieder die Adaption mit den Ordnern vorstellen. Nur sind diese in diesem Fall wie Ordner, in denen ich Dokument verteile. In dem einen sortiere ich den Inhalt, im zweiten die Routen. Die Verknüpfung wäre dann wie ein Symlink. Und um diese Form der Verknüpfung geht es beim Routing. Ich habe den URL https://meine-seite.de/services/schlafen in eine Seite umgewandelt, deren Inhalt ausgespielt werden soll. Das Ausspielen dieser Seite übernimmt in einer Webapplikation der Controller. Es ist dann egal, ob sich hinter dem URL ein komplexer Teil einer Applikation verbirgt oder einfach nur das Ausspielen eines Titels mit Inhalt in Textform. Der URL wird im Grunde in einen Controller samt Action umgewandelt.

Das S in SOLID

Gemäß dem Single Responsibility Principle geht man in Symfony-Applikationen inzwischen zu sogenannten Action Controllern über. Das heißt, ein Controller als Objekt, der dann selbst Infokanal ist, hat nur noch eine Action. Das heißt, er ist nur noch für genau eine Sache zuständig.

Im Kontext einer Symfony-Applikation ist dieses Routing statisch gelöst. Auch wenn wir hier inzwischen mithilfe von Annotationen das Routing regeln können, möchte ich für mein Beispiel trotzdem eine YAML-Datei verwenden (es ginge auch XML), denn es macht diesen Prozess des Routings offensichtlicher:

# config/routes.yaml service_list: path: /services controller: App\Controller\ServiceController::list

Diese Definition dient nicht nur dem Auflösen eines URL (hier beispielsweise https://meine-seite.de/services), sondern auch für den Rückweg. Wir können dann in unserem Template oder dem Controller den Router nach dem URL fragen und nutzen dazu nur noch den Identifier service_list. Das hat den Vorteil, dass die URL-Segmente an (fast) einer Stelle hinterlegt sind und nicht im Code verteilt liegen. Natürlich kann man diese Routen auch parametrisiert definieren:

# config/routes.yaml service_show: path: /services/{slug} controller: App\Controller\ServiceController::show

Der slug in der Definition des Pfads dient der Identifizierung des Service, von dem wir die Informationen darstellen wollen. Das heißt, mit den Beispielen aus dem obigen Block wäre slug = schreiben|lesen|schlafen. Damit haben wir eine eindeutige Zuordnung, und dem Ausspielen der jeweiligen Service-Seite steht nichts mehr im Weg.

Dynamisches Routing

Wenn man Routen aus der Applikation heraus erstellen, ändern oder wieder löschen muss, so spricht man von einem dynamischen Routing. Eigentlich genügt eine einfache Zuordnung zwischen dem URL und dem Controller samt Action, also wie z. B. in Tabelle 1 zu sehen.

path

controller

/services/schlafen

ServiceController::schlafen

/services/schreiben

ServiceController::schreiben

/services/lesen

ServiceController::lesen

Tabelle 1: Beispiel einer Zuordnung beim dynamischen Routing

Mit einem Index auf dem Pfad wäre es im Grunde ein indexierter Lookup, der die Performance nur geringfügig beeinflussen sollte. Bei der Performance hingegen liegt der Vorteil des statischen Routings von Symfony: Sämtliche Konfiguration wird im Livebetrieb in PHP-Code umgewandelt. Das heißt, der Lookup für das statische Routing wäre nur:

 public function getController(string $path): string { if (\array_key_exists($path, $this->routes)) { return $this->routes[$path]; } }

Das kann man mit einer Datenb...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang