TypoScript-Referenz (TSref): Überblick mit Beispielen
TypoScript ist die Konfigurationssprache von TYPO3. Damit legst du fest, wie TYPO3 eine Seite ausgibt: welches Template, welche Inhalte, welche Menüs, welche Meta-Tags. Diese Seite fasst die wichtigsten Teile der TypoScript-Referenz (TSref) auf Deutsch zusammen, mit Beispielen für die aktuellen Versionen TYPO3 13 LTS und 14.
Früher lag unter typo3.net/tsref eine Kopie der Referenz für TYPO3 4.x. Viele Objekte von damals gibt es nicht mehr. Wo das so ist, steht hier, was du heute stattdessen nimmst. Die vollständige, offizielle Referenz findest du auf docs.typo3.org.
Du kommst nicht weiter? Stell deine Frage im Forum unter TypoScript, Menüs oder Fluid.
Inhalt: Grundlagen · Datentypen · getText · Bedingungen · Funktionen · stdWrap · typolink · Top-Level-Objekte · Content-Objekte · HMENU · GIFBUILDER · Plugins
Grundlagen
TypoScript ist ein Baum aus Eigenschaften. Jede Zeile setzt einen Wert an einem Pfad, Punkte trennen die Ebenen. Geschweifte Klammern sparen Schreibarbeit, sie bedeuten dasselbe wie der lange Pfad.
# Kommentar
page = PAGE
page.10 = TEXT
page.10.value = Hallo Welt
# dasselbe mit Klammern
page.10 {
value = Hallo Welt
wrap = <p>|</p>
}
Die Operatoren:
| Operator | Bedeutung | Beispiel |
|---|---|---|
= |
Wert setzen | page.10.value = Hallo |
< |
Kopieren (Kopie zum Zeitpunkt der Zeile) | lib.footer2 < lib.footer |
=< |
Referenz (nur für Content-Objekte, Änderungen am Original wirken mit) | page.20 =< lib.footer |
> |
Löschen | page.10.wrap > |
:= |
Wert mit einer Funktion ändern | lib.list := addToList(5,6) |
( … ) |
Wert über mehrere Zeilen | value ( … ) |
Weitere Bausteine:
- Konstanten stehen in
{$…}und werden vor dem Auswerten eingesetzt:wrap = <div class="{$site.wrapClass}">|</div>. - Dateien einbinden:
@import 'EXT:site_package/Configuration/TypoScript/Setup/*.typoscript' - Wo TypoScript liegt: Seit TYPO3 13 meist in einem Site Set der Site-Package-Extension (
Configuration/Sets/<Name>/setup.typoscriptundconstants.typoscript). Ein TypoScript-Datensatz im Backend (früher „Template“) geht weiterhin. - Eigene Bausteine legst du unter
lib.ab und verwendest sie per Kopie oder Referenz, zum Beispiellib.footer.
Datentypen
Jede Eigenschaft erwartet einen bestimmten Typ. Die häufigsten:
| Datentyp | Bedeutung | Beispiel |
|---|---|---|
| string | beliebiger Text | value = Hallo |
| integer | ganze Zahl | maxItems = 3 |
| boolean | 1 = an, 0 oder leer = aus |
htmlSpecialChars = 1 |
| wrap | Text vor und nach dem Inhalt, getrennt durch | |
wrap = <p>|</p> |
| list | kommagetrennte Liste | pidInList = 12,13 |
| page-id | Seiten-UID | parameter = 42 |
| date-conf | Datumsformat wie bei PHP date() |
date = d.m.Y |
| resource / path | Datei, meist mit EXT: |
file = EXT:site_package/Resources/Public/Images/logo.svg |
| imgResource | Bild mit Maßen und Format, siehe imgResource | file.maxW = 800 |
Viele Eigenschaften sind zusätzlich stdWrap-fähig: Dann kannst du den Wert mit .data, .field oder .stdWrap dynamisch berechnen, siehe stdWrap.
getText
getText liest Werte aus dem Seiten-Kontext. Du nutzt es über .data (oder in insertData mit {…}).
lib.pageTitle = TEXT
lib.pageTitle.data = page:title
lib.info = TEXT
lib.info {
value = Seite {page:uid} in {siteLanguage:title}
insertData = 1
}
Häufige Schlüssel:
| Schlüssel | liest | Beispiel |
|---|---|---|
field: |
Feld des aktuellen Datensatzes | field:header |
page: |
Feld der aktuellen Seite | page:subtitle |
date: |
aktuelles Datum | date:Y |
leveltitle:, levelfield: |
Seite im Rootline-Pfad | leveltitle:1 |
register: |
Register (siehe LOAD_REGISTER) | register:pageTitle |
LLL: |
Übersetzung aus einer XLF-Datei | LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:footer |
site: |
Wert aus der Site-Konfiguration | site:base |
siteLanguage: |
Wert der aktuellen Sprache | siteLanguage:title |
path: |
öffentlicher Pfad einer Datei | path:EXT:site_package/Resources/Public/Css/main.css |
file: |
Eigenschaft einer Datei (in FILES) |
file:current:alternative |
GP: |
GET-/POST-Parameter (immer absichern, z. B. mit intval = 1) |
GP:tx_news_pi1|news |
Mit // gibst du Ausweichwerte an: data = page:nav_title // page:title.
Bedingungen
Bedingungen stehen in eckigen Klammern und gelten bis [END] (oder [GLOBAL]). Seit TYPO3 9.4 ist die Syntax die Symfony Expression Language, die alte Schreibweise wie [treeLevel = 1] funktioniert seit TYPO3 10 nicht mehr.
[tree.level == 0]
page.10.variables.isHome = TEXT
page.10.variables.isHome.value = 1
[END]
[frontend.user.isLoggedIn]
lib.greeting.value = Willkommen zurück!
[END]
Was früher wie geschrieben wurde:
| alt (bis TYPO3 9) | heute |
|---|---|
[treeLevel = 0] |
[tree.level == 0] |
[PIDinRootline = 12] |
[12 in tree.rootLineIds] |
[globalVar = TSFE:id = 5] |
[traverse(page, "uid") == 5] |
[loginUser = *] |
[frontend.user.isLoggedIn] |
[usergroup = 4] |
[4 in frontend.user.userGroupIds] |
[globalVar = GP:L = 1] |
[siteLanguage("languageId") == 1] |
[hostname = example.org] |
[request && request.getNormalizedParams().getHttpHost() == "example.org"] |
[IP = 192.168.*] |
[ip("192.168.*")] |
[dayofmonth = 7], [month = 12], [hour = 8] |
[date("j") == 7], [date("n") == 12], [date("G") == 8] |
[compatVersion = 12.4] |
[compatVersion("12.4")] |
[applicationContext = Development*] |
[applicationContext matches "/^Development/"] |
[browser = …], [useragent = …], [device = …] |
gibt es nicht mehr: Browser- und Geräteweichen heute mit CSS und JavaScript |
[userFunc = …] |
eigene Funktion über einen ExpressionLanguage-Provider |
Weitere nützliche Variablen und Funktionen: site("identifier"), typo3.version, like(text, "*Muster*") und request.getQueryParams() (zusammen mit traverse()).
Funktionen
Funktionen sind Eigenschaften, die Werte verarbeiten. Die wichtigste ist stdWrap: Fast jedes Content-Objekt kann sie, und viele Eigenschaften haben eine .stdWrap-Untereigenschaft.
stdWrap
stdWrap holt einen Wert, verändert ihn und verpackt ihn. Die Eigenschaften werden in einer festen Reihenfolge abgearbeitet (erst Daten holen, dann verändern, dann verpacken), nicht in der Reihenfolge, in der du sie schreibst.
lib.headline = TEXT
lib.headline {
# Daten holen: Untertitel, sonst Titel
field = subtitle // title
ifEmpty = Ohne Titel
# verändern
htmlSpecialChars = 1
crop = 60 | … | 1
case = upper
# verpacken
wrap = <h1 class="headline">|</h1>
required = 1
}
Oft gebraucht:
- Daten:
value,field,data,current,cObject,numRows - Prüfen:
required,if,ifEmpty,override - Verändern:
htmlSpecialChars,crop,cropHTML,case,trim,intval,replacement,split,date,formattedDate - Verpacken:
wrap,noTrimWrap(z. B.noTrimWrap = | | |für Leerzeichen),dataWrap(wrap mit{…}),innerWrap,outerWrap - Ausgabe steuern:
insertData,typolink,cache,debug
typolink
typolink erzeugt Links: zu Seiten, Dateien, E-Mail-Adressen und externen Adressen.
lib.contactLink = TEXT
lib.contactLink {
value = Kontakt
typolink {
parameter = t3://page?uid=42
ATagParams = class="btn btn-primary"
title = Zur Kontaktseite
}
}
# nur die URL ausgeben, absolut
lib.pageUrl = TEXT
lib.pageUrl.typolink {
parameter.data = page:uid
returnLast = url
forceAbsoluteUrl = 1
}
parameter versteht Seiten-UIDs (42), t3://-Links aus dem Link-Browser, URLs, E-Mail-Adressen und Dateien. Mit Leerzeichen getrennt folgen Ziel, CSS-Klasse und Titel: parameter = 42 _blank btn "Mehr erfahren". Parameter hängst du mit additionalParams = &tx_news_pi1[news]=7 an.
if
if gibt nur dann etwas aus, wenn die Bedingung stimmt. Ohne Vergleich prüft isTrue, ob ein Wert gesetzt ist.
page.20 = TEXT
page.20 {
value = Nur auf der Startseite
if {
value = 1
equals.data = page:uid
}
}
lib.media = TEXT
lib.media {
value = Diese Seite hat Bilder
if.isTrue.data = page:media
}
Weitere Vergleiche: isFalse, isGreaterThan, isLessThan, isInList, und negate = 1 kehrt das Ergebnis um.
imgResource
imgResource beschreibt ein Bild mit Maßen und Format. Ein c hinter der Zahl schneidet zu (crop), ein m skaliert bis zur Grenze.
lib.logo = IMAGE
lib.logo {
file = EXT:site_package/Resources/Public/Images/logo.png
file.maxW = 300
file.ext = webp
altText = typo3.net
}
lib.teaser = IMG_RESOURCE
lib.teaser {
file = fileadmin/bilder/teaser.jpg
file.width = 800c
file.height = 450c
}
IMAGE gibt den fertigen <img>-Tag aus, IMG_RESOURCE nur die Bild-URL.
Weitere Funktionen
- split zerlegt einen Wert an einem Zeichen und rendert jeden Teil einzeln, replacement ersetzt Text (auch mit regulären Ausdrücken).
- numberFormat (mit
decimals,dec_point,thousands_sep) und round formatieren Zahlen. - date formatiert Zeitstempel wie PHP
date(). Für Monatsnamen in der richtigen Sprache gibt es seit TYPO3 12 formattedDate (ICU-Formate wiedd. MMMM yyyy).strftimeist veraltet. - parseFunc wandelt RTE-Text in HTML um. Für Inhalte aus dem Rich-Text-Editor nimmst du
parseFunc < lib.parseFunc_RTE. - HTMLparser filtert und ändert HTML-Tags, encapsLines packt Zeilen in Absätze, makelinks macht aus URLs Links.
- cache speichert das Ergebnis eines Objekts:
cache.key = footer_{siteLanguage:languageId}mitcache.key.insertData = 1(sonst bleiben die Klammern stehen) undcache.lifetime = 3600. - textStyle und tableStyle stammen aus der Zeit vor CSS und sind längst entfernt. Heute übernimmt CSS diese Aufgabe.
lib.year = TEXT
lib.year {
data = date:U
date = Y
}
lib.created = TEXT
lib.created {
field = crdate
formattedDate = dd. MMMM yyyy
formattedDate.locale = de-DE
}
Top-Level-Objekte
Auf der obersten Ebene stehen feste Namen: page (die Seite), config (Einstellungen für die Ausgabe), lib (eigene Bausteine), plugin (Einstellungen der Extensions), tt_content (wie Inhaltselemente gerendert werden) und styles (von fluid_styled_content). Frames und Framesets aus der alten Referenz gibt es nicht mehr.
page
PAGE ist der Rahmen der HTML-Seite: CSS, JavaScript, Kopfbereich und Inhalt.
page = PAGE
page {
typeNum = 0
shortcutIcon = EXT:site_package/Resources/Public/Icons/favicon.ico
includeCSS {
main = EXT:site_package/Resources/Public/Css/main.css
}
includeJSFooter {
main = EXT:site_package/Resources/Public/JavaScript/main.js
main.defer = 1
}
headerData.10 = TEXT
headerData.10.value = <link rel="preconnect" href="https://fonts.example.org">
10 = PAGEVIEW
10.paths.10 = EXT:site_package/Resources/Private/Templates/
}
Für einen zweiten Seitentyp (z. B. einen Feed) legst du ein weiteres PAGE-Objekt mit eigener typeNum an.
config
config steuert die Ausgabe der ganzen Seite.
config {
sendCacheHeaders = 1
admPanel = 0
concatenateCss = 1
concatenateJs = 1
compressCss = 1
compressJs = 1
disablePrefixComment = 1
htmlTag.attributes.class = no-js
}
Viele bekannte Einstellungen von früher sind heute Site-Konfiguration statt TypoScript: Domain und baseURL, Sprachen (sys_language_uid, language, locale_all), linkVars = L und sprechende URLs (früher realurl). absRefPrefix steht standardmäßig auf auto und muss meist nicht gesetzt werden.
meta
Meta-Tags setzt du unter page.meta. Beschreibung und Robots-Angaben kommen meist schon aus den Seiteneigenschaften (Systemextension seo).
page.meta {
viewport = width=device-width, initial-scale=1
description.field = description
og:title.field = title
og:title.attribute = property
}
Konstanten
Konstanten sind Platzhalter für Werte, die du an einer Stelle pflegst. In TYPO3 13 und 14 sind auch die Site Settings (settings.definitions.yaml im Site Set) als Konstanten verfügbar.
# constants.typoscript
site.logoWidth = 300
# setup.typoscript
lib.logo.file.maxW = {$site.logoWidth}
Content-Objekte
Content-Objekte (cObjects) erzeugen die Ausgabe. Aktuell gibt es: TEXT, COA, COA_INT, CASE, CONTENT, RECORDS, FILES, IMAGE, IMG_RESOURCE, SVG, FLUIDTEMPLATE, PAGEVIEW, HMENU, USER, USER_INT, EXTBASEPLUGIN, LOAD_REGISTER und RESTORE_REGISTER.
TEXT
TEXT gibt einen Wert aus, mit allen stdWrap-Funktionen.
lib.slogan = TEXT
lib.slogan {
value = Das deutschsprachige TYPO3-Forum
wrap = <p class="slogan">|</p>
}
COA
COA (Content Object Array) fasst mehrere Objekte zusammen, sortiert nach ihren Nummern. COA_INT macht dasselbe, wird aber bei jedem Aufruf neu berechnet (nicht gecacht). Nimm es nur, wenn es wirklich nötig ist.
lib.footer = COA
lib.footer {
wrap = <footer>|</footer>
10 = TEXT
10.value = ©
20 = TEXT
20.data = date:Y
20.noTrimWrap = | | |
30 = TEXT
30.value = typo3.net
}
CONTENT und RECORDS
CONTENT holt Datensätze per Abfrage, RECORDS holt bestimmte Datensätze per UID. Für die Inhalte einer Spalte gibt es bei fluid_styled_content den fertigen Baustein styles.content.get.
lib.contentMain = CONTENT
lib.contentMain {
table = tt_content
select {
orderBy = sorting
where = {#colPos}=0
}
}
lib.footerText = RECORDS
lib.footerText {
tables = tt_content
source = 12
}
Ohne pidInList sucht select auf der aktuellen Seite. {#colPos} setzt den Feldnamen sicher in die Abfrage ein.
FLUIDTEMPLATE und PAGEVIEW
Das HTML der Seite kommt heute aus Fluid-Templates. Seit TYPO3 13 ist PAGEVIEW der einfachste Weg: Das Template wird automatisch nach dem Backend-Layout der Seite gewählt.
page.10 = PAGEVIEW
page.10 {
paths.10 = EXT:site_package/Resources/Private/Templates/
variables {
content < styles.content.get
}
dataProcessing.10 = menu
dataProcessing.10.as = mainNavigation
}
In älteren Projekten und für einzelne Bausteine gibt es FLUIDTEMPLATE:
page.10 = FLUIDTEMPLATE
page.10 {
templateName = Default
templateRootPaths.10 = EXT:site_package/Resources/Private/Templates/Page/
partialRootPaths.10 = EXT:site_package/Resources/Private/Partials/Page/
layoutRootPaths.10 = EXT:site_package/Resources/Private/Layouts/Page/
variables.content < styles.content.get
}
Das alte TEMPLATE-Objekt mit Markern (###CONTENT###) gibt es nicht mehr. Wer so ein Projekt aktualisiert, stellt auf Fluid um.
IMAGE und FILES
IMAGE gibt ein Bild aus (siehe imgResource), FILES durchläuft Dateien, zum Beispiel die Bilder aus den Seiteneigenschaften.
lib.pageImage = FILES
lib.pageImage {
references {
table = pages
uid.data = page:uid
fieldName = media
}
maxItems = 1
renderObj = IMAGE
renderObj {
file.import.data = file:current:uid
file.treatIdAsReference = 1
file.width = 1200c
file.height = 600c
altText.data = file:current:alternative
}
}
USER und USER_INT
USER ruft eine eigene PHP-Methode auf, USER_INT dasselbe ungecacht. Die Methode bekommt den bisherigen Inhalt, die Konfiguration und den Request.
lib.hello = USER
lib.hello {
userFunc = Vendor\SitePackage\UserFunc\Hello->render
greeting = Hallo
}
Für Extbase-Plugins gibt es EXTBASEPLUGIN. Die alten PHP_SCRIPT-Objekte sind seit langem entfernt.
CASE
CASE wählt je nach Wert ein anderes Objekt aus.
lib.byLayout = CASE
lib.byLayout {
key.field = layout
default = TEXT
default.value = Standard-Layout
1 = TEXT
1.value = Layout 1
}
LOAD_REGISTER
Register sind Zwischenspeicher: LOAD_REGISTER setzt Werte, getText liest sie mit register:, RESTORE_REGISTER stellt den vorherigen Zustand wieder her.
lib.titleBox = COA
lib.titleBox {
10 = LOAD_REGISTER
10.boxTitle.data = page:title
20 = TEXT
20.data = register:boxTitle
20.wrap = <h2>|</h2>
30 = RESTORE_REGISTER
}
Entfernte Content-Objekte
In der alten Referenz standen viele Objekte, die es in aktuellen TYPO3-Versionen nicht mehr gibt:
| alt | heute |
|---|---|
TEMPLATE (Marker-Templates) |
PAGEVIEW oder FLUIDTEMPLATE |
FILE |
FILES, oder TEXT mit data = path:… |
HTML |
TEXT |
IMGTEXT (Text mit Bild) |
Inhaltselement „Text & Medien“ von fluid_styled_content |
OTABLE, CTABLE, COLUMNS, HRULER, CLEARGIF |
HTML und CSS im Fluid-Template |
FORM |
Systemextension form (Form-Framework) |
SEARCHRESULT |
Systemextension indexed_search oder Solr |
MULTIMEDIA |
FILES und Fluid (Media-ViewHelper) |
PHP_SCRIPT, PHP_SCRIPT_INT, PHP_SCRIPT_EXT |
USER und USER_INT |
EDITPANEL |
Frontend-Bearbeitung per Extension |
HMENU
HMENU erzeugt Menüs aus dem Seitenbaum. Jede Ebene (1, 2, …) ist ein TMENU. Mit special baust du besondere Menüs: directory (Unterseiten einer Seite), list (bestimmte Seiten), rootline (Brotkrumen), language (Sprachwahl), updated, browse, keywords, categories und userfunction.
lib.mainMenu = HMENU
lib.mainMenu {
entryLevel = 0
1 = TMENU
1 {
wrap = <ul class="nav">|</ul>
expAll = 1
NO = 1
NO.wrapItemAndSub = <li>|</li>
ACT = 1
ACT.wrapItemAndSub = <li class="active">|</li>
}
2 < .1
2.wrap = <ul class="subnav">|</ul>
}
# Brotkrumen-Navigation
lib.breadcrumb = HMENU
lib.breadcrumb {
special = rootline
special.range = 0|-1
1 = TMENU
1 {
wrap = <ol class="breadcrumb">|</ol>
NO.wrapItemAndSub = <li>|</li>
CUR = 1
CUR.doNotLinkIt = 1
CUR.wrapItemAndSub = <li aria-current="page">|</li>
}
}
TMENU
TMENU ist ein Textmenü. Wichtige Eigenschaften: wrap (um das ganze Menü), expAll (alle Unterebenen aufklappen) und je Zustand (siehe Item-States) wrapItemAndSub, linkWrap, ATagParams, ATagTitle, stdWrap, doNotLinkIt. In aktuellen TYPO3-Versionen ist es das einzige Menüobjekt.
Item-States
Jeder Menüpunkt hat einen Zustand. Jeder Zustand außer NO muss mit = 1 eingeschaltet werden, sonst gilt NO.
| Zustand | gilt für |
|---|---|
NO |
normale Menüpunkte |
IFSUB |
Menüpunkte mit Unterseiten |
ACT |
Seiten im aktuellen Pfad (Rootline) |
ACTIFSUB |
wie ACT, mit Unterseiten |
CUR |
die aktuelle Seite |
CURIFSUB |
wie CUR, mit Unterseiten |
USR |
Seiten mit Zugriffsbeschränkung für Benutzergruppen |
SPC |
Abstandhalter (Seitentyp „Spacer“) |
MenuProcessor
In Fluid-Projekten baust du Menüs meist nicht mehr mit TMENU, sondern mit dem MenuProcessor: Er liefert die Seiten als Variable, das HTML schreibst du im Template.
page.10.dataProcessing.10 = menu
page.10.dataProcessing.10 {
levels = 2
as = mainNavigation
}
<ul class="nav">
<f:for each="{mainNavigation}" as="item">
<li class="{f:if(condition: item.active, then: 'active')}">
<a href="{item.link}" target="{item.target}">{item.title}</a>
</li>
</f:for>
</ul>
Weitere Varianten: special = rootline für Brotkrumen, special = language für die Sprachwahl. Für Sprachmenüs gibt es außerdem den LanguageMenuProcessor (language-menu).
GMENU, IMGMENU und JSMENU
Grafische Menüs (GMENU, GMENU_LAYERS, GMENU_FOLDOUT), Bildmenüs (IMGMENU), JavaScript-Menüs (JSMENU) und TMENU_LAYERS gibt es nicht mehr. Heute nimmst du ein TMENU oder den MenuProcessor und gestaltest das Menü mit CSS. Ausklapp- und Mega-Menüs entstehen mit CSS und etwas JavaScript.
GIFBUILDER
GIFBUILDER erzeugt Bilder auf dem Server, zum Beispiel Text auf einem Hintergrund oder Bilder mit Rahmen. Er braucht PHP GD, fürs Skalieren und für Effekte zusätzlich ImageMagick oder GraphicsMagick. Die Ebenen sind nummeriert: BOX, TEXT, IMAGE, EFFECT, SHADOW, EMBOSS, OUTLINE, SCALE, CROP, ADJUST, WORKAREA.
lib.badge = IMAGE
lib.badge {
file = GIFBUILDER
file {
XY = 300,80
backColor = #f49700
format = png
10 = TEXT
10 {
text.data = page:title
fontSize = 24
fontColor = #ffffff
offset = 20,50
}
}
}
Für Überschriften als Bild war der GIFBUILDER früher sehr beliebt. Heute nimmst du dafür Webfonts. Nützlich bleibt er für Vorschaubilder, Wasserzeichen und Social-Media-Grafiken.
Plugins
Unter plugin. stehen die Einstellungen der Extensions, meist mit dem Präfix tx_. Extbase-Extensions lesen settings, view und persistence.
plugin.tx_news {
settings {
detailPid = 42
list.paginate.itemsPerPage = 10
}
view {
templateRootPaths.10 = EXT:site_package/Resources/Private/Extensions/News/Templates/
}
}
Mit view.templateRootPaths (und partialRootPaths, layoutRootPaths) überschreibst du die Templates einer Extension, ohne sie selbst zu ändern. Eine höhere Nummer gewinnt.
Weiterführende Links
- TypoScript-Referenz auf docs.typo3.org (englisch, offiziell)
- TypoScript-Syntax und Bedingungen
- Fragen und Antworten im Forum: TypoScript, Menüs, Templates & Layouts und die FAQ
Stand: