Fluid ViewHelper Dokumentation

Warum das Ganze?

Ich bekomme immer wieder Mails, dass es im Internet keine vernünftige Dokumentation zu Fluid gibt. Viele haben immer wieder Probleme damit Übersetzungen mit HTML-Tags auf die Webseite zu transportieren. Die Suche ging in die Stunden. Für uns Programmierer kein Thema: Wir gehen in den Quellcode der Fluid-ViewHelper und ziehen uns die benötigten Daten direkt aus dem Quellcode. Viele ziehen sich die Informationen auch aus dem CheatSheet von Patrick Lobacher sofern sie denn überhaupt wissen was htmlEscape und Kollegen machen. In den Büchern wird gerade mal mit nem Satz oder Zwei auf einen Parameter eingegangen. Wenn überhaupt. Hinzu kommt, dass gefühlte 20 neue ViewHelper in der 4.6er Version hinzugekommen sind. Die sind in den Büchern noch gar nicht dokumentiert. Auch die Inlinenotation  ist nur geringfügig erklärt und Beispiele gibt es nur in den Kommentaren des ViewHelper-Quelltextes.

Kein Wunder, dass sich die Postfächer mit Fragen füllen. Ich habe heute (14.04.2012) damit angefangen eine öffentliche ViewHelper-Dokumentation zu schreiben und kann nur hoffen, dass die Fragen bald über Google gefunden werden und die Postfächer überschaubar bleiben.

Um konstruktive Kritik/Lob/Fehler wird gebeten.

f:alias Seit TYPO3 4.3

Parameter

ParameterErklärung
map

Die Eingabe erfolgt in Arraynotation. Der Key gibt den Namen der neuen Variable wieder, während der Wert den Inhalt wieder spiegelt.

Mit diesem ViewHelper könnt Ihr eigene Variablen innerhalb des öffnenden und schließenden Tags zur Verfügung stellen. Das ist sinnvoll, wenn Ihr einen bestimmten Wert (z.B. aus Objekten) oder eine etwas längere ViewHelper Aneinanderreihung in Eurem Template mehrfach wieder verwenden wollt.

Beispiel für einfache Texte

<f:alias map="{vorname: 'Stefan', nachname: 'Froemken'}">
 <p>Hallo zusammen,<br />mein Name ist {vorname} {nachname}</p>
</f:alias>

Beispiel für selbst erstellte Arrays

Dieses Beispiel ist vielleicht wenig sinnvoll, aber es zeigt sehr gut, wie man innerhalb von Fluid mehrdimensionale Arrays erstellen kann.

<f:alias map="{company: {name: 'Mueller und Co.', mitarbeiter: {0: {name: 'Stefan'}, 1: {name: 'Petra'}}}}">
 <p>Wir, die Firma {company.name}, haben folgende Mitarbeiter:</p>
 <ul>
 <f:for each="{company.mitarbeiter}" as="mitarbeiter">
 <li>{mitarbeiter.name}</li>
 </f:for>
 </ul>
</f:alias>

Beispiel für Werte aus Objekten

Dieses Beispiel funktioniert nur, wenn Ihr das feUser-Objekt in Eurer Extension per $this->view->assign() verfügbar gemacht habt.

<f:alias map="{vorname: feUser.firstName, nachname: feUser.lastName}">
 <p>Hallo zusammen,<br />mein Name ist {vorname} {nachname}</p>
</f:alias>

f:base Seit TYPO3 4.3

Dieser ViewHelper macht nur dann Sinn, wenn Ihr Eure komplette Webseite (inkl. Headerbereich) mit Hilfe von Fluid aufbaut. Ansonsten würde dieser Tag immer im Bodybereich der Webseite erstellt werden, wo er keinen Sinn macht bzw. nicht hingehört.

Beispiel

Es gibt keine Parameter für diesen ViewHelper, daher bleibt es bei diesem kurzen Beispiel.

<f:base />

Die Ausgabe im Quelltext könnte wie folgt aussehen:

<base href="https://www.typo3lexikon.de/" />

f:case Seit TYPO3 6.2

ParameterErklärung
valueDer Inhalt des f:case ViewHelpers wird nur dann angezeigt, wenn der Wert von value dem expression-Argument aus dem f:switch ViewHelper übereinstimmt.
defaultEin f:case ViewHelper, bei dem default aktiviert wurde, wird immer dann angezeigt, wenn kein anderer f:case ViewHelper zu der expression des f:switch ViewHelpers passt.

Ein Beispiel findet Ihr beim f:switch ViewHelper

f:cObject Seit TYPO3 4.3

ParameterErklärungPflichtfeld

typoscriptObjectPath

Gebt hier den TypoScript Objektpfad an wie z.B. lib.beispieldaten.10Ja

data

Hiermit könnt Ihr dem TypoScript Objektpfad noch ein paar Daten mit auf den Weg geben. Handelt es sich dabei um ein Objekt oder ein Array, dann könnt Ihr mit Hilfe von "field" auf die Werte der Keys/Schlüssel zugreifen. Handelt es sich um einen Text oder eine Zahl, dann wird der Wert über "current" verfügbar gemacht. 

currentValueKey

Wenn im Bereich "data" mit Arrays oder Objekte gearbeitet wird, dann kann man mit diesem Parameter angeben, welcher Wert eines Schlüssels über "current" verfügbar gemacht werden soll. 

Das ist in meinen Augen ein sehr mächtiger ViewHelper, da Ihr hiermit die geballte Ladung von TypoScript zur Verfügung habt. Nähere Erläuterungen in den Beispielen:

Einfaches Beispiel

im TypoScript (das statische Template von css_styled_content muss eingebunden sein):

lib.content < styles.content.get

Im Fluidtemplate dann

<f:cObject typoscriptObjectPath="lib.content" />

Mit diesem einfachen Beispiel werden alle tt_content-Datensätze der aktuellen Seite ausgegeben

Beispiel mit Text zwischen den Tags

Im TypoScript:

lib.content = TEXT
lib.content {
  value.current = 1
  value.wrap = <p>Das ist der Text zwischen den Tags<br />|</p>
}

im Fluidtemplate

<f:cObject typoscriptObjectPath="lib.content">
    Stefan heisst Euch willkommen
</f:cObject>

oder auch:

<f:cObject typoscriptObjectPath="lib.content" data="Stefan heisst Euch willkommen" />

Der ViewHelper erkennt, dass Ihr nur Text eingetragen habt. In diesem Falle wird dieser mit Hilfe von "current = 1" im TS zur Verfügung gestellt.

Beispiel mit einem Array/Objekt

Falls kein Array oder Objekt zur Hand, dann machen wir uns eins:

<f:cObject typoscriptObjectPath="lib.content" data="{vorname: 'Stefan', nachname: 'Froemken'}" currentValueKey="nachname" />

Wenn Ihr ein Objekt oder Array habt, dann reicht natürlich diese Form:

<f:cObject typoscriptObjectPath="lib.content" data="{feUser}" currentValueKey="lastName" />

Das TS könnte dann so aussehen:

lib.content = COA
lib.content {
  10 = TEXT
  10.value.current = 1
  10.value.wrap = <p>Nachname: |</p>
  20 = TEXT
  20.value.dataWrap = Vollständiger Name: {field: vorname} {field: nachname}
}

Wie oben schon erwähnt könnt Ihr mit currentValueKey angeben, welcher Wert aus dem Array oder Objekt über current=1 zur Verfügung gestellt werden soll. Auf die anderen Werte eines Arrays oder Objektes könnt Ihr dann wie hier im Beispiel mit "field" zugreifen.

f:comment Seit TYPO3 4.6

Für diesen ViewHelper gibt es keinen Parameter. Alles was sich innerhalb der Tags befindet, wird schlichtweg entfernt. Andere enthaltene ViewHelper werden auch nicht ausgeführt. Dieser ViewHelper ist schon mal sinnvoll zum Debuggen der Webseite. So kann man z.B. f:for-Schleifen damit temporär ausblenden, um Fehlersuchen auf das Wesentliche zu beschränken.

Beispiel

<f:alias map="{vorname: 'Stefan'}">
    <f:comment>
        <p>Dieser Text wird nicht angezeigt</p>
        <p>Mein Name ist: {vorname}</p>
    </f:comment>
    <p>{vorname} wohnt in Lindlar</p>
    <![CDATA[<p>{vorname} wohnt in Lindlar</p>]]>
</f:alias>

Alles zwischen den f:comment-Tags wird überhaupt nicht gerendert, angezeigt oder überhaupt auch nur verarbeitet. Die Sache mit "Stefan wohnt in Lindlar" wird ganz normal angezeigt. Die letzte Zeile wird allerdings nochmal interessant. Denn mit Hilfe dieser CDATA-Notation könnt Ihr Euch den original Quelltext wie im Fluidtemplate anzeigen lassen.

f:count Seit TYPO3 4.3

ParameterErklärung

subject

Gebt hier das Array oder Objekt an, das gezählt werden soll. Wenn dieser Wert leergelassen wird, wird versucht, den Inhalt zwischen den Tags zu zählen

Dieser ViewHelper zählt Arrayelemente oder Inhalte in einem Objekt

Beispiel mit Inhalt zwischen den Tags

<f:alias map="{mitarbeiter: {0: 'Stefan',1: 'Petra',2: 'Sascha'}}">
    <p>Bei uns arbeiten <f:count>{mitarbeiter}</f:count> Mitarbeiter</p>
</f:alias>

Beispiel unter Verwendung von subject

<f:alias map="{mitarbeiter: {0: 'Stefan',1: 'Petra',2: 'Sascha'}}">
    <p>Bei uns arbeiten <f:count subject="{mitarbeiter}" /> Mitarbeiter</p>
</f:alias>

Beispiel als Inlinenotation

<f:alias map="{mitarbeiter: {0: 'Stefan',1: 'Petra',2: 'Sascha'}}">
    <p>Bei uns arbeiten {f:count(subject: mitarbeiter)} Mitarbeiter</p>
</f:alias>

Beispiel als Inlinenotation extrem

<f:alias map="{mitarbeiter: {0: 'Stefan',1: 'Petra',2: 'Sascha'}}">
    <p>Bei uns arbeiten {mitarbeiter -> f:count()} Mitarbeiter</p>
</f:alias>

f:cycle Seit TYPO3 4.3

ParameterErklärung
values

Eingabe als Arraynotation. Erläuterung im Beispiel

as

Gebt hier den Namen der neuen Variable an

Sobald Ihr anfangt Fluid zur Listengenerierung zu verwenden, dann wird auch dieser ViewHelper zu Eurem Liebling. Listen werden bei Fluid mit f:for generiert. Aber diese Ausgabe ist sehr statisch. Man kann evtl. nur auf das erste und letzte Element Zugriff nehmen. Aber um jeder dritten Zeile ein anderes Aussehen zu verpassen benötigen wir diesen f:cycle ViewHelper.

Beispiel

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
    <table cellpadding="5" cellspacing="0" border="2">
        <f:for each="{mitarbeiter}" as="kollege">
            <f:cycle values="{0: 'green', 1: 'red', 2: 'blue'}" as="color">
                <tr>
                    <td style="color: {color}">{kollege.vorname}</td>
                    <td style="color: {color}">{kollege.stadt}</td>
                </tr>
            </f:cycle>
        </f:for>
    </table>
</f:alias>

Mit Hilfe von f:alias habe ich eine Variable mit 6 Einträgen erzeugt. Diese Einträge lasse ich mit f:for durchlaufen. f:cycle schaut jetzt nach, ob es sich um den ersten Eintrag handelt. Wenn ja, dann weise der Variable "color" den Wert aus dem ersten Arrayelement zu. In diesem Fall "green". Beim zweiten Durchlauf erhält die Variable "red" und zu guter Letzt "blue". Sind wir im Vierten Durchlauf, wird wieder mit dem ersten Element von f:cycle angefangen "green" und so weiter. Auf diese Weise erhalten wir eine Tabelle mit immer drei abwechselnden Farben.

f:debug Seit TYPO3 4.3

ParameterErklärungVersion

title

Gibt der Debugausgabe einen Titel. Bei mehreren Debugausgaben könnt Ihr so die jeweiligen Ausgaben besser unterscheiden.

 
maxDepthDas Rendern von Objekten kann sehr groß werden und schnell das PHP MemoryLimit sprengen. Deshalb könnt Ihr hier die maximale Objekttiefe angeben.ab TYPO3 4.7
plainTextAnstatt einer HTML/JavaScript Ausgabe könnt Ihr die Ausgabe auch komplett als reinen Text ausgeben lassen.

ab TYPO3 4.7

ansiColorsWenn plainText aktiv ist, könnt Ihr mit ansiColors die Textausgabe mit etwas Farbe aufhübschen

ab TYPO3 4.7

inlineNormalerweise klebt die HTML Debugausgabe oben am Browserrand. Wenn Ihr diese Eigenschaft aktiviert, findet die Ausgabe genau dort statt, wo der f:debug ViewHelper verwendet wird.

ab TYPO3 4.7

blacklistedClassNames

Einige Klassen werden bei der Debugausgabe sehr groß. So z.B. der ObjectManager oder diverse ObjectStorages. Wenn Ihr diese Objekte in der Ausgabe nicht benötigt, dann könnt Ihr diese Objekte hiermit von der Ausgabe ausschließen

ab TYPO3 4.7

blacklistedPropertyNames

Ähnlich wie blacklistedClassNames, nur mit dem Unterschied, dass hiermit bestimmte Eigenschaften von der Debugausgabe ausgeschlossen werden.

ab TYPO3 4.7

Falls eine Eurer Variablen wieder erwartend nichts ausgeben sollte, könnt Ihr mit Hilfe diesen ViewHelpers Euch komplette Arrays und unter bestimmten Voraussetzungen auch ganze Objekte anzeigen lassen. In der Ausgabe seht Ihr dann, ob Euer gewünschter Wert überhaupt gefüllt ist oder nicht.

Objekte sind teilweise so groß, dass sie einfach den Rahmen sprengen. Sie bestehen teilweise aus mehreren 10.000 Zeilen vielleicht auch aus 100.000. Auf jeden Fall sind sie teilweise so groß dass der Browser schon mal abkachelt. Bitte konvertiert in diesem Fall Eure Objekt vorher in ein Array ($result->toArray()). Dann klappts auch mit der Debugausgabe.

Beispiel

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
    <f:debug title="Mitarbeiter">{mitarbeiter}</f:debug>
</f:alias>

f:else Seit TYPO3 4.3

Diesen ViewHelper erkläre ich im Bereich f:if, da er nur dort verwendet werden kann.

Seit TYPO3 8.0 gibt es für diesen ViewHelper den if-Parameter, mit dem sich else-if Strukturen abbilden lassen.

f:escape Seit TYPO3 4.4. Veraltet seit 4.6. Entfernt mit TYPO3 6.0

Diesen ViewHelper gibt es nicht mehr. Bitte verwendet einen der f:format.* ViewHelper.

f:flashMessages Seit TYPO3 4.4

ParameterErklärungVersion

renderMode

Sollen die Fehlermeldungen als Liste ul oder als Container div gerendert werden.

seit TYPO3 4.4, veraltet seit TYPO3 7.3, entfernt in TYPO3 8.0

asDa seit TYPO3 7.6 dieser ViewHelper nur noch als div-Tag gerendert wird, müsst Ihr diesen Parameter verwenden, wenn Ihr die Ausgabe nach Euren eigenen Vorstellungen rendern lassen wolltseit TYPO3 7.3

queueIdentifier

Alle Benachrichtigungen einer Extension landen normalerweise in einer Warteschlange mit dem Namen extbase.flashmessages.[extension]_[plugin]. Da Ihr aber auch eigene Namen vergeben könnt, war es bisher nicht möglich diese im Frontend rendern zu lassen. Dieser Parameter schafft Abhilfe.seit TYPO3 7.6

Dieser ViewHelper macht nur im Bereich selbstprogrammierter Extensions Sinn. Denn nur hier können Fehler auftauchen, die dem Webseitenbesucher mitgeteilt werden müssen. Hat der User z.B. bei einem Loginformular seinen Usernamen vergessen anzugeben und die dafür zuständige Action-Methode wurde so programmiert, dass der Username eine Pflichtangabe ist, dann wird dies dem Validator gemeldet, der daraufhin eine errorAction-Methode aufruft, die dann wiederum Fehlermeldungen zuerst sammelt und dann als "Bündel" an der Stelle ausgibt, an der Ihr diesen ViewHelper platziert habt.

Seit TYPO3 8.6 gibt es den FlashMessageRenderResolver. Immer dann, wenn der as-Parameter nicht angegeben wurde, springt dieser ein und rendert die Benachrichtigungen je nach Kontext. Im Backend findet also eine andere Ausgabe statt als im Frontend und nochmals anders, wenn die Ausgabe im CLI erfolgt.

Beispiel (Ausgabe als div)

<f:flashMessages />

Beispiel für eigenes Rendering

<f:flashMessages as="flashMessages">
  <dl class="bg-info">
    <f:for each="{flashMessages}" as="flashMessage">
      <dt>{flashMessage.code}</dt>
      <dd>{flashMessage.message}</dd>
    </f:for>
  </dl>
</f:flashMessages>

f:for Seit TYPO3 4.3

ParameterErklärung

each

Array oder Objekt, das durchlaufen werden soll

as

Ein Variablenname, der Daten des aktuellen Durchlaufs enthält

key

Falls Ihr den Key/Schlüssel des aktuellen Durchlaufes benötigt, könnt Ihr hiermit den Namen einer weiteren Variable definieren

reverse

Der Durchlauf des Arrays oder Objektes geschieht rückwärts

iteration

Eine Arrayvariable, die Informationen darüber beinhaltet, ob man sich im ersten oder letzten Durchlauf befindet. Außerdem enthalten: index, cycle, total, isEven, isOdd

Der f:for-ViewHelper ist DER ViewHelper für die Listengeneration. Schaut Euch die Erläuterung in den Beispielen an.

Einfaches Beispiel

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
    <table cellpadding="5" cellspacing="0" border="2">
        <f:for each="{mitarbeiter}" as="kollege">
            <tr>
                <td>{kollege.vorname}</td>
                <td>{kollege.stadt}</td>
            </tr>
        </f:for>
    </table>
</f:alias>

Ich weise der Variable mitarbeiter 6 Einträge zu, die dann eins nach dem Anderen von f:for durchlaufen werden. Mit jedem Durchlauf wird eine weitere Tabellenzeile erstellt.

Beispiel für rückwärts

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
    <table cellpadding="5" cellspacing="0" border="2">
        <f:for each="{mitarbeiter}" as="kollege" reverse="1">
            <tr>
                <td>{kollege.vorname}</td>
                <td>{kollege.stadt}</td>
            </tr>
        </f:for>
    </table>
</f:alias>

Zu Info: Man könnte bei dem Parameter reverse auch TRUE statt 1 verwenden.

Beispiel mit key/Schlüssel

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
    <table cellpadding="5" cellspacing="0" border="2">
        <f:for each="{mitarbeiter}" as="kollege" reverse="1" key="eintrag">
            <tr>
                <th colspan="2">Eintrag: {eintrag}</th>
            </tr>
            <tr>
                <td>{kollege.vorname}</td>
                <td>{kollege.stadt}</td>
            </tr>
        </f:for>
    </table>
</f:alias>

Ich weiß, das ist jetzt nicht das beste Beispiel, aber Ihr seht, wie ich mit Hilfe des key-Parameters auf die keys der jeweiligen Einträge zugreifen kann.

Beispiel mit Durchlaufinformationen

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
 <table cellpadding="5" cellspacing="0" border="2">
 <f:for each="{mitarbeiter}" as="kollege" iteration="iterator">
 <f:if condition="{iterator.isFirst}">
 <tr><th colspan="2">Los gehts</th></tr>
 </f:if>
 <tr>
 <td>Durchlauf beginnend bei 0: {iterator.index}</td>
 <td>Durchlauf beginnend bei 1: {iterator.cycle}</td>
 <td{f:if(condition:iterator.isOdd, then: ' style="color: green;"')}>{kollege.vorname}</td>
 <td{f:if(condition:iterator.isEven, then: ' style="color: red;"')}>{kollege.stadt}</td>
 </tr>
 <f:if condition="{iterator.isLast}">
 <tr><th colspan="2">Eintraege: {iterator.total}</th></tr>
 </f:if>
 </f:for>
 </table>
</f:alias>

iterator.cycle ist genau wie iterator.index einfach nur ein Zähler und hat nichts mit dem ViewHelper f:cycle zu tun. Dieses Beispiel zeigt die Verwendung aller Durchlaufinformationen. Auch wenn Ihr den f:if-ViewHelper noch nicht kennengelernt haben solltet, so sollte dieses Beispiel selbsterklärend sein. Probierts mal aus.

f:form Seit TYPO3 4.3

ParameterErklärung 

action

Welche Actionmethode soll aufgerufen werden, wenn das Formular abgesendet wird

 

arguments

Welche zusätzlichen Variablen sollen beim Absenden mit übergeben werden

fds

controller

Falls sich die gewünschte Actionmethode nicht im gleichen Controller befindet, muss hier dieser entsprechende Controller angegeben werden

 

extensionName

Falls das Formular von einer anderen Extension abgearbeitet werden soll, dann muss hier der Extensionname ohne tx_ und ohne Unterstriche angegeben werden

 

pluginName

Falls das Formular von einem anderen Plugin abgearbeitet werden soll, dann muss hier der Pluginname angegeben werden

 

pageUid

Seiten-UID eintragen, wenn das Formular von einer anderen Seite aus abgearbeitet werden soll

 

object

Übergebt hier ein Objekt mit Eigenschaften, die die Eingabefelder im Formular wiederspiegeln.

 

pageType

Gebt hier eine Seitentyp ID an, die das Formular abarbeiten soll. Könnte für AJAX interessant sein.

 

noCache

Kann aktiviert werden, um das Caching für die Zielseite zu deaktivieren.

 

noCacheHash

Nach Aktivierung wird dem generierten Link zur Zielseite kein cHash-Parameter angehangen

 

section

Definition eines Ankers zu dem auf der Zielseite gesprungen werden soll. Interessant wir Seiten auf denen viele Inhalte sind.

 

format

Gibt an um welches Format es sich bei der Zielseite handelt. Alternativ ginge auch "xml", obwohl das bei einer Formularzielseite wenig Sinn machen würde. Klappt nur wenn actionUri nicht gesetzt ist.

 

additionalParams

Fügt weitere Variablen der Zielseite an. Im Gegensatz zu arguments, können hiermit Variablen hinzugefügt werden die nicht mit dem Extensionnamen geprefixed werden. Klappt nur wenn actionUri nicht gesetzt ist.

 

absolute

Nach Aktivierung wird der Zeilseite noch der Domainname und Pfad vorangestellt. Klappt nur wenn actionUri nicht gesetzt ist.

 

addQueryString

Falls dem Formular bereits Parameter über die URL mitgegeben wurden, könnt Ihr hier entscheiden, ob diese Parameter auch mit auf die Zielseite übergeben werden. Klappt nur wenn actionUri nicht gesetzt ist.

 

argumentsToBeExcludedFromQueryString

Falls Ihr addQueryString aktiviert habt, aber einen oder zwei bestimmte Parameter wieder entfernen wollt, dann tragt Ihr hier diese Parameter ein. Klappt nur wenn actionUri nicht gesetzt ist.

 
addQueryStringMethodNormalerweise werden nur die GET Parameter bei Verwendung von addQueryString an die Zielseite angehangen. Dieser Parameter erlaubt 4 Werte. GET: Standard. Die GET-Parameter werden übergeben. POST: Die POST Parameter werden mit übergeben. GET,POST: GET-Parameter sind die Basis und werden mit POST Parametern überschrieben, sofern beide Methoden gleichnamige Parameter beinhalten. POST,GET: POST-Parameter werden mit GET-Parametern überschrieben.Seit TYPO3 7.6

fieldNamePrefix

Falls ein anderer Prefix gewünscht ist. Macht eigentlich nur Sinn, wenn die Formulardaten von einer anderen Extension abgearbeitet werden müssen.

 

actionUri

Gebt hier Eure ganz eigene individuelle Zielseiten-URL ein. Viele der oberen Parameter haben aber dann keinen Wirkung mehr.

 

objectName

Hier kommt ein Objekt- bzw. Modelname rein, in das die nach Absenden gesammelten Formulardaten gespeichert werden sollen. Hat den Vorteil, dass Ihr nicht in jeder Action die Formulardaten überprüfen, sondern die Überprüfung nur einmalig im Model vornehmen müsst.

 
hiddenFieldClassNameDer f:form ViewHelper rendert ein paar hidden Felder, um z.B. eine Liste über die erlaubten Formularfelder zu generieren oder auch die Action zu kennen, die dieses Formular rendern lässt. Mit diesem Parameter könnt Ihr dem div-Tag, der diese hidden Felder enthält explizit setzen.Seit TYPO3 4.7

Der f:form-ViewHelper schaut von seinen ganzen Parametern extremst gewaltig aus. Aber wenn man mal bedenkt das allein 11 Parameter nur für die Generierung der Zielseiten-URL zuständig sind, bleibt nur noch eine handvoll Parameter übrig. Der große Vorteil diesen ViewHelpers ist Sicherheit und Arbeitserleichterung, die wir uns in den Beispielen mal näher anschauen.

Beispiel

<f:form object="{feUser}" objectName="newFeUser">
    <f:form.textarea property="firstName" rows="5" cols="50" />
</f:form>

Ich hab grad meinen Rechner frisch aufgesetzt und hab leider noch keine Extension hier mit der ich das testen konnte. Deshalb schaut das Ergebnis im FE-Quelltext ein bisschen "unnormal" aus:

<form action="/typo3_46/index.php?id=6&amp;tx__%5Bcontroller%5D=Standard&amp;cHash=d1469ddb628871564f3257920c1f6ee8" method="post"> <div style="display: none"> <input type="hidden" name="__referrer[extensionName]" value="" /> <input type="hidden" name="__referrer[controllerName]" value="Standard" /> <input type="hidden" name="__referrer[actionName]" value="index" /> <input type="hidden" name="__hmac" value="a:2:{s:9:&quot;newFeUser&quot;;a:1:{s:9:&quot;firstName&quot;;i:1;}s:4:&quot;tx__&quot;;a:1:{s:10:&quot;controller&quot;;i:1;}}ff5ff9b62f7b5c49a696d3f7b1009991853d6533" /> </div> <textarea rows="5" cols="50" name="newFeUser[firstName]"></textarea> </form>

Hier seht Ihr das Thema Sicherheit. Fluid baut automatisch einen versteckten Bereich mit ein paar Werten in Euer Formular ein. Unteranderem befindet sich dort ein __hmac-Wert. Innerhalb diesen Wertes sind alle erlaubten Formularfelder nochmals enthalten. Wenn also über bestimmte Webseitenattacken Felder entfernt oder hinzugefügt werden, dann kann Extbase später feststellen, dass die Anzahl und/oder Feldnamen nicht übereinstimmen und wirft eine Fehlermeldung. Das Formular kann also nicht abgesendet werden.

Ich habe in meinem Beispiel noch einen Objektnamen angegeben "newFeUser". Wie Ihr seht wurde dieser Wert jedem Feld in meinem Formular vorangestellt. Das hat den Vorteil, dass meine Formularfelder nicht einzeln, sondern gebündelt in einem Array an die Zielseite übertragen werden. Dort angekommen kann ich meiner Action mitteilen, dass der Inhalt diesen Arrays in ein Modell portiert werden soll. Bei dieser Portierung werden auch automatisch die enthaltenen Werte auf Gültigkeit überprüft, sofern Ihr überhaupt Überprüfungsregeln in Euren Modellen angegeben habt. Nur wenn alle Überprüfungen gültig waren, kann das Modell mit den Formulardaten an die Action übergeben werden und dort mit einem Einzeiler in der Datenbank gespeichert werden.

f:groupedFor Seit TYPO3 4.3

ParameterErklärung

each

Array oder Objekt, das durchlaufen werden soll

as

Ein Variablenname, der die gruppierten Datensätze enthält

groupBy

anhand welcher Eigenschaft soll das Array gruppiert werden

groupKey

Innerhalb der f:groupedBy-Tags kann mit dieser Variable auf den gruppierten Wert zugegriffen werden.

Ein sehr mächtiger ViewHelper im Bereich der Listengenerierung. Übergebt dem ViewHelper ein Array und ein Gruppierungskriterium und Ihr erhaltet mit jedem Durchlauf bzw. mit jeder gefundenen Gruppe ein Array mit den dazugehörigen Arrayelementen zurück. Zu kompliziert? Na dann schaut mal in die Beispiele:

Beispiel

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
    <table cellpadding="5" cellspacing="0" border="2">
        <f:groupedFor each="{mitarbeiter}" as="kollegen" groupBy="stadt" groupKey="stadt">
            <tr>
                <th colspan="2">{stadt}</th>
            </tr>
            <f:for each="{kollegen}" as="kollege">
                <tr>
                    <td style="color: {color}">{kollege.vorname}</td>
                    <td style="color: {color}">{kollege.stadt}</td>
                </tr>
            </f:for>
        </f:groupedFor>
    </table>
</f:alias>

Ich hab hier wieder das Beispiel mit den 6 Mitarbeitern ausgepackt. Wie Ihr sehen könnt habe ich dem f:groupedBy-ViewHelper gesagt, dass er diese Mitarbeiter anhand ihrer Städte gruppieren soll (groupBy). Das geübte Auge sieht evtl. sofort, dass die ersten beiden Arrayeinträge in Lindlar wohnen. Um innerhalb der f:groupedBy-Tags auf diesen Städtenamen zugreifen zu können, verwende ich den Parameter groupKey. Der Wert aus groupBy und groupKey müssen nicht übereinstimmen. Innerhalb von groupKey hätte ich auch einfach city nehmen können.

Über die Variable, die ich unter "as" angegeben habe kann ich nun auf die Elemente der ersten gefundenen Gruppe zugreifen und mit f:for durchlaufen lassen.

f:if Seit TYPO3 4.3

ParameterErklärung

condition

Hier kommt die Vergleichtsabfrage rein (Siehe Beispiele)

Ich glaube der f:if-ViewHelper ist mit der wichtigste ViewHelper überhaupt auch wenn er in seinen Möglichkeiten etwas beschränkt ist. Wer sich mal den fed:if-ViewHelper aus der fed-Extension angeschaut hat, weiß wovon ich rede.

Folgende Vergleiche sind erlaubt: ==, !=, <, <=, >, >= und %

Ab TYPO3 8.0 können auch f:if ViewHelper mit komplexen logischen Operatoren wie && und || inkl. Gruppierungen mittels Klammern verwendet werden.

Vergleicht werden können nur Variablen folgenden Typs: Zahlen, Objekteigenschaften, Arrays und Ergebnisse aus ViewHelpern

Einfache Beispiele

<f:alias map="{wert1: 1, wert5: 5}">
    <f:if condition="{wert1}==1">
        <p>Der Wert ist 1</p>
    </f:if>
    <f:if condition="{wert5}==5">
        <f:then>
            <p>Der Wert ist 5</p>
        </f:then>
        <f:else>
            <p>Der Wert ist NICHT 5</p>
        </f:else>
    </f:if>
    <f:if condition="{wert5} % 2">
        <f:then>
            <p>Die Berechnung liefert einen Restwert von 1.</p>
        </f:then>
        <f:else>
            <p>Es konnte kein Restwert ermittelt werden</p>
        </f:else>
    </f:if>
    <f:if condition="{wert1}!={wert5}">
        <p>wert1 ist NICHT gleich wert5</p>
    </f:if>
    <f:if condition="{wert1}<{wert5}">
        <p>wert1 ist kleiner als wert5</p>
    </f:if>
    <f:if condition="{0:wert1,1:wert5}=={0:1,1:5}">
        <p>Der erste Array ist gleich mit allen Werten aus dem zweiten Zahlenarray</p>
    </f:if>
</f:alias>
<f:alias map="{elemente: {0: wert1, 1: wert2}}">
    <f:if condition="{elemente -> f:count()==2">
        <p>Vergleich mit ViewHelpern: Das Elementearray beinhaltet 2 Elemente</p>
    </f:if>
</f:alias>
<f:alias map="{wert1: 'hallo'}">
    <f:if condition="{0: wert1} == {0: 'hallo'}">
        <p>Stringvergleiche klappen nur als Array</p>
    </f:if>
</f:alias>

Wenn kein f:then oder f:else-ViewHelper gefunden wurde, dann wird der Inhalt zwischen den f:if-ViewHelpern immer nur dann ausgegeben, wenn die Bedingung wahr ist. Wenn komplette WENN->DANN-SONST-Konstrukte erzeugt werden müssen, dann müssen auch immer die f:then und f:else-ViewHelper verwendet werden.

f:image Seit TYPO3 4.3

ParameterErklärung 

src

Pfad zu der Datei. Prefix EXT: möglich.

Kombinierter Identifier wie 2:uploads/tx_news/hund.png. Wobei die Zahl die UID des Storages angibt.

UID aus der Tabelle sys_file

Wenn treatIdAsReference aktiviert wurde, dann gilt nicht mehr die UID aus der Tabelle sys_file, sondern die UID aus der Tabelle sys_file_reference.

 

alt

Alternativtext für das Bild, falls es nicht angezeigt wird

 

width

Breite des Bildes. Hier kann z.B. mit einem angehangenen "c" gesagt werden, dass das Bild, falls die Proportionen nicht genau passen, abgeschnitten wird. Z.B. 200c

 

height

Höhe des Bildes. Hier kann z.B. mit einem angehangenen "c" gesagt werden, dass das Bild, falls die Proportionen nicht genau passen, abgeschnitten wird. Z.B. 100c

 

minWidth

Auch wenn die Bilder im Original evtl. kleiner sind wie dieser Wert hier, so werden diese Bilder auf die hier angegebene Breite gezoomt.

 

minHeight

Auch wenn die Bilder im Original evtl. kleiner sind wie dieser Wert hier, so werden diese Bilder auf die hier angegebene Höhe gezoomt.

 

maxWidth

Auch wenn die Bilder im Original evtl. größer sind wie dieser Wert hier, so werden diese Bilder auf die hier angegebene Breite verkleinert.

 

maxHeight

Auch wenn die Bilder im Original evtl. größer sind wie dieser Wert hier, so werden diese Bilder auf die hier angegebene Höhe verkleinert.

 

treatIdAsReference

Verwende die UID beim src-Parameter für die Tabelle sys_file_reference und nicht mehr für Tabelle sys_file.Seit TYPO3 6.0
imageAnstatt dem src-Parameter könnt Ihr hier das komplette Bildobjekt von FAL übergeben (FileInterface/AbstractFileFolder). src und image sind eine entweder-oder-Sache. Ihr könnt nicht beide gleichzeitig verwenden.Seit TYPO3 6.2
crop

Hiermit könnt Ihr das in sys_file_reference hinterlegte Cropping überschreiben. Erwartet wird ein Text wie: X,Y,WIDTH,HEIGHT. X = Horizontale Anzahl Pixel von der oberen linken Ecke. Y = Vertikale Anzahl von Pixel der oberen linken Ecke. WIDTH/HEIGHT: Breite und Höhe des Ausschnitts in Pixel.

Wenn 0, dann wird das in sys_file_reference hinterlegte Cropping komplett deaktiviert.

Seit TYPO3 7.3
absoluteWenn 1, dann wird das Bild mit einem absoluten Pfad gerendert.Seit TYPO3 7.6

Ich war total begeistert, als ich von diesem ViewHelper das erstmal gelesen habe. Die Arbeit, die man sich normalerweise umständlich in einer Extension oder im TS machen musste gibt es nun fertig als ViewHelper und die Bilder werden nicht einfach nur verkleinert dargestellt. Nein! Sie werden mit Hilfe von PHP-GD und imagemagick auf die hier angegebene Größe verkleinert. Eine geniale Erfindung, die ich nicht mehr missen möchte.

Beispiel in Originalgröße

<f:image src="fileadmin/bilder/landschaft.jpg" alt="landschaft" />

Beispiel: Beibehaltung der Proportionen

<f:image src="fileadmin/bilder/landschaft.jpg" alt="landschaft" width="50" />

Beispiel: Geschnittenes Bild

<f:image src="fileadmin/bilder/landschaft.jpg" alt="landschaft" width="100c" height="100c" />

Die kürzere Seite wird auf 100 Pixel gesetzt und bei der längeren Seite wird nach 100 Pixeln einfach abgeschnitten.

f:layout Seit TYPO3 4.3

Doku kommt noch

f:media Seit TYPO3 7.6

ParameterErklärung
fileHier geht es nicht um eine UID, Dateinamen oder Referenz. Diese Eigenschaft erwartet das komplette Bildobjekt vom Typ FileInterface oder AbstractFileFolder
additionalConfigEine zusätzliche Konfiguration, die an den Bildrenderer Prozess übergeben wird
width

Breite des Bildes. Hier kann z.B. mit einem angehangenen "c" gesagt werden, dass das Bild, falls die Proportionen nicht genau passen geschnitten wird. Z.B. 200c

height

Höhe des Bildes. Hier kann z.B. mit einem angehangenen "c" gesagt werden, dass das Bild, falls die Proportionen nicht genau passen geschnitten wird. Z.B. 100c

f:render Seit TYPO3 4.3

ParameterErklärung

section

Der Name einer Section, die gerendert werden soll.

partial

Pfad + Dateiname ohne .html-Endung ab dem Verzeichnis, das für Partials definiert wurde.

arguments

Welche Variablen sollen in den Partial/das Layout übernommen werden.

optional

Normalerweise hagelt es Fehlermeldungen, wenn Sections nicht auffindbar sind. Setzt man diesen Parameter aber auf TRUE, dann wird eben nichts ausgegeben.

Die Partials sind in Fluid wie die FCEs in TemplaVoila. Kurz: Wiederverwendbare Templates. Eine geniale Sache solange Ihr diese ViewHelper in Maßen einsetzt, denn das Laden eines Partials dauert ca. 5 Millisekunden. Wenn Ihr also irgendwann mal auf die Idee kommen solltet jede Zelle einer Tabelle mit Partials generieren zu wollen, dann kann das Laden der Webseite bei 700 Tabellenzeilen und 15 Spalten schonmal etwas dauern: 700 Zeilen * 15 Spalten * 5 Millisekunden = 52500 Millisekunden. Plus die Zeit, die TYPO3 selbst noch braucht sind wir bei knapp einer Minute.

Die Dateien für Partials liegen immer in fest vorgegebenen Verzeichnissen. Innerhalb von Extensions ist dies: typo3conf/ext/[ExtensionKey]/Resources/Private/Partials/. Wenn Ihr allerdings mit FLUIDTEMPLATE arbeitet, dann gebt Euren gewünschten Verzeichnispfad mit Hilfe der TS-Eigenschaft "partialRootPath" mit abschließendem / an.

Sections haben kein eigenes Verzeichnis, da diese immer innerhalb der aktuellen Templatedatei definiert werden müssen. Außnahmen machen da die Layouts.

Beispiel für Partial

In unserem Fluidtemplate:

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'},1: {vorname: 'Petra', stadt: 'Lindlar'},2: {vorname: 'Sascha', stadt: 'Remscheid'},3: {vorname: 'Patrick', stadt: 'Bonn'},4: {vorname: 'Sven', stadt: 'Gummersbach'},5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
    <table cellpadding="5" cellspacing="0" border="2">
        <f:for each="{mitarbeiter}" as="kollege">
            <f:render partial="TableRow" arguments="{kollege: kollege}"/>
        </f:for>
    </table>
</f:alias>

In der Partial Datei TableRow.html

<tr>
    <td>{kollege.vorname}</td>
    <td>{kollege.stadt}</td>
</tr>

Weitere Beispiele folgen

f:renderChildren Seit TYPO3 4.5

ParameterErklärung
arguments

Variablen in ArrayNotation, die an das Unter-Template übergeben werden sollen

Dieser ViewHelper findet nur innerhalb der Templates von Fluid Widgets Gebrauch. Gerade beim f:paginate Widget wird f:renderChildren benötigt, um den Inhalt zwischen dem öffnenden und schließenden f:pageinate zu rendern. f:paginate kommt mit einem eigenen kleinen Fluid Template daher und baut sich selbst als Seitennavigation wahlweise vor und/oder nach diesem Inhalt aus renderChildren ein.

f:renderFlashMessages Seit TYPO3 4.3. Veraltet seit TYPO3 4.5. Entfernt mit TYPO3 6.0

Diesen ViewHelper gab es nur für kurze Zeit. Schon 2 Versionen später wurde dieser vom f:flashMessages ViewHelper abgelöst.

f:section Seit TYPO3 4.3

ParameterErklärung

name

Ein Name unter dem man den Inhalt zwischen den Tags wieder auffinden kann

Sections arbeiten ähnlich wie Partials. Während Partials in eine eigene Datei ausgelagert werden und somit innerhalb der Extension von überall aufgerufen werden können, befinden sich Sections innerhalb der Templatedateien und können auch nur von dort und Layouts aufgerufen werden. Mit Hilfe von Sections lassen sich gerade große Templates hervorragend strukturieren.

Beispiel

<f:alias map="{mitarbeiter: {0: {vorname: 'Stefan', stadt: 'Lindlar'}, 1: {vorname: 'Petra', stadt: 'Lindlar'}, 2: {vorname: 'Sascha', stadt: 'Remscheid'}, 3: {vorname: 'Patrick', stadt: 'Bonn'}, 4: {vorname: 'Sven', stadt: 'Gummersbach'}, 5: {vorname: 'Andrea', stadt: 'Wuppertal'}}}">
  <table cellpadding="5" cellspacing="0" border="2">
    <f:for each="{mitarbeiter}" as="kollege">
      <f:render section="TableRow" arguments="{kollege: kollege}"/>
    </f:for>
  </table>
</f:alias>

<f:section name="TableRow">
  <tr>
    <td>{kollege.vorname}</td>
    <td>{kollege.stadt}</td>
  </tr>    
</f:section>

f:spaceless Seit TYPO3 7.6

Jedes Enter, jede Einrückung und jedes Leerzeichen in Euren Fluidtemplates werden 1zu1 im Seiten Quelltext Eurer Webseite ausgegeben. Zwar reduziert der Browser überflüssigen Leerraum bei der Ausgabe auf ein Leerzeichen zusammen, aber trotzdem muss jedes Leerzeichen zum Browser übertragen werden und kostet somit zusätzlichen Traffic. Mit diesem ViewHelper können die überflüssigen Leerräume schon vor der Ausgabe entfernt werden.

Im folgenden Beispiel würde der HTML Quelltext als eine lange Zeile zum Browser übertragen werden.

Es wird nur Leerraum zwischen den HTML-Tags entfernt. Nicht jedoch der Leerraum im Fließtext.

Beispiel

<f:spaceless>
  <table>
    <tbody>
      <tr>
        <td>Hallo</td>
      </tr>
    </tbody>
  </table>
</f:spaceless>

f:switch Seit TYPO3 6.2

ParameterErklärung

expression

Ein string/int/bool Wert, auf den die enthaltenen f:case ViewHelper reagieren sollen.

Mit dem f:switch ViewHelper könnt Ihr gleich mehrere Varianten eines Wertes überprüfen. Auf die Frage "Was bist Du?" könnte die Antwort Vater, Mutter, Tochter oder Sohn erfolgen. Diese 4 Antwortmöglichkeiten mittels dem f:if ViewHelper zu realisieren wäre schon sehr komplex und schwer zu warten. Mit jeder weiteren Variante würde der Quelltext ein bisschen weiter nach rechts rutschen. Nach ein paar Monaten weiß kein Mensch mehr, was da eigentlich gerade passiert.

Beispiel

<f:switch expression="{whoAreYou}">
  <f:case value="Vater">Ich brauch Taschengeld</f:case>
  <f:case value="Mutter">Wann gibt's Mittach?</f:case>
  <f:case value="Tochter">Wo ist mein Lippenstift?</f:case>
  <f:case value="Sohn">Ich geh scaten</f:case>
  <f:case default="1">Stell Dich vor</f:case>
</f:switch>

f:then Seit TYPO3 4.3

Diesen ViewHelper erkläre ich im Bereich f:if, da er nur dort verwendet werden kann.

f:translate Seit TYPO3 4.3

ParameterErklärung

key

Der key, mit dem man die Übersetzung aus dem Sprachdateien auslesen kann

default

Wenn der Key in der Sprachdatei nicht gefunden werden kann, dann verwende diesen Text. Wenn default nicht gesetzt ist, wird der Inhalt zwischen den Tags verwendet.

htmlEscape

Alle Übersetzungen aus den Sprachdateien werden durch htmlspecialchars geschleust, was es unmöglich macht, HTML-Tags in den Übersetzungen anzeigen zu lassen. Setzt diesen Wert auf FALSE, um dieses Vorgehen zu unterbinden.

arguments

In den Übersetzungen können Platzhalter definiert werden, die dann mit den Inhalten diesen Arrays gefüllt werden.

Mit dem f:translate-ViewHelper greift Ihr auf eine beliebige Sprachdatei (meist locallang.xml) zu und holt Euch die entsprechende Übersetzung mit Hilfe der Angabe im Parameter "key".

Innerhalb von Extensions wird immer auf die locallang.xml im Verzeichnis Resources/Private/Language/ zugegriffen. Im Bereich FLUIDTEMPLATE müsste Ihr hier die Pfadsyntax verwenden:

LLL:fileadmin/templates/locallang.xml:domain_model_irgendwas.titel

bzw:

LLL:EXT:meineExtension/Resources/Private/Language/locallang.xml:domain_model_irgendwas.titel

Diese "LLL:" Prefixe müssen bei der Pfadnotation immer gesetzt sein!!! Etwas einfacher machen es sich die FLUIDTEMPLATE-User, wenn sie im TS zuvor angeben auf welche locallang.xml welcher Extension sie zugreifen wollen:

extbase.pluginName = Pi1
extbase.controllerExtensionName = MeineExtension

Dann reicht es auch wieder nur den "key" anzugeben OHNE den ganzen Pfad

Beispiel

<f:translate key="domain_model.title" htmlEscape="false" />

Beispiel mit Pfad

<f:translate key="LLL:fileadmin/lang/locallang.xml:domain_model.title" />

Beispiel mit Platzhaltern

In unserem Template:

<f:translate key="LLL:fileadmin/lang/locallang.xml:domain_model.title" arguments="{0: 'Herr der Ringe'}" />

In der locallang.xml

<label index="domain_model.title">Title of: %s</label>

Mit %s wird auf den ersten Wert des übergebenen Arrays zugegriffen. Kommt %s nochmals vor, dann wird auf den zweiten Arrayeintrag zugegriffen. Um das unabhängig von der Reihenfolge zu machen empfehle ich noch folgende Notation:

<label index="domain_model.title">Titel von: %1$s</label>

Mit %1 greift Ihr auf den ersten Eintrag zu und sagt diesem, dass er als String/Text interpretiert werden soll ($s). Auf php.net findet Ihr heraus wofür diese ganzen Kürzel stehen.