TYPO3: Verschiedene Seiten-Templates mit Fluid und BE Layout

Mit der Fluid Template Engine (ab TYPO3 Version 4.3) und dem Backend Layout (ab TYPO3 Version 4.5) kann man mit wenig Aufwand dem Redakteur verschiedene Seiten-Layouts zur Auswahl anbieten, die er über eine Select-Box in den Seiteneigenschaften einer Seite wählen kann (siehe Abbildung).

Das macht Erweiterungen wie z.B. rlmp_tmplselector unnötig. Hier die Schritt-für-Schritt-Anleitung für die Einrichtung und Konfiguration der Seiten-Templates:

1) Backend Layout anlegen

Backend Layouts legt man als Datensätze in einem beliebigen SysFolder ab (außer, man hat eine „General Record Storage Page“ gewählt, dann muss man die Datensätze dort ablegen). Die Erstellung ist sehr einfach, TYPO3 stellt dafür in dem Datensatz einen Wizard zur Verfügung, hier am Beispiel eines einfachen zwei-spaltigen Layouts:

Als „Spaltennummer“ wird eine Zahl vergeben. Diese wird weiter unten verwendet, um den Inhalt einzulesen. Meistens benötigt man als Seiten-Layout ein 1-spaltiges, ein 2-spaltiges und eines, das nur den Seiten-Inhalt (ohne Header, Footer, Randspalten usw.) ausgibt, z.B. für Popups oder Lightboxen.

2) HTML-Templates erstellen

Als nächstes legt man die HTML-Templates für die Seiten-Layouts an. Ich habe dabei folgende Struktur vorliegen:fileadmin/templates/fluid/ für die Seiten-Templatesfileadmin/templates/fluid/layouts/ für die Templates, welche die grobe Struktur der Seite vorgeben (Rahmen-Layout)fileadmin/templates/fluid/partials/ für die Templates, die Seiten-Teile enthalten (z.B. Subnavigationen oder den Kopfbereich). Diese Seiten-Teile können in unterschiedlichen Layouts oder Seiten-Templates eingebunden werden. In diesem Beispiel-Setup werden diese aber nicht benötigt.

fileadmin/templates/fluid/layouts/default.html

<div id="header">...</div>
<div id="content">
  <f:render section="content" />
</div>
<div id="footer">...</div>

fileadmin/templates/fluid/1col.html

<f:layout name="default" />
<f:section name="content">
  <div id="content_main">
    <f:format.html>{content}</f:format.html>
  </div>
</f:section>

fileadmin/templates/fluid/2col.html

<f:layout name="default" />
<f:section name="content">
  <div id="content_main">
    <f:format.html>{content}</f:format.html>
  </div>
  <div id="content_left">
    <f:format.html>{content_left}</f:format.html>
  </div>
</f:section>

fileadmin/templates/fluid/popup.html

<div id="content">
  <f:format.html>{content}</f:format.html>
</div>

Hinweis: Bei mir gab es Probleme mit dem Rendering. Standardmäßig jagt Fluid den Content durch die Rendering-Funktion „parseFunc“ mit den Einstellungen von „lib.parseFunc_RTE“. Allerdings ist in diesen Einstellungen keine iframes, Formulare usw. vorgesehen (diese kann man und soll man über den RTE gar nicht einpflegen), so dass die Tags <iframe> und <form> sichtbar auf der Seite ausgegeben werden. Um das zu verhindern, gibt es mehrere Lösungen:1) Verwendung von „f:format.raw“ (Fluid Version > 1.3.0):

<f:format.raw>{content}</f:format.raw>

2) TypoScript-Objekt direkt einbinden:

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

Und in TypoScript:

lib.content < styles.content.get

3) Ein nicht existierendes Rendering-Setup angeben, z.B. lib.parseFunc_FLUID:

<f:format.html parseFuncTSPath="lib.parseFunc_FLUID">{content}</f:format.html>

Lösung 1 und 2 ist von marcoseiler.de

3) TypoScript Konfiguration

Allgemeine Konfiguration und Zuweisung der Platzhalter

TS Setup

page.10 = FLUIDTEMPLATEpage.10 {
  partialRootPath = fileadmin/templates/fluid/partials/
  layoutRootPath = fileadmin/templates/fluid/layouts/
  variables {
    content < styles.content.get
    content_left < styles.content.get
    content_left.select.where = colPos=1
  }
}

In die Platzhalter „content“ und „content_left“ werden nun die Inhalte eingelesen, die vom Redakteur im Backend in den entsprechenden Spalten angelegt wurde. Gei „content_left“ lesen wir die Inhalte aus „Spaltennummer“ 1 ein, also die Inhalte aus Spalte „Linker Rand“, die weiter oben im Backend Layout definiert wurde.Zuweisung BE Layout zu HTML-TemplateJe nachdem, welches Backend Layout in den Seiteneigenschaften ausgewählt wurde, sollte ein anderes Seiten-Template verwendet werden. Dies geschieht mit diesen TypoScript-Anweisungen:

TS Setup

page.10.file.cObject = CASE
page.10.file.cObject {
  key.data = levelfield:-1, backend_layout_next_level, slide
  key.override.field = backend_layout
  default = TEXT
  default.value = fileadmin/templates/fluid/2cols.html
  2 = TEXT
  2.value = fileadmin/templates/fluid/1col.html
  3 = TEXT
  3.value = fileadmin/templates/fluid/popup.html
}

Standardmäßig wird dabei das 2-Spalten-Layout verwendet (dieses sollte deshalb auch auf der Root-Seite in zwei Select-Boxen für das Backend-Layout ausgewählt werden). Die Templates werden über die IDs der Backend-Layouts zugewiesen. In meinem Fall hat das 1-spaltige Backend-Layout die ID 2, das Popup-Backend-Layout die ID 3.

Optional: CSS Datei einbinden, abhängig von gewählen Layout

page.headerData.10 = CASE
page.headerData.10 {
  stdWrap.wrap = <link rel="stylesheet" type="text/css" href="path/to/css/|" media="all" />
  key.data = levelfield:-1, backend_layout_next_level, slide
  key.override.field = backend_layout
  default = TEXT
  default.value = layout_2col.css
  2 = TEXT
  2.value = layout_1col.css
  3 = TEXT
  3.value = layout_popup.css
}

Hinweis: Ich habe hier das Raute-Symbol (#) als Trennzeichen verwendet, da bei Verwendung einer Pipe (|) mein WordPress-Editor eine fehlerhafte Ausgabe erzeugt.Optional: body-Tag mit Klasse auszeichnenFür das Layout ist es oft nötig, dass man in CSS weiß, welches Layout aktuell gewählt ist. Deshalb kann man dem body-Tag je nach gewählten Layout eine andere Klasse geben:

TS Setup

page.bodyTagCObject = CASE
page.bodyTagCObject {
  stdWrap.wrap = <!!=|>
  key.data = levelfield:-1, backend_layout_next_level, slide
  key.override.field = backend_layout
  default = TEXT
  default.value = layout-2col
  2 = TEXT
  2.value = layout-1col
  3 = TEXT
  3.value = layout-popup
}

19 Kommentare zu “TYPO3: Verschiedene Seiten-Templates mit Fluid und BE Layout”

  1. Sehr guter Ansatz, besten Dank für diesen Artikel.

    Gibt es eine Möglichkeit, das Frontend Layout mit dem Backend Layout zu verknüpfen? Beispiel: Backend Layout: 2 Spalten, Layout 1 – 75% – 25% / Layout 2 25% – 75%?

  2. Hallo Joegi,
    wie man das Frontend Layout über das BE Layout steuert, steht oben im Text unter „Zuweisung BE Layout zu HTML-Template“. Oder habe ich deine Frage falsch verstanden?

  3. Hallo Sven

    Das mit der Zuweisung der Backend Layouts ist mir klar. Meine Frage bezieht sich auf das Feld Frontent Layout in den Seiteneigenschaften vom T3 Backend. 2 Spalten Layouts hat man ja oft in verschiendenen Varianten. Hier wäre es fein, wenn man pro Grid View Template eine Anzahl an FE Layouts definieren könnte.

  4. Ach so. Das ist eine interessante Frage, war bei den Webprojekten, die ich bisher umgesetzt habe, aber nicht nötig. Ich muss zugeben, meistens nutze ich noch TemplaVoila.

  5. Laut backend_layout Autoren ist Frontend Layout hinfällig . Man soll einfach künftig Backend Layout benutzen.

  6. Leicht verständlicher Artikel, hat mir sehr geholfen, Danke!

    Trotzdem habe ich eine Frage zu deinen TypoScript-Beispielen.

    Was ein wrap macht weiss ich. Aber was hierbei passiert und rauskommen soll, verstehe ich nicht:

    stdWrap.wrap = !!

    Wäre dir für eine kurze Erklärung sehr dankbar.

  7. Danke für den Hinweis, Johannes. Die fehlerhafte Ausgabe beim wrap war bedingt durch den WordPress-Editor, der anscheinend Probleme bei Escapen von HTML-Code in Verbindung mit einer Pipe hat.

  8. Danke für die Erklärung, Sven :-)
    Auch dein letztes Code-Beispiel für das body-Tag hat diesen Fehler.

    Gruß, Johannes.

  9. Hallo, Sven,
    vielen Dank für den Interessanten Artikel. Ich werde in einem zukünfitgen Projekt auf TemplaVoila verzichten und diesen Ansatz testen. In Verbindung mit gridelements bestimmt eine feine Sache.

    @Joegi: Wenn es unterschiedliche Varianten – beispielsweise von einem 2-spaltigem Layout gibt, könnte man einfach mehrere Backend-Layouts definieren. Duch unterschiedliche Icons könnte der Redakteur diese unterscheiden. Die explizite Zuweisung (Backend-Layout / Frontend-Layout) ist meiner Meinung nach für den Redakteur nicht benutzerfreundlich. Der Redakteur soll in den Seiteneigenschaften unter Erscheinungsbild einfach das Layout wählen und fertig.

    Freue mich auf Feedback!

    Viele Grüße
    Jan

  10. Hallo !

    In deinem Beispiel ist bei der TypoScript Config welche aufgrund des verwendeten BE-Layouts das FE-Template auswählt das „stdWrap“ unnötig.

    Also anstelle von:
    page.10.file.stdWrap.cObject = CASE

    Tut es auch ein:
    page.10.file.cObject = CASE

    grüße,
    Bernhard

  11. Hallo Bernhard,

    danke für den Hinweis, ich bin immer glücklich, wenn ich etwas optimieren und vereinfachen kann :)

  12. Hallo,
    schöner Beitrag!
    allerdings gibt es im letzte CodeSchnipsel – dem TypoScript für den BodyTag – einen kleinen Fehler: „split“ ist eine Eigenschaft von wrap, korrekt muss dort also stehen:

    stdWrap.wrap.splitChar = #

    (meiner Meinung nach wird der spezielle splitChar aber garnicht benötigt und das Pipe-Symbol tut es auch (oder habe ich was übersehen?))

    viele Grüße

  13. Hi, danke für den Beitrag. Ich habe das bei mir sehr ähnlich umgesetzt. Hat super funktionert.
    Eines ist mir nicht klar, ich habe bei mir noch ein 2tes Seitenlayout (page type 98) für eine Druckversion.

    Wenn ich mit innerhalb eines Spaltenlayouts festlege dass die default.html aussenrum als Seitenlayout verwendet wird, wie bekomme ich es dann hin dass aussenrum bei type=98 ein print.html verwendet werden soll?

    Danke
    Alex

  14. Hallo Alex,

    du könntest für jedes Backend-Layout-Template ein entsprechendes zweites Template für die Druckansicht anlegen:
    page.10.file.cObject.2.value = fileadmin/templates/fluid/1col_print.html
    Und in diesem Template dann statt <f:layout name=“default“ /> das Haupt-Druck-Template einlesen: <f:layout name=“print“ />

    Andererseits stehe ich solchen alternativen, für den Druck optimierten Layouts kritisch gegenüber, ich finde die Optimierung für den Ausdruck per CSS und media=“print“ sauberer. Für die druckoptimierten Seiten solltest du auf jeden Fall die Indexierung durch Suchmaschinen verhindern

  15. Genau diesen Beitrag hab ich gesucht gehabt. Sonst müsste ich wirklich auf jeder Seite ein Template zuweisen im Typoscript. Das hätte kein Spaß gemacht und dem Kunden schon gar nicht.

    Danke.

  16. Super!

    Ein nicht existierendes Rendering-Setup, wie

    <f:format.html parseFuncTSPath="lib.parseFunc_FLUID">{content}</f:format>

    sorgt auch dafür, dass die Werte HTML-formatiert ohne zusätzliche „\n“-Umbrüche ausgegeben werden.

    So lassen sich Javascriptvariablen füllen oder ähnliches.

  17. Hallo!

    Ich danke Dir für diese tolle Hilfestellung! Dadurch bin ich auf einiges gekommen und mir wurde so manches klarer!

    Großes Lob also von mir!

    lg

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.