Anzeige
Anzeige
UX & Design
Artikel merken

Neue Template-Eingine für FLOW3 und TYPO3 4.x: Fluid – Templating leicht gemacht

Mit Fluid steht TYPO3-Entwicklern ab Version 4.3 eine neue Template-Engine zur Verfügung, die auch Bestandteil von FLOW3 ist. Sie ist leicht zu lernen, sehr flexibel und extrem erweiterbar. Der folgende Artikel erläutert Grundlagen und stellt die Konzepte hinter Fluid vor.

4 Min. Lesezeit
Anzeige
Anzeige

TYPO3-Entwickler setzen beim Thema Templating meist auf die populäre markerbasierte Variante, die schon sehr lange fester Bestandteil von TYPO3 ist. Andere haben bereits mit Smarty, PHPTAL oder anderen Template-Engines gearbeitet und fragen sich nun womöglich, weshalb es noch einer weiteren Template-Engine bedarf. Ein Beispiel zur Ausgabe einer Liste von Blogposts soll verdeutlichen, woran es bislang hakt:

Klassisches Templating
// Im Template

###CONTENTS###
<ul>
###SUBELEMENT###
    <li>###TITLE###</li>
###SUBELEMENT###
</ul>
###CONTENTS###

// in PHP

$subEl = getSubpart(“SUBELEMENT“);
$out = ‘‘; foreach ($recordList as $record) {
    $out .= substituteMarker($subEl, ‘TITLE‘, $record[‘title‘]);
}
return substituteSubpart($template, ‘SUBELEMENT‘, $out);

Listing 1

Anzeige
Anzeige

Wie man sieht, ist sehr viel Code für eine einfache Aufgabe wie die Ausgabe einer Liste notwendig – außerdem existiert keine saubere Trennung zwischen Präsentations- und Anwendungslogik.

Nachdem klar war, dass TYPO3 in Zukunft eine neue Templating-Lösung benötigt, hat das Kernentwickler-Team viele verschiedene Template-Engines unter die Lupe genommen – alle hatten jedoch gemeinsame Nachteile:

Anzeige
Anzeige
  • nicht komplett objektorientiert programmiert (PHP 4)
  • komplizierte oder unlogische Syntax
  • PHP im Template erlaubt
  • mangelhafte und unsaubere Erweiterbarkeit

Hier setzt Fluid [1] an: Die Template-Engine besitzt eine neue, intuitive Syntax, die extrem flexibel und erweiterbar ist, aber trotzdem leicht erlernt werden kann. Das folgende Beispiel soll anhand eines Blogs verdeutlichen, wie effizient Entwickler mit Fluid arbeiten können.

Anzeige
Anzeige

Objekte traversieren leicht gemacht

Im Controller können Variablen mit Hilfe von „$this->view->assign(‚blogTitle‘, ‚Mein erster Blog‘);“ zugewiesen werden. Um den Inhalt einer Variablen im Template auszugeben, ist die {…}-Syntax vorhanden: {blogTitle}.

Einfache Variablenausgabe
// Im Controller:
$this->view->assign('blogTitle', 'Mein erster Blog');
// Im Template:
<h1>{blogTitle}</h1>

Listing 2

Darüber hinaus ist es möglich, sich „durch Objekte durchzuhangeln“, indem man einen Punkt verwendet: „{blog.title}“ führt zu einem Aufruf von „$blog->getTitle()“, „{post.author.name}“ analog zu „$post->getAuthor()->getName()“.

Anzeige
Anzeige
Objekte traversieren
// Im Controller:
$this->view->assign('blog', $blog);
// Im Template:
<h1>{blog.title}</h1>

Listing 3

Standard-ViewHelper nutzen

Nun wollen wir das obige Beispiel erweitern und eine Liste von Blogpostings ausgeben. Dafür greift man in Fluid auf so genannte „ViewHelper“ zurück. Im Template werden diese mit Hilfe von speziellen Tags aufgerufen. Das folgende Listing gibt alle Beiträge eines Blogs aus:

ViewHelper aufrufen
<f:for each="{blog.posts}" as="post">
	<h2>{post.title}</h2>
	<p>{post.teaser}
		<f:actionlink action="show" arguments="{post : post.uid}">mehr...</f:actionlink>
	</p>
</f:for>

Listing 4

Das spezielle Tag „<f:for>“ ist ein solcher ViewHelper. Mit ihm kann über Arrays iteriert werden, um die einzelnen Elemente auszugeben. Im obigen Beispiel gibt es noch einen zweiten ViewHelper namens „<f:actionlink>“, der verwendet wird, um einen Link auf die Detailansicht auszugeben.

Häufig benötigte ViewHelper wie Schleifen, Links, Formulare oder Localization [2] liefert Fluid mit. Jede Extension kann allerdings ihre eigenen ViewHelper definieren und nutzen.

Anzeige
Anzeige

Eigene ViewHelper

Nun soll das Blog-Beispiel noch ein wenig erweitert werden, indem ein ViewHelper für den Onlinedienst „Gravatar“ implementiert wird. Gravatar ordnet einer E-Mail-Adresse ein Avatarbild zu, sodass dieses Bild bei jedem Blogkommentar angezeigt wird, bei dem man seine E-Mail-Adresse angibt. Der ViewHelper muss also eine E-Mail-Adresse entgegen nehmen und soll dann folgende schematische Ausgabe erzeugen: „<img xsrc=“http://gravatar.com/avatar/md5($email)“ />“.

Um einen ViewHelper nutzen zu können, muss dieser zuerst importiert werden, bevor er im Template zur Verfügung steht. Der Import erfolgt mittels „{namespace blog=Tx_Blog_ViewHelpers}“. Nun können Sie ViewHelper unterhalb von „Tx_Blog_ViewHelpers“ aufrufen, indem Sie <blog:…>-Tags im Template nutzen.

Der Gravatar-ViewHelper soll über „<blog:gravatar>“ im Template angesteuert werden. Damit muss er in der Klasse „Tx_Fluid_ViewHelpers_GravatarViewHelper“ implementiert werden. Der Klassenname setzt sich zusammen aus dem Namespace, dem Namen des Tags (ohne Namespace-Prefix) und der Endung „ViewHelper“.

Anzeige
Anzeige
Verwendunng des Gravatar-ViewHelpers
{namespace blog=Tx_Blog_ViewHelpers}
<blog:gravatar email="{post.author.email}" />

Listing 5

Gravatar-ViewHelper implemetieren

Jeder ViewHelper muss von „Tx_Fluid_Core_AbstractViewHelper“ erben. Außerdem muss er eine „render“-Methode besitzen, deren Rückgabewert in die Ausgabe eingefügt wird.

Hello world als ViewHelper
class Tx_Blog_ViewHelpers_GravatarViewHelper extends Tx_Fluid_Core_AbstractViewHelper {
    public function render() {
        return 'Hello World';
    }
}

Listing 6

An der Stelle, an der im Template „<blog:gravatar />“ steht, wird nun „Hello World“ ausgegeben.
Da wir die angegebene E-Mail-Adresse benötigen, müssen wir auf die Tag-Argumente zugreifen.

Argumente müssen registriert werden

Aus Sicherheitsgründen müssen alle Argumente mit Namen und Datentyp registriert werden – das Framework übernimmt dann die Überprüfung der Argumente. Die Registrierung der Argumente ist einfach:

Anzeige
Anzeige
Argumente registrieren
/**
* @param string $email Email to look for
*/
public function render($email) {
...
}

Listing 7

Wie man sieht, werden alle Methodenargumente automatisch als Tag-Attribute registiert und stehen in der render()-Methode zur Verfügung. Ganz wichtig ist hier der Kommentarblock über dem Methodennamen, denn der Typ der Argumente (hier „string“) wird daraus entnommen. Die eigentliche Implementierung der Render-Methode ist anschließend ein Kinderspiel:

Render-Methode implementieren
class Tx_Blog_ViewHelpers_GravatarViewHelper extends Tx_Fluid_Core_AbstractViewHelper {
	/**
	* @param string $email Email to look for
	*/
	public function render($email) {
		return 'http://www.gravatar.com/avatar/' . md5(strtolower($email)) . '.jpg';
	}
}

Listing 8

Es ist übrigens auch möglich, Argumente als optional zu definieren: Geben Sie dazu einfach Standardwerte an, wie Sie es von PHP kennen:

Optionale Argumente
// Kommentarblock nicht vergessen!
public function render ($email, $imageSize = 'large') {...}

Listing 9

Fortgeschrittene Validierung

Durch die Angabe des Datentyps in „@param“ wird eine einfache Validierung durchgeführt. Leider ist diese hier nicht ausreichend. Der Nutzer kann beliebige Strings angeben, eigentlich sollen aber nur E-Mail-Adressen akzeptiert werden. Für solche Fälle gibt bietet Fluid erweiterte Validatoren, die durch den @validate-Tag verwendet werden können.

Anzeige
Anzeige
Erweiterte Validierung
/**
 * @param string $email Email of user
 * @param string $imageSize Size of the image.
 * @validate $email EmailAddressValidator
 */
public function render($email, $imageSize = 'large') {...}

Listing 10

Fazit

Als fester Bestandteil von TYPO3 4.3 und FLOW3 ermöglicht Fluid Entwicklern nicht nur flexibles und trotzdem einfaches Templating, sondern auch einen Einstieg in die Konzepte von FLOW3 und TYPO3 5.0.

Mehr zu diesem Thema
Fast fertig!

Bitte klicke auf den Link in der Bestätigungsmail, um deine Anmeldung abzuschließen.

Du willst noch weitere Infos zum Newsletter? Jetzt mehr erfahren

Anzeige
Anzeige
8 Kommentare
Bitte beachte unsere Community-Richtlinien

Wir freuen uns über kontroverse Diskussionen, die gerne auch mal hitzig geführt werden dürfen. Beleidigende, grob anstößige, rassistische und strafrechtlich relevante Äußerungen und Beiträge tolerieren wir nicht. Bitte achte darauf, dass du keine Texte veröffentlichst, für die du keine ausdrückliche Erlaubnis des Urhebers hast. Ebenfalls nicht erlaubt ist der Missbrauch der Webangebote unter t3n.de als Werbeplattform. Die Nennung von Produktnamen, Herstellern, Dienstleistern und Websites ist nur dann zulässig, wenn damit nicht vorrangig der Zweck der Werbung verfolgt wird. Wir behalten uns vor, Beiträge, die diese Regeln verletzen, zu löschen und Accounts zeitweilig oder auf Dauer zu sperren.

Trotz all dieser notwendigen Regeln: Diskutiere kontrovers, sage anderen deine Meinung, trage mit weiterführenden Informationen zum Wissensaustausch bei, aber bleibe dabei fair und respektiere die Meinung anderer. Wir wünschen Dir viel Spaß mit den Webangeboten von t3n und freuen uns auf spannende Beiträge.

Dein t3n-Team

Mirco

GENAIL! Danke für den Artikel. Das Prinzip dieser Templates, den ViewHelperl etc. kenne ich bereits vom ZendFramework, wo es grandios funktioniert. Ich hoffe doch stark, das auch der Rest vom T3-Core mit den nächsten Versionen auf MVC umgebaut wird (das soll ja mit FLOW kommen soweit ich weiß). Bleibt am Ball, danke :-)

Antworten
Steffen Müller

Die API scheint sich ein wenig verändert zu haben:

Statt
class Tx_Blog_ViewHelpers_GravatarViewHelper extends Tx_Fluid_Core_AbstractViewHelper {
muss es heißen:
class Tx_Blog_ViewHelpers_GravatarViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper {

Antworten
Sebastian Kurfürst

Hallo Steffen,

vielen Dank für die Korrektur, es wurden da noch ViewHelper in andere Positionen geschoben, da der Artikel weit vor Fluid 1.0 erschienen ist.
Jetzt, mit Fluid 1.0, erachten wir die öffentliche API als stabil an.

Viele Grüße,
Sebastian

Antworten
cialis

Hallo und danke für den nützlichen Artikel. Genau das habe ich gesucht.

Antworten
me@foo.bar

Das ist aber nicht richtig durchdacht, oder? Da habe ich ne Syntax für Variablen {} und dann noch „View-Helper“, die sich an XML anlehnen. Woher weiß denn die Variablen-Syntax, in welchem Kontext sie angewendet wird? (Also [CDATA] oder Attribut).

Schon mal nen Blick auf TAL/Metal geworfen, wie man sowas richtig macht?

http://de.wikipedia.org/wiki/Zope_Page_Templates

Antworten
ak

oh man!

die jungs vom typo3-core team können es einfach nicht lassen. ich kann bis heute nicht nachvollziehen, wieso typoscript eingeführt wurde und ich weiss auch nicht warum jetzt wieder eine neue template sprache eingeführt werden soll… jaja, ich weiß. sicherheit, die bösen themer könnten ja sonst schlechten php code in die templates schreiben… jetzt mal ehrlich: auf grundlage von php noch eine extra script sprache obendrauf zu setzen (was wieder einen entsprechenden parser benötigt) ist FÜR MICH einfach schwachsinn und nicht nachvollziehbar… echt jetzt. was soll das?? welche gründe sprechen denn gegen die verwendung von php in templates???? ok – die deutsche korrektheit vielleicht oder das engere korsett für den themer… aber ansonsten müssen entwickler wieder eine neue syntax lernen, seiten müssen doppelt geparst werden (energie-kosten schon mal dabei bedacht?) und die so komplexe web-welt wird wieder um eine neue sprache erweitert… juhuu!!! ich weiß schon warum typo3 vor allem in deutschland angewendet wird… das passt einfach zum stock im arsch und zur korrektheit ;-)

Antworten
taliah

An sich eine ganz gute Idee, nur leider nicht ganz zu Ende gedacht. Und zugegebenermaßen, was als Nachteil gehandelt wird (PHP im Template möglich) ist meines Erachtens gar keiner. Siehe TWIGG-Engine (z. B. bei Symfony 2) – funktioniert prima und man kann für etwas kniffligere Sachen auch mal einen kleinen Workaround schreiben. Ist mit FLUID leider nicht möglich, da hängt es schon an einem einfachen String-Vergleich im Template – ich muss entweder einen View-Helper schreiben, oder, wenn mir das zu blöd ist, den zu prüfenden String vorher in eine Variable packen und dann mit an das Template übergeben.
Schon irgendwie sehr seltsam sowas.
Eigentlich schade, dass nicht doch der Schritt gemacht wird, der ja schon „fast“ angedacht wurde: Einfach mal Symfony 2 mit TYPO3 verquicken. Leider kam man ja zu dem Schluss, dass doch schon zu viel Zeit in TYPO3 5 geflossen sei und man deshalb zwar Symfony 2 eigentlich gerne hätte, aber dann doch lieber selbst weiter stricken wolle. Ich kann es zwar irgendwo verstehen, dennoch glaube ich, dass die jetzige Entscheidung weit unpopulärer enden wird, als wenn man den Schlenker auf Symfony gemacht hätte. Ich als Entwickler hätte jedenfalls überhaupt nichts dagegen! ;)

Antworten
Sal Mcdonal

Its like you read my mind! You seem to know a lot about this, like you wrote the book in it or something. I think that you can do with some pics to drive the message home a little bit, but instead of that, this is magnificent blog. An excellent read. I’ll certainly be back.

Antworten

Melde dich mit deinem t3n Account an oder fülle die unteren Felder aus.

Bitte schalte deinen Adblocker für t3n.de aus!
Hallo und herzlich willkommen bei t3n!

Bitte schalte deinen Adblocker für t3n.de aus, um diesen Artikel zu lesen.

Wir sind ein unabhängiger Publisher mit einem Team von mehr als 75 fantastischen Menschen, aber ohne riesigen Konzern im Rücken. Banner und ähnliche Werbemittel sind für unsere Finanzierung sehr wichtig.

Schon jetzt und im Namen der gesamten t3n-Crew: vielen Dank für deine Unterstützung! 🙌

Deine t3n-Crew

Anleitung zur Deaktivierung
Artikel merken

Bitte melde dich an, um diesen Artikel in deiner persönlichen Merkliste auf t3n zu speichern.

Jetzt registrieren und merken

Du hast schon einen t3n-Account? Hier anmelden

oder
Auf Mastodon teilen

Gib die URL deiner Mastodon-Instanz ein, um den Artikel zu teilen.

Anzeige
Anzeige