Statische Inhalte und symfony

24. Juni 2010 von John Freytag [permalink]

Kaum ein Webprojekt kommt ohne statische Inhaltsseiten aus, die prinzipiell aus puren HTML-Templates bestehen und Inhalte bereitstellen, die sich nicht oder nur sehr selten ändern.
In der Regel bietet es sich an, solch Seiten über irgendeine Art von CMS-Mechanik verwaltbar zu machen. Aber gerade für kleinere Projekte kann eine solche Lösung viel zu viel Aufwand bedeuten.

symfony ist ein großartiges Framework, das man beim Erstellen von komplexen Webanwendungen echt nicht missen möchte. Aber da die symfony-Architektur es vorsieht, dass jeder Aufruf einer Seite durch eine Controller-Funktion gesteuert werden muss, wird das Einbinden von statischen Inhalten, die überhaupt keine Logik erfordern, etwas mühsam. Man müsste für jedes einzelne Template eine leere Controller-Funktion schreiben, was nicht nur viel unnötige Tipparbeit ist, sondern den Code auch extrem unleserlich macht – insbesondere wenn es auch Controller mit echter Logik im selben Modul gibt!

Mit Hilfe der Routing-Regeln von symfony kann man sich diese Sache aber zum Glück ersparen:

Nehmen wir an, wir haben von unserem Kunden/Webdesigner 3 statische HTML-Templates bekommen, die es einzubinden gilt: index.html, contact.html und products.html
Damit symfony diese als Templates erkennt, müssen sie zunächst in das übliche Namensschema gebracht werden: Aus index.html wird indexSuccess.php, aus contact.html contactSuccess.php usw..
Bei 3 Templates geht das noch locker per Hand, für mehr nimmt am besten ein Werkzeug wie die bash zur Hand:

	for i in *.html; do mv "$i" "${i/.html}"Success.php; done

Haben wir die Templates nun im richtigen Namensformat im templates-Ordner unseres gewünschten symfony-Moduls (nennen wir es mal “static”), so können wir uns eine Routing-Regel schreiben, die gleich zwei Fliegen mit einer Klappe erschlägt:


static_template:
url: /static/:template.html
param: { module: static, action: index }

In Routing-Regeln werden “.” und “/” als Trennzeichen interpretiert, “:bezeichner” können durch beliebigen Text ersetzt werden, welcher dem aufgerufenen Controller als Request-Variable mit dem Namen “bezeichner” übergeben wird.
Die hier beschriebene Routing-Regel greift also auf alle URLs, die im “Unterordner” static auf .html enden, wobei der eigentliche Name der HTML-Seite (der Teil vor dem .html) uns in der Request-Variable “template” zur Verfügung gestellt wird. Und diese können wir jetzt nutzen, um durch eine einzige Controller-Funktio jeweils das richtige Template darzustellen:

  public function executeIndex(sfWebRequest $request)
  {
	$this->setTemplate($request->getParameter('template', 'index'));
  }

Wird nun also z.B. die Seite /static/contact.html aufgerufen, so greift unsere Routing-Regel und leitet automatisch zur Controller-Funktion der index-Action weiter. Hier hat die Request-Variable “template” nun den Wert “contact”, welcher direkt wenig überraschend zur Auswahl des Templates verwendet wird. Symfony sucht hier also nach einer Datei mit dem Namen “contactSuccess.php” und verwendet diese nun als Template.
Da wir unsere statischen HTML-Seiten am Anfang entsprechend umbenannt haben, wird nun also die ursprüngliche “contact.html” gerendert. Unser Ziel ist erreicht!

Der Clou: Da die URL dank Routing-Magic genau dem ursprünglichen Namen der HTML-Datei entspricht, müssen wir mit Glück nicht einmal die in den Templates verwendeten Links anpassen!

Bevor wir diese Sache zu den Akten legen sollten wir aber noch sicherstellen, dass Aufrufe von nicht existierenden .html-Seiten nicht zu Fehlern führen. Denn wenn ein Template, das angezeigt werden soll, nicht existiert, wirft symfony eine 500er-Fehlerseite statt der hier gewünschten 404-Meldung (Page not found). Dafür sagen wir unserer Controller-Funktion einfach explizit, welche Seiten existieren:

  public function executeIndex(sfWebRequest $request)
  {
	$template = $request->getParameter('template', 'index');
	$allowed_templates = array( 'index', 'contact', 'products' );
	$this->forward404Unless(in_array($template, $allowed_templates));
	$this->setTemplate($template);
  }

Tags:
Kategorie: Allgemein, Symfony

Sie können die Kommentare für diesen Post mit diesem RSS 2.0 Feed verfolgen. Hinterlassen sie einen Kommentar oder einen Trackback von ihrem Blog.

Hinterlasse einen Kommentar: