XSL / XSLT als Templatesystem

Bekanntlich setzt das papaya CMS bereits seit Version 1 (um 2000) auf XSL / XSLT als Templatesystem. Auch wenn der Standard schon viele Jahre besteht und z.B. im professionellen Umfeld (große Softwareprojekte, insbesondere im Java Bereich) eine große Wertschätzung und Verbreitung genießt, so ist die Wahrnehmung bei vielen PHP Entwicklern leider noch anders. Und das obwohl XSL / XSLT ein offener Standard ist, der die vielbeschworene Trennung von Logik, Inhalt und Layout sauber implementiert und der nicht zuletzt beliebige Ausgabeformate (HTML, XML, PDF u.v.m.) ermöglicht.

Umso erfreulicher ist es immer, wenn die mannigfaltigen Vorteile gegenüber proprietären Script- und Templatesprachen die Runde machen – wie aktuell in einem lesenswerten Beitrag von phpmonkeys.de.

Fazit der Autoren:

Der Vorteil von XSL ist, dass man dieses Verfahren mit jeder Programmiersprache einsetzen kann, die einen XSLTProzessor mitbringt. Und dabei können Template- und Layout-Dateien ohne Aufwand migriert werden. Man benötigt nur eine ähnliche Implementierung wie der HTMLGenerator und Logik, die die XML-Daten generiert.

…das völlig korrekt – neben weiteren Vorteilen:

  • offener Standard des W3C, keine proprietäre Lösung
  • in die Einarbeitung investierte Zeit ist nicht auf ein Produkt begrenzt, sondern kann in verschiedenen Projekten angewandt werden
  • hervorragend dokumentierter Standard, viel Literatur verfügbar
  • hohe Verbreitung in der Java-Welt
  • mächtiges Werkzeug/Programmiersprache
  • gut nutzbar für Internationalisierung der Ausgabe
  • und viele, viele mehr… 😉

Open Social – erster Überblick, Videos, Links…

Aktuell schauen wir uns gerade Open Social genauer an um zu sehen, ob wir eine Integration ins papaya CMS implementieren wollen.

In Kürze gibt es dazu hier noch ein Update mit weiteren Informationen (Argumente pro/contra, technische Bedenken/Probleme etc.) und nicht zuletzt unserer Entscheidung. Bis dahin hier schonmal einige Informationsfragmente und Links zum Thema, die wir bei der Recherche lesenswert fanden:

Open Social – was ist das, worum geht es?

Ein guter Einstieg ist ja oftmals Wikipedia, wo natürlich auch zu OpenSocial ein umfangreicher Artikel zur Verfügung steht. Hierin fasst man das Thema mit folgenden Zeilen zusammen:

OpenSocial ist eine Menge von Programmierschnittstellen für Anwendungen in webbasierten sozialen Netzwerken. OpenSocial wird von Google entwickelt und wurde am 1. November 2007 veröffentlicht.

Anwendungen, welche die OpenSocial-API nutzen, sind mit jedem anderen sozialen Netzwerk interoperabel, welches dieses auch unterstützt, so können Funktionen von Seiten wie MySpace und Friendster miteinander verknüpft werden. Zum Start von OpenSocial sind aus Deutschland lediglich das Business Netzwerk XING und der Einladungs- und Ticketservice amiando dabei.

Die Technologie basiert weitgehend auf offenen Standards wie HTML und JavaScript. OpenSocial unterstützt vier APIs für social software-Anwendungen für den Datenzugriff und Kernfunktionen teilnehmender sozialer Netzwerke. Jede API zielt auf unterschiedliche Aufgaben: eine generelle Javascript-API, eine für Menschen (Menschen und deren Beziehungen), eine für Aktivitäten (Veröffentlichungen) und eine für Single Sign-On.

Weitere Informationen

Näheres speziell zur Idee des ganzen und zur Technik gibt es auf der Website des Projektes bei code.google.com. Dort gibt es auch eine Liste der Unternehmen bzw. der Portale, die Open Social bereits einsetzen (oder sich zumindest dazu bekannt haben, es einbauen zu wollen).

Videos / Präsentationen / Tutorials zum Thema

Google hat natürlich eine Youtube Playlist mit diversen Videos zu OpenSocial:

FAQs zu OpenSocial

Die folgenden Punkte sind auch der Google-Website entnommen, ich habe mal die meines Erachtens wichtigsten FAQ Einträge übernommen:

What is the basic architecture of a social application that uses the OpenSocial API?
OpenSocial applications use Google’s gadget architecture but with extensions that provide programmatic access to social data within its container environment. Similar to gadgets, OpenSocial apps are hosted XML documents with HTML/JavaScript within their bodies. Social apps have most of the infrastructure of gadgets available to them but with a few minor exceptions.

Where do OpenSocial apps run?
One of the initial environments for social apps which use the OpenSocial APIs is Orkut. Other OpenSocial enabled websites are expected to launch support for developers soon.

How do I create social apps using OpenSocial?
Social apps are initially created in the same manner as gadgets: with your favorite text editor or within the Google Gadgets Editor. They then can be augmented with the OpenSocial JavaScript APIs, where they can fetch and post social data about friends and activities.

Does OpenSocial require any special markup languages or plug-ins?
No. OpenSocial uses standard JavaScript, HTML, and XML.

What resources do I need to create an OpenSocial gadget?
Other than a good idea and a few minutes to write JavaScript and HTML, you don’t need any. Google will do all the hosting for you if you want, but you are also free to use your own servers.

Can OpenSocial apps use Flash?
Yes. Similar to gadgets, it is possible to embed Flash content into a social app.

Can OpenSocial apps interact with other websites?
Yes, social apps have the ability to fully interact with outside 3rd party applications using standard web protocols.

What other JavaScript libraries can I use?
All of them! Dojo, Prototype, JQuery, GWT, etc.

What languages can I use on my server?
All of them! PHP, Ruby on Rails, Java, etc.

Das hört sich spannend an – wie startet man am besten?

Genauer ansehen muss man sich dazu folgende Seiten:

Bevor man sich die ganzen Links im Detail ansieht, macht dieses Video auf jeden Fall Sinn – hierin werden die für OpenSocial verfügbaren Ressourcen kurz vorgestellt:

Medium: www.youtube.com
Link: www.youtube.com

Lesenswerte Blogartikel anderer zum Thema OpenSocial

Fazit

Wie eingangs bemerkt ist es noch zu früh für ein wirkliches Fazit – spannend auf jeden Fall, ob das technisch so gut und ausgereift ist, dass wir darauf aufsetzen wollen, gilt es noch zu klären. Später mehr dazu…

Update / Ergänzung (2008-10-31)

Eine sehr lesenswerte Ausführung zum eng verwandten Thema „Open ID“ / „OpenID“ habe ich gerade bei Pixelsebi.com gefunden – zu dem Thema werde ich hier im Blog auch nochmal nachlegen 😉

Update / Ergänzung (2008-11-17)

Deployment mit Capistrano

Alexander machte mich auf ein recht spannendes Tool aufmerksam: Capistrano. Das ist, ganz kurz zusammengefasst, eine RubyOnRails Anwendung zur Ausführung von Tasks auf einem entfernten Server und könnte ein paar selbstgebaute Shellscripts entweder ergänzen oder ersetzen. Hier mal die Eingangsbeschreibung von deren Website: Great for automating tasks via SSH on remote servers, like software installation, application deployment, configuration management, ad hoc server monitoring, and more.”

Der Tipp von Alexander zielte vor allem auf das Deployment ab (”Dort gibt es eine Software namens Capistrano http://www.capify.org/, welche es erlaubt per Ruby aus dem SVN Projekte auf mehrere Server zu verteilen und notfalls auch ein Rollback basierend auf verschiedenen Versionsnummer zu machen.“). Und das könnte in der Tat sehr interessant sein, schaue ich mir nochmal genauer an und berichte dann.

papaya Entwicklung: XSL Templates für Content Module

In einigen Fällen stellt sich dem Template-Programmierer die Frage, wie die Inhalte unter /page/content/topic ausgegeben werden sollen. Grundsätzlich stehen drei verschiedene Wege zur Verfügung:

  • <xsl:apply-templates> oder <xsl:call-template>
  • <xsl:value-of>
  • <xsl:copy-of>

Die erste Variante führt weitere Templates auf, die den Teilbaum in /page/content/topic weiterverarbeiten, wobei man mit call-template direkt ein bestimmtes Template aufrufen kann. Mit value-of gibt man lediglich alle Textknoten in die Ausgabe aus, die im referenzierten Teilbaum enthalten sind, während copy-of den gesamten Teilbaum in die Ausgabe kopiert.

Wann nimmt man was?

Welche Variante sollte man denn nun benutzen? Alle Methoden haben ihre Vor- und Nachteile.

1. value-of

Mit value-of erzeugt man sichere Ausgaben, da alle Formatierungen aus Texteingabefeldern entfernt werden. Besonders bei user-generiertem Content ist dies eine sehr einfache Methode, um Manipulationen zu verhindern. Auch Inhalte, die im Backend eingegeben werden, können auf diese Weise sauber gehalten werden.

Der Nachteil dieser Methode ist jedoch, dass man sie nicht überall einsetzen kann, wo man Formatierungen wie <h2>, <em>, <strong> usw. einsetzen will. Auch Hyperlinks gehen natürlich verloren. Für umfangreiche strukturierte Inhalte sollte man also diesen Weg nicht gehen.

2. copy-of

copy-of hat den Vorteil, dass alle Formatierungen und inhaltlichen Strukturierungen (<h1-6>) mit in die Ausgabe übernommen werden, genauso wie Hyperlinks, was durchaus erwünscht sein kann. Schließlich möchte man als Redakteur Artikel schreiben, die in Absätzen strukturiert sind, Zwischenüberschriften oder Links zu anderen Ressourcen enthalten.

Der Nachteil dieser Methode ist, dass man die Kontrolle über den Teilbaum aus den Händen gibt. Er wird ja einfach in die Ausgabe kopiert. Daher sollte man diese Anweisung auch nicht für user-generierten Content benutzen, der bösen Code enthalten könnte.

“Böser Code” kann zum Teil auch durch Sonderzeichenmaskierung (=Escaping) in der Methode getParsedData() in der Content-Modul-Klasse entschärft werden, indem man bspw. papaya_strings::escapeHTMLChars($myStringVar) benutzt (siehe auch $this->getXHTMLString()).

3. apply-templates oder call-template

Mit apply-templates kann man komplexe Strukturen innerhalb von /page/content/topic an zusätzliche XSLT-Templates zur Verarbeitung weiterdelegieren. Die Anweisung sucht dabei ein Template, dessen match-Muster am besten zum jeweiligen Element in der Knotenmenge des Kontextknotens passt. Für jeden Knoten im Kontextknoten wird also ein Template anzuwenden versucht. Falls es kein passendes Template gibt, wird einfach der entsprechende Textknoten ausgegeben. Wenn das select-Attribut benutzt wird, versucht XSLT, ein Template für jeden in select definierten Knotenmengenausdruck anzuwenden.

Diese Anweisung hat den Nachteil, dass sie nicht besonders performant ist, da der gesamte Teilbaum durchsucht wird. XSLT versucht dabei, für jeden Knoten das richtige Tempate zu finden.

Nach Möglichkeit sollte man also Templates direkt auswählen, indem man call-template benutzt und den gewünschten Teilbaum des Kontextknotens als Parameter übergibt. Auf diese Weise hat man auch die volle Kontrolle darüber, welches Template benutzt wird und welche Transformation angewendet werden soll.

Bei den aufzurufenden Templates steht man natürlich wieder vor der Wahl, ob man jetzt value-of oder copy-of benutzen soll. Wenn es sich um Inhalte handelt, die man im Backend in einzeilige Textfelder eingibt, wird man mit Sicherheit value-of benutzen, bei mehrzeiligen Textfeldern, die auch HTML-Eingabe erlauben, muss man auch copy-of benutzen, damit der HTML-Code auch in der Ausgabe landet. Um die Eingabe von HTML-Code oder sonstiges zu verhindern, sollte man die Content-Module so schreiben, dass entsprechende Validitätschecks bereits während der Eingabe im Backend den Inhalt überprüfen. Validitätschecks sollten also nicht die Aufgabe des Template-Programmierers sein.

(Credits: Text entstammt dem internen papaya-Blog und wurde von Max verfasst.)