Zum Inhalt springen

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.typoscript und constants.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 Beispiel lib.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 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 wie dd. MMMM yyyy). strftime ist 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} mit cache.key.insertData = 1 (sonst bleiben die Klammern stehen) und cache.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.

Stand: