Ziel: Dieser Artikel zeigt kompakt und praxisnah, wie du in TYPO3 12 Inhalte aus tt_content per TypoScript und DataProcessing holst und im Fluid‑Template ausgibst. Du bekommst sofort einsetzbare Snippets plus Hinweise zu Performance, Mehrsprachigkeit und typischen Stolpersteinen.
TYPO3 12 – Inhalte gezielt „herausangeln“

Wann nutze ich was?
- CONTENT: Wenn du eine Menge tt_content-Elemente aus einer (oder mehreren) Seiten/Spalten rendern willst – mit dem Standard‑Rendering von tt_content.
- RECORDS: Wenn du gezielt konkrete UIDs rendern möchtest (z. B. aus FlexForms oder manueller Auswahl).
- DatabaseQueryProcessor: Wenn du die Datensätze als Array im Fluid‑Template brauchst (z. B. für eigene Loops/Strukturen) und optional trotzdem das Standard‑Rendering verwenden willst.
1) CONTENT: Inhalte der aktuellen Seite aus einer bestimmten Spalte (colPos
)
lib.column0Content = CONTENT
lib.column0Content {
table = tt_content
select {
pidInList = this # current page
where = colPos=0 # pick a column
orderBy = sorting
}
renderObj =< tt_content # use default tt_content rendering
}
Fluid‑Beispiel:
<f:cObject typoscriptObjectPath="lib.column0Content" />
Tipp: Für weitere Spalten einfach colPos
anpassen (z. B. 1, 2, …).
2) CONTENT: Inhalte von anderer Seite (per PID) + Filter nach CType
lib.textmediaFromPid = CONTENT
lib.textmediaFromPid {
table = tt_content
select {
pidInList = 123 # replace with your PID
where = colPos=0 AND CType='textmedia'
orderBy = sorting
}
renderObj =< tt_content
}
Fluid‑Beispiel:
<f:cObject typoscriptObjectPath="lib.textmediaFromPid" />
RECORDS: Konkrete Elemente per UID auswählen (z. B. aus FlexForm) → meine Lieblingsmethode 🖤
lib.byUids = RECORDS
lib.byUids {
tables = tt_content
source = 123,124,125 # list of tt_content UIDs
dontCheckPid = 1 # allow cross-page rendering if needed (use with care)
}
Fluid‑Beispiel:
<f:cObject typoscriptObjectPath="lib.byUids" />
Achtung: dontCheckPid = 1
nur setzen, wenn du wirklich seitenübergreifend rendern willst. Rechte/Struktur beachten.
4) FLUIDTEMPLATE + DatabaseQueryProcessor (Records als Array im View)
Mit dem DatabaseQueryProcessor bekommst du Rohdaten im Fluid‑Template. Du kannst sie selbst loopen oder für einzelne Elemente das Standard‑Rendering triggern.
page.10 = FLUIDTEMPLATE
page.10 {
templateName = Default
# set your templateRootPaths / partialRootPaths / layoutRootPaths as usual
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
table = tt_content
pidInList = this
where = colPos=0
orderBy = sorting
as = contentRecords # variable available in Fluid
# language handling is taken from site context during rendering
}
}
}
Fluid‑Beispiel: eigenes Looping und optional Standard‑Renderer pro Datensatz verwenden:
<f:for each="{contentRecords}" as="record">
<!-- custom output using fields from {record} -->
<article class="ce ce-{record.CType}">
<h3>{record.header}</h3>
<p>{record.bodytext}</p>
</article>
<!-- OR render with default tt_content rendering for a record -->
<f:cObject typoscriptObjectPath="tt_content" data="{record}" />
</f:for>
Mehrsprachigkeit (Kurzüberblick)
- Beim Rendering über
tt_content
(CONTENT/RECORDS mitrenderObj =< tt_content
) übernimmt der TYPO3‑Frontend‑Kontext die Sprachüberlagerung automatisch. - Im DatabaseQueryProcessor werden – je nach Site‑Kontext – in der Regel bereits lokaliserte Datensätze geliefert. Wenn du explizit nur Standardsprache willst, nutze z. B.:
where = sys_language_uid IN (0,-1)
Performance & Sauberkeit
- orderBy = sorting: Nutze die redaktionelle Reihenfolge.
- dontCheckPid sparsam: Nur wenn wirklich seitenübergreifend nötig.
- Konsistenz: Einheitliche colPos‑Konventionen im Team (z. B. 0=Main, 1=Sidebar, 2=Footer …).
- Cachen lassen: Standardmäßig sind die Objekte gecacht. Nur in Ausnahmefällen no_cache-Logik nutzen.
Typische Stolpersteine
- Nichts wird gerendert: Prüfe colPos, pidInList, where und ob die Inhalte evtl. versteckt/zeitgesteuert sind.
- Doppelte Ausgabe: Nicht gleichzeitig dieselbe Spalte per CONTENT und zusätzlich nochmal im Template ausgeben.
- Records ohne Standard‑Rendering: Wenn du DataProcessing nutzt, aber das Default‑Rendering erwartest, musst du pro Datensatz tt_content via <f:cObject ... data="{record}" /> aufrufen.
Mini‑Checkliste (Copy & Go)
- Welche Quelle? this oder PID‑Liste?
- Welche Spalte(n)? colPos klar?
- Reihenfolge? orderBy = sorting gesetzt?
- Sprache? Vom Site‑Kontext abgedeckt oder explizit filtern?
- Müssen es konkrete UIDs sein? → RECORDS.
- Brauche ich Rohdaten im Fluid? → DatabaseQueryProcessor.
TL;DR – Schnellsteinstieg
# Main column of current page (standard rendering)
lib.main = CONTENT
lib.main {
table = tt_content
select {
pidInList = this
where = colPos=0
orderBy = sorting
}
renderObj =< tt_content
}
Für gezielte UIDs:
lib.byUids = RECORDS
lib.byUids {
tables = tt_content
source = 123,124
}
- TYPO3-Entwicklung mit DDEV und Docker – Der ultimative Leitfaden
- Extbase-Controller und PSR-7 Responses in TYPO3 11
TypoScript