Anzeige
Anzeige
UX & Design
Artikel merken

Der TYPO3-Standard-Wrap kann mehr, als man denkt: stdWrap verstehen und anwenden

stdWrap ist eine Sammlung von mächtigen Hilfsfunktionen in TypoScript, mit der man verschiedene Datenquellen auslesen sowie die Daten überprüfen und verarbeiten kann. Dieser Artikel erklärt, wie stdWrap intern funktioniert und was dies für die Anwendung bedeutet. Außerdem beschreibt er wichtige stdWrap-Funktionen und zeigt, wie man diese geschickt kombiniert.

9 Min. Lesezeit
Anzeige
Anzeige

Anzeige
Anzeige

stdWrap, der TypoScript-Standard-Wrap, ist eine der am häufigsten verwendeten TypoScript-Funktionen. Die bekannteste Anwendung der stdWrap-Funktion ist das TypoScript-Objekt „TEXT“:

cObject TEXT: nur value + stdWrap
page.98 = TEXT  # in allen hier abgebildeten Beispielen ist page.98 immer ein TEXT
page.98 {
	value = Startseite
	typolink.parameter = 123
	wrap = <div class=“home“>|</div>
}

Listing 1

Schaut man sich nun an, was hier tatsächlich passiert, so findet man im TYPO3-Sourcecode in der Datei
„typo3\sysext\cms\tslib\class.tslib_content.php“ folgenden Aufruf:

Anzeige
Anzeige
Quellcode des cObjects TEXT, ungekürzt
function TEXT($conf)	{
		return $this->stdWrap($conf['value'],$conf);
	}

Listing 2

Es wird also eine tatsächliche PHP-Funktion aufgerufen, inklusive aller Parameter, die man dem Objekt „TEXT“ im TypoScript zugewiesen hat. Diese stellt sich – stark gekürzt – wie folgt dar:

Anzeige
Anzeige
Quellcode von stdWrap, stark gekürzt
function stdWrap($content,$conf)	{
		if (is_array($conf))	{
			if ($conf['field']) {
				$content=$this->getFieldVal($conf['field']);
			}
			if ($conf['stdWrap.']){ 
				$content=$this->stdWrap($content,$conf['stdWrap.']); 
			}
			if ($conf['typolink.']){
				$content=$this->typolink($content, $conf['typolink.']);
			}
			if ($conf['wrap']){
				$content=$this->wrap($content, $conf['wrap']);
			}
		}
		return $content;
}

Listing 3

stdWrap ist demnach eine Funktion, die andere Funktionen aufruft, sofern man diese konfiguriert hat. Sie bekommt einen String namens $content als Eingabe, bearbeitet diesen und gibt ihn wieder aus.

Man kann mehrere Funktionen in einem Schritt aufrufen. Sie werden dann immer in der Reihenfolge ausgeführt, die im Quellcode definiert wurde. Die Konfigurationsreihenfolge im TypoScript spielt dabei keine Rolle.

Anzeige
Anzeige

Anwendungsgebiete von stdWrap

stdWrap kann man nur dort nutzen, wo diese Funktion auch definiert ist. Letzten Endes ist stdWrap nur eine PHP-Funktion, die auch aufgerufen werden muss. Wann immer man stdWrap auf einen Parameter anwenden kann, so steht bei diesem in der TSref etwas in der Form „int+ / stdWrap“ oder „string /stdWrap“.

Manche – aber nicht alle – cObjects kann man auch komplett per stdWrap wrappen. Sie haben dann meist einen Parameter namens „stdWrap“. Ein guter Trick für Elemente, die sich nicht ohne Weiteres wrappen lassen, ist, diese einfach in das Array „COA“ zu packen:

stdWrap bei beliebigen Objekten nutzen mit COA
page.10 = COA
page.10.10 < plugin.tx_myplugin
page.10.stdWrap.ifEmpty = Plugin ist leer.

Listing 4

Wenn man bei einem Parameter keine stdWrap-Eigenschaft definiert hat, kann man diese leider auch nicht nutzen.

Anzeige
Anzeige

Die unterschiedlichen stdWrap-Funktionen

Einen Überblick über die verfügbaren stdWrap-Funktionen bekommt man im TSref [1] und im offiziellen TYPO3-Wiki [2].

Die Funktionen werden in der Reihenfolge, in der sie auch im Wiki stehen, abgearbeitet. Dabei ist die Reihenfolge, in der das TypoScript definiert wurde, unerheblich.

Die stdWrap-Funktionen kann man grob in drei Gruppen unterteilen, die nacheinander in dieser Reihenfolge aufgerufen werden:

Anzeige
Anzeige
  1. Daten holen, zum Beispiel „field“ oder „data“
  2. Daten überprüfen/überschreiben, beispielsweise „ifEmpty“
  3. Daten verarbeiten, zum Beispiel „crop“, „typolink“, „wrap“

Daten holen

field: Datenbankfelder holen
#Feld subtitle holen
page.98.field = subtitle

#herausfinden, welche Felder es gibt
page.98.debugData = 1

Listing 5

Die wohl bekannteste Funktion zum Holen von Daten ist „field“. Mit dieser kann man ein aktuell verfügbares Feld auslesen. Das sind normalerweise die Felder auf der Seite, auf der man sich gerade befindet. Innerhalb eines Menüs wäre es die aktuelle Seite im Menü, innerhalb einer Extension könnten es beispielsweise Felder des anzuzeigenden Datensatzes sein. In der Regel kann „field“ auf alle Felder einer Datenbanktabelle zugreifen. In einigen Extensions werden die Felder aber auch gefiltert oder neue hinzudefiniert. Welche Felder aktuell verfügbar sind, kann man sich anzeigen lassen, indem man die letzte Zeile in Listing 5 testweise setzt.

data: Verschiedenste Daten auslesen
#Mit data kann man unter anderem folgendes auslesen:
#Aktuelle Felder
page.98.data = field:subtitle
#Felder anderer Tabellen 
page.99.data = {DB:static_countries:56:cn_iso_2}
#GET- und POST Variable:
page.100.data = GP:tx_ttnews|tt_news # GPVar is seit Version 4.3.x deprecated
#Cookies:
page.101.data = global : HTTP_COOKIE_VARS | mycookie
#Cookies:
page.102.data = global : HTTP_COOKIE_VARS | mycookie
#Lokalisierte Texte:
page.103.data = LLL:EXT:tt_news/pi/locallang.xml:latestHeader
#Register:
page.104.data = register:myCount
#Und vieles mehr.

Listing 6

Wer schon einmal versucht hat, in der TSref zu verstehen, was „getText“ eigentlich macht, der wird in der Regel verwirrt gewesen sein. Dort steht nämlich nur, dass „data“ vom Typ „getText“ ist. Im TYPO3-Wiki ist „getText“ zum Glück detaillierter beschrieben [3].

Object: Ausgabe eines anderen Objekts
lib.myext.title.stdWrap.cObject = IMAGE
lib.myext.title.stdWrap.cObject.file = GIFBUILDER

Listing 7

Mit „cObject“ kann man die Ausgabe eines anderen Objekts als Grundlage nutzen. Im Zusammenhang mit „TEXT“ weniger einleuchtend ist die Möglichkeit, die gesamte Ausgabe der stdWrap-Funktion nach einem anderen Element umzubiegen. Möchte man aber zum Beispiel einen Titel durch ein GIFBUILDER-Objekt ersetzen, um ihn grafisch darzustellen, kann das sehr sinnvoll sein:

Anzeige
Anzeige

Daten überschreiben

ifEmpty, ifBlank und override: Überschreiben
# Output: angezeigt!
page.98 .value = gelöscht?
page.98.override = angezeigt!

#Output: gelöscht?
page.98 .value = gelöscht?
page.98.ifEmpty = angezeigt!

Listing 8

Die drei Funktionen „ifEmpty“, „ifBlank“ und „override“ überschreiben Daten und scheinen ähnlich zu wirken, unterscheiden sich aber dennoch: Sollte nach dem Holen der Daten aus dem vorherigen Schritt der Inhalt des Links leer sein, so wird dieser mit dem Inhalt von „ifEmpty“ oder „ifBlank“ ersetzt. Dabei interpretiert „ifEmpty“ den leeren String “, die Zahl 0 sowie den String ‚0‘ als leer. „ifBlank“ interpretiert nur den leeren String “ als leer.

„override“ dagegen überschreibt in jedem Fall den Wert, den „$content“ in dem Moment hat, es sei denn, der Inhalt von „override“ selbst ist leer oder ‚0‘.

required, fieldRequired, if: Notausstieg aus stdWrap
/*
Manchmal ist auch ein „Notausstieg“ sinnvoll. 
Diese Funktionen geben sofort den leeren String, wenn
*/
# der derzeitige Inhalt leer oder 0 ist:
page.98.required = 1

# das Feld media gesetzt ist:
page.98.fieldRequired = media

# das Feld media ist nicht gesetzt
page.98.if.isFalse.field = media

# die Seite den Typ „normale Seite“ hat:
page.98.if.equals.value.field = doktype 
page.98.if.equals = 1

Listing 9

Die Funktion „trim“ wird nach „required“ aber vor dem „if“ aufgerufen. Das hat praktische Gründe, thematisch würde sie besser zur Gruppe „Daten verarbeiten“ passen.

Anzeige
Anzeige

Daten verarbeiten

Die größte Gruppe der stdWrap-Funktionen ist jene zum Verarbeiten der Daten. Viele trivialere stdWrap-Funktionen stellen einfach nur entsprechende PHP-Funktionen zur Bearbeitung von Strings zur Verfügung.

Dazu zählen zum Beispiel: „intval“, „stripHtml“, „htmlSpecialChars“, „case = upper“ und weitere. Andere Funktionen rufen entsprechende TYPO3-API-Funktionen auf.

Da es unmöglich ist, in diesem Rahmen alle stdWrap-Funktionen zu beschreiben, werden im Folgenden nur einige wichtige vorgestellt, die nach Themen geordnet sind.

Anzeige
Anzeige
Quellcode der Wrap-Funktion
function wrap($content,$wrap,$char='|')	{
	if ($wrap)	{
		$wrapArr = explode($char, $wrap);
		return trim($wrapArr[0]).$content.trim($wrapArr[1]);
	} else return $content;
}

Listing 10

Es gibt insgesamt fünf normale Wraps. Diese werden in der Reihenfolge „innerWrap“, „innerWrap 2“, „wrap“, „wrap2 [,3]“, „outerWrap“ aufgerufen. In der Regel wird bei ihnen die Pipe „|“ durch den aktuellen Inhalt von „$content“ ersetzt.

wrap mit Stern statt Pipe als Trennzeichen
page.98.value = I need my pipes
page.98.wrap = |||*|||
page.98.wrap.splitChar = *

Listing 11

Bei „wrap“, „wrap2“ und „wrap3“ kann man zur Aufspaltung anstelle der Pipe „|“ auch ein anderes Zeichen definieren.

innerWrap mit Wiederaufruf von stdWrap
page.98.value = Ein Text
page.98.innerWrap.data = LLL:EXT:myext/locallang.xml:wrapMe

Listing 12

Beim „inner-“ und „outerWrap“ ist das allerdings nicht möglich. Dagegen kann bei „innerWrap“, „innerWrap2“ und „outerWrap“ der Text des Wraps selbst nochmal durch die stdWrap-Funktion gejagt werden. Das wiederum ist bei „wrap“ bis „wrap 3“ nicht möglich, was vermutlich historische Gründe hat.

Spezielle Wraps: noTrimWrap, dataWrap
page.98. noTrimWrap = |Ich | Dich|
page.99. dataWrap = <div class=“{field:myClass}“>|</div>

Listing 13

„noTrimWrap“ funktioniert wie der normale Wrap, entfernt jedoch keine Leerzeichen. Um Anfang und Ende zu definieren, muss der Wrap in zusätzliche Pipes eingepackt werden.

Beim „dataWrap“ wird sämtlicher Text, der zwischen geschwungenen Klammern liegt, durch die „getText“-Funktion gejagt. Also in etwa so, als hätte man ihn bei Data eingegeben.

Zu den wichtigsten HTML-Funktionen gehören „HTMLparser“, „stripHtml“ und „br“. Die Funktion „br = 1“ ist zwar simpel, aber oft sehr hilfreich. Ist sie gesetzt, so werden alle im Text vorhandenen New-Lines durch „<br />“-Tags ersetzt – so kann man Zeilenumbrüche im Frontend ausgeben.

„stripHtml“ entfernt sämtliche HTML-Tags. Dies ist wichtig, wenn man einen Text zum Beispiel (per crop) kürzen will.

Der HTMLParser kann HTML-Eingaben parsen, verbotenes HTML entfernen oder nur erlaubte Tags darin belassen. Verwandt, aber noch komplexer ist die „parseFunc“, die auch vom RTE genutzt wird. Seit TYPO3 4.3 gibt es die Funktion „cropHTML“. Diese kürzt Texte und bewahrt dabei alle HTML-Tags.

stdWrap rekombinieren

Eine große Stärke von stdWrap liegt darin, dass man die einzelnen Funktionen beliebig kombinieren kann. Dabei gibt es zwei mögliche Kombinationsformen: die lineare Kombination und die rekursive Kombination.

Lineare Kombination zweier stdWrap-Funktionen
# Ausgabe: stdWrap ist prima
page.98.value = stdWrap ist toll
page.98.crop = 7
page.98.noTrimWrap = || ist prima|

Listing 14

Bei der linearen Kombination werden die Funktionen einfach hintereinander aufgerufen und zwar in der Reihenfolge, die im Quellcode definiert war.

Rekursive Kombination von stdWrap-Funktionen
# Ausgabe: stdWrap ist prima
page.98.value = stdWrap ist toll
page.98.stdWrap.crop = 7
page.98.noTrimWrap = || ist prima|

# Ausgabe: stdWrap
page.98.value = stdWrap ist toll
page.98.crop = 7
page.98.stdWrap.noTrimWrap = || ist prima|

Listing 15

Beim rekursiven Aufruf dagegen wird die stdWrap-Funktion noch ein weiteres Mal aufgerufen. Dadurch kann man die Ausführungsreihenfolge der Funktionen beeinflussen:

Wenn man die Aufrufreihenfolge der Funktionen nicht ändern muss, sollte man der linearen Kombination den Vorzug geben – diese ist performanter.

Komplexe stdWrap-Beispiele

Titel eines tt_news-Datensatzes auslesen
lib.myNewsTitle = TEXT
lib.myNewsTitle.data = DB:tt_news:188:title

Listing 16

Kennt man die UID eines Newsdatensatzes, so kann man dessen Titel wie oben beschrieben einfach auslesen.

Was aber, wenn man die UID des tt_news-Datensatzes aus einer GET-Variable auslesen muss, um zum Beispiel den Titel der aktuell anzuzeigenden News in der SINGLE-Ansicht auszulesen? Das geht unter anderem so:

tt_news Titel aus GET-Variable ermitteln
1	lib.myNewsTitle = TEXT
2	lib.myNewsTitle {
3		dataWrap = DB:tt_news:{GP:tx_ttnews|tt_news}:title
4		wrap3 = {|}
5		insertData = 1
6	}

Listing 17

Aber wie funktioniert das? Die Funktionen werden in der Reihenfolge aufgerufen, in der sie im Beispiel stehen. Zunächst wird also in Zeile 3 der dataWrap ausgeführt. Danach hat „$content“ den Wert „DB:tt_news:188:title“. Durch wrap3 in Zeile 4 wird „$content“ umgewandelt in „{DB:tt_news:188:title}“. insertData in Zeile 5 parst nun noch einmal den String nach geschwungenen Klammern und schickt den Inhalt durch die getText-Funktion. Danach hat $content als Wert den Titel der News – dieser wird auch zurückgegeben.

Die Split Funktion nutzen
# Pipes in Zeilenumbrüche verwandeln
page.98 {
 value =Jochen|Kasper|Robert 
 split {
 token = |
 wrap = <br />
 }
}
/*
Ausgabe:
Jochen<br />
Kasper<br />
Robert <br />
*/

# Bestimmten Datensatz zurückgeben
page.99 {
 value = Jochen|Kasper|Robert 
 split {
 token = |
 wrap = <br />
 returnKey = 1
 }
}
#Ausgabe: Kasper

Listing 18

Die Split-Funktion gehört zu den komplizierteren stdWrap-Funktionen. Wenn man sich mit ihr intensiver auseinandersetzt, merkt man schnell, wie mächtig sie ist. Es gibt ein sehr gutes Tutorial dazu im Wiki [4], daher oben zwei kleine Beispiele zur Motivation.

stdWrap erweitern

Wem die eingebauten stdWrap-Funktionen nicht genügen, der kann entweder eine der zwei integrierten userFuncs „preUserFunc“ und „postUserFunc“ oder einen der derzeit vier vorhandenen Hooks nutzen. Nähere Infos dazu finden sich auch in dem Handout zu einem stdWrap-Vortrag der Autorin [5].

Die Zukunft von stdWrap

Auf den TYPO3 Developer Days 2010 in Elmshorn wurde im Rahmen eines Workshops die nahe Zukunft von stdWrap und TypoScript besprochen. Die Neuerungen werden voraussichtlich in TYPO3 4.5 zur Verfügung stehen. Das Projekt dazu heißt „Pimp Your TypoScript“ [6]. Neben Verbesserungen der Code-Qualität hinsichtlich Performance und Erweiterbarkeit soll es auch für Entwickler einige nützliche Neuerungen geben.

So wird es künftig möglich sein, an jeder Stelle des TypoScripts stdWrap-Funktionen anzuwenden. Ausnahmen gibt es nur bei Kollisionen mit bestehenden Funktionsnamen, etwa „crop“ beim GIDBUILDER. Dieses neue Feature wird „chained TypoScript“ genannt. Unter anderem wird es damit möglich, die Konfiguration einer stdWrap-Funktion durch TypoScript zu definieren.

chained TypoScript voraussichtlich ab v. 4.5
# TYPO3 v. 4.4
page.98.crop = 255|..|1
# ab v. 4.5 
page.98.crop.field = cropAt

Listing 19

Ab Version 4.5 soll es zudem möglich sein, per stdWrap-Funktion zu ermitteln, um wie viel hier nun gecropt werden soll.

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
Ein Kommentar
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

lina.wolf

Das Beispiel mit dem auslesen des Newstitels hatte ich auch hier schon mal ausführlicher erklärt: Datenbankfelder dynamisch per stdWrap.data auslesen

LG Lina

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