PixelConsult - Full Service Internet Agentur

TYPO3 DCE Tutorial

Dynamic Content Elements, kurz DCE, ist eine Extension für die neueren Typo3 Versionen (ab 6.2). Sie arbeitet mit dynamischen Elementen und ersetzt damit die flexiblen Content Elemente, die in TemplaVoila verwendet wurden. Dieses wird seit Typo3 6.2 nicht mehr unterstützt, da Typo3 seitdem verstärkt auf „FLUID“ und die dazu gehörenden „View Helper“ setzt. Der große Vorteil der View Helper ist es, das „for-Schleifen“ und „if-Abfragen“ verwendet werden können.

Mit DCE lassen sich sehr schnell neue Content Elemente anlegen. Durch die Verwendung von Fluid und damit der Bedingungen und Abfragen, lassen sich auch komplizierte Templates schnell anlegen. Ein großer Vorteil ist die getrennte Darstellung von angelegten Eingabe-Elementen und Template. Durch die sehr geordnete und übersichtliche Anzeige der Eingabe-Elemente im Backend ist auch für einen ungelernten Redakteur die Dateneingabe leicht.

Im Großen und Ganzen ist die Extension ziemlich selbsterklärend und für Entwickler, wie auch Redakteure, einfach zu verwenden.
Wer sich in Fluid-Programmierung auskennt, hat natürlich klare Vorteile. Aber auch für Entwickler, die sich damit noch nicht auskennen, ist sie schnell zu durchschauen.

Problematisch ist leider, dass es (noch) keine ausführliche Dokumentation zu der Extension gibt. Das liegt wohl daran, dass der Entwickler allein ist. Man muss aber sagen, dass er sich viel Mühe gibt und in jedem weiteren Update haben sich schöne neue Funktionen und gute Fixes befunden.

Einfache Erklärungen und kleine Beispiele helfen oft schnell weiter. Da wir die Extension vor einiger Zeit entdeckt haben und uns am Anfang immer nur sehr langsam weiterbewegt haben, da oft nur Kleinigkeiten nicht richtig waren, haben wir uns dazu entschlossen, für alle Interessierten eine kleine Anleitung zu schreiben, wie man mit der Extension umgeht.

Es handelt sich um Beschreibungen und Bilder der Extension-Version 1.3.6.

Tabs

Auf den einzelnen Tabs lassen sich die Eingabe-Elemente für das Backend definieren, die Vorlage für das Frontend festlegen und einige weitere Einstellungen vornehmen.

Tab Allgemein

Auf dem Tab Allgemein wird der Titel des DCEs festgelegt. Hier gibt es auch die Option, den Typ des DCEs zu verändern. Datenbankbasiert ist jedoch die einzige Auswahlmöglichkeit.

Mit Inaktiv lässt sich festlegen, ob das DCE im Backend überhaupt eingesetzt werden darf. Wenn man dieses Auswahlfeld wählt, dann werden alle Instanzen dieses DCEs als ungültig angezeigt.

Eingabefelder

Unter "Felder"lässt sich festlegen, welche Eingabefelder dem Redakteur im Backend angezeigt werden und wie diese aussehen sollen. Wird ein neues Feld erzeugt, so müssen zunächst zwei Felder ausgefüllt werden.

 

Das erste bestimmt den "Titel dieses Feldes", der dem Redakteur im Backend zu dem Feld angezeigt wird. Im zweiten wird eine, in diesem DCE eindeutige, "Variable"angegeben. Diese wird dazu verwendet, um im Template die Stelle anzugeben, an der die Eingaben des Feldes verwendet werden sollen.

Das Feld kann drei unterschiedliche Typen besitzen: ElementReiter (Tab) oder Abschnitt (Sektion).

Elemente

Ein "Element" kann diverse Konfigurationen zugewiesen bekommen.

Die unten im Bild dargestellten Konfigurationen sind möglich:

TYPE: input

  • Mit "Simple input field" wird ein einfaches Eingabefeld erzeugt.
  • Mit "Typolink" wird auch ein einfaches Eingabefeld erzeugt. In dieses lässt sich jedoch mit Hilfe eines Wizards eine Verlinkung einfügen. Das Besondere ist, das man nicht nur eine interne Seite, sondern auch einen einzelnen Datensatz auswählen kann.
    Wird auf den Button für den Wizard geklickt, öffnet sich das Standard Typo3 Fenster zum Einfügen von Verlinkungen. Auf diesem kann eine interne Seite, eine Datei, ein Ordner, eine Externe URL oder eine E-Mail Adresse ausgewählt werden.

TYPE: text

  • Mit "Full RTE" wird ein komplexes Eingabefeld, mit allen möglichen Bearbeitungsfeldern, erzeugt, in dem eine umfassende Textbearbeitung möglich ist.
  • Mit "Inherit RTE from TSconfig" wird dasselbe komplexe Eingabefeld erzeugt, wie mit "Full RTE". Welche Bearbeitungsfelder angezeigt werden, lässt sich hier jedoch im TSconfig definieren.
  • Die "Simple Textarea" erzeugt ein einfaches mehrzeiliges Eingabefeld, bei dem es keine weiteren Bearbeitungsmöglichkeiten gibt.

TYPE: check

  • Mit "Simple checkbox" wird eine einfache Checkbox erzeugt. Diese kann vom Redakteur im Backend aktiviert werden.

TYPE: select

  • Die "Automatical list of items" erzeugt eine automatische Liste aller vorhanden Seiten.
  • Die "Manual list of items" erzeugt eine Liste mit Elementen, die man selbst definieren kann. Wenn man den Befehl <onchange>reload</onchange> aktiviert, wird die Seite bei der Eingabe im Backend neu geladen und es können so zusätzliche Elemente angezeigt werden.

TYPE: group

  • Mit Hilfe von "File upload" kann im Backend eine Bild-Datei ausgewählt werden.
  • Mit Hilfe von "Link internal page with suggest wizard" kann eine interne Seite ausgewählt werden, zu der oder dem verlinkt wird.
  • Mit Hilfe von "Link Pages and get pages as associative array" kann eine Reihe von internen Seiten oder Datensätzen ausgewählt werden, zu denen verlinkt werden kann.

TYPE: miscellaneous

  • Mit "Color Picker" lässt sich ein Eingabefeld erzeugen, in das mit Hilfe eines Wizards eine Farbe eingetragen werden kann.
  • Die "Display Conditions" lassen sich zu jedem Elemententyp hinzufügen. Sie sorgen dafür, dass ein Element nur unter bestimmten Bedingungen angezeigt wird. Zum Beispiel nur dann, wenn in einer "Manual list of items" das <onChange>reload</onChange> aktiviert ist. Allerdings ersetzen sie die gesamte bereits festgelegte Konfiguration. Das bedeutet, dass man diese vor dem einfügen der Display Conditions sichern sollte.

TYPE: FAL

  • Mit "File Abstraction Layer (recommended)" lässt sich eine Datei im Fileadmin auswählen und einbinden.
  • Mit "File Abstraction Layer (section use only)" lässt sich innerhalb einer Sektion eine Datei im Fileadmin auswählen und einbinden.

Tab

Ein "Tab" erzeugt bei der Dateneingabe im Backend einen neuen Reiter. Alle Elemente oder Sektionen, die unterhalb eines Tabs angeordnet sind werden im Backend auf diesem Tab dargestellt. Es müssen keine Tabs erstellt werden.

Aber sobald ein Tab als erstes im DCE erstellt wird, wird das Standard „Allgemein“ Tab entfernt und durch das benutzerdefinierte ersetzt. Alle weiteren Tabs werden ergänzend hinzugefügt. Wenn nur ein einziges benutzerdefiniertes Tab vorhanden ist, wird dieses im Backend nicht angezeigt. Wichtig ist, dass ein Tab nur angezeigt wird, wenn sich auch ein Element darauf befindet. Ansonsten wird es im Backend ausgeblendet.

Sektion

Eine "Sektion" besteht aus einer Gruppe von beliebigen Elementen.

Im Backend kann die Sektion nicht nur einmal verwendet werden, wie ein Feld, sondern nach Belieben oft. Der Sektion können durch die Schaltfläche "Test" unten immer neue Gruppen von Elementen hinzugefügt werden. Diese lassen sich einzeln löschen und ihre Reihenfolge kann geändert werden.

Tab Template

Auf dem Tab "Template" wird die Darstellung der Eingabe-Felder definiert. Der Code besteht aus Fluid-Programmierung und HTML.

Das Template kann hier einerseits in das Textfeld eingegeben werden und andererseits auch durch eine Datei geladen werden. Dazu wird der Template-Typ von "Inline" auf "Datei" geändert.

Durch einen Klick auf das weiße Feld unter "Template-Inhalt (Fluid)" können die Variablen der vorher definierten Eingabefelder ausgewählt werden. Zusätzlich gibt es noch "Basis-Variablen" und "Viewhelper". Mit Hilfe der Basis-Variablen können zum Beispiel die Seiteneigenschafften ausgewählt werden. Die Viewhelper gehören zur FLUID-Programmierung. Es gibt allgemein verwendete und für die DCEs vom Entwickler geschriebene Helfer. Außerdem ist es auch möglich eigene Viewhelper hinzuzufügen.

Tab DCE-Container

Mit Hilfe des DCE-Containers werden alle Objekte dieses DCEs, die nacheinander im Backend eingefügt werden, in einen Container gelegt. Wie dieser Container aussehen soll, wird in diesem Template definiert. So kann zum Beispiel ein Rahmen definiert werden, in dem dann die Objekte angezeigt werden. Auf diese Weise lässt sich zum Beispiel eine Bilder-Galerie erstellen.Wenn jedoch ein Objekt eines anderen DCEs eingefügt wird, so wird der Container geschlossen. Wird danach wieder ein Objekt des Container-DCEs eingefügt, so wird ein neuer Container eröffnet.

Das Limit gibt an, wie viele Objekte sich in einem Container befinden dürfen. Ein Limit von "0" bedeutet unendlich viele Objekte. Bei einem Limit von zum Beispiel "5" würde nach fünf Objekten der Container geschlossen und für das sechste Objekt ein neuer Container eröffnet. Außerdem lässt sich ein neuer Container eröffnen, indem bei der Eingabe eines neuen Objektes der Haken bei "Neuen DCE-Container bilden" gesetzt wird.

Beispiel

Wenn folgender Code im DCE-Container-Template steht:

  1. <f:section name="main">
  2. <div class="row">
  3. <f:render partial="Container/Dces" arguments="{dces:dces}" />
  4. <div>
  5. </f:section>

Und dann fünf Objekte des Container-DCEs hintereinander im Backend eingefügt werden, dann erscheinen diese alle gemeinsam in einem <div>:

Wird danach ein Objekt eines anderen DCEs eingefügt und dann wieder drei des Container-DCEs, entsteht:

Tab Backend Template

Das "Backend Template" beschreibt, wie gespeicherte Objekte des DCEs im Backend aussehen. Dazu kann einmal der einfache Modus gewählt werden:

Dabei können alle vorhandenen Elemente und Sektionen für die Anzeige ausgewählt werden. Das sieht dann bei einem gespeicherten Objekt dieses DCEs im Backend so aus:

Die zweite Möglichkeit ist ein eigenes Template zu schreiben:

Hierzu können einige HTML und FLUID Codes verwendet werden, um die Anzeige zu gestalten. Dazu muss der {namespace} aus dem normalen Template übernommen werden. Dann können alle Felder, die in diesem DCE definiert sind, eingefügt werden:

  1. {namespace dce=ArminVieweg\Dce\ViewHelpers}
  2. <f:image src="fileadmin/img/{field.bild}" width="200" height="auto"/>
  3. <f:format.html>{field.header}</f:format.html>
  4. <f:format.html>{field.text}</f:format.html>

Dieses Template erzeugt dann diese Ansicht bei einem gespeicherten Objekt:

Tab Icon & Wizard

Auf diesem Tab kann das Icon ausgewählt werden, mit dem das DCE im Backend angezeigt werden soll. Zusätzlich kann man hier auch bestimmen, ob das DCE überhaupt angezeigt werden soll. Zusätzlich kann die Wizard Kategorie und die Beschreibung bestimmt werden.

Das DCE Icon kann aus einer Reihe von Symbolen ausgewählt werden. Es kann aber auch ein eigenes Icon verwendet werden. Dieses wird dann im Backend angezeigt, wenn ein neues Inhaltselement erzeugt werden soll.

Tab Detailseite

Auf der Detailseite kann man angeben, welche Zusatzinformationen zu einem Objekt angezeigt werden sollen.

Damit dies funktioniert, muss zunächst ein Button im normalen Template untergebracht werden. Dieser lautet zum Beispiel:

  1. <f:link.page additionalParams="{detailDceUid:contentObject.uid}">Weiter</f:link.page>

Durch diesen wird auf der aktuellen Seite die ID dieses speziellen DCE-Objektes aufgerufen und die zusätzlichen Informationen ausgelesen, die sich auf der Detailseite befinden. Mit dem Button:

  1. <f:link.page pageUid="{page.uid}">Zurück</f:link.page>

kann dann wieder zur Original-Seite zurückgekehrt werden.

Beispiel

Wird im Template:

  1. <f:section name="main">
  2. <div>
  3. <h1>{field.header}</h1>
  4. <p>{field.text}</p>
  5. <f:link.page additionalParams="{detailDceUid:contentObject.uid}">Weiter</f:link.page>
  6. </div>
  7. </f:section>

und auf der Detailseite:

  1. <f:section name="main">
  2. <div>
  3. <h1>{field.header}</h1>
  4. <p>{field.text}</p>
  5. <p>Hier gibt es weitere Informationen</p>
  6. <f:link.page pageUid="{page.uid}">Zurück</f:link.page>
  7. </div>
  8. </f:section>

definiert, dann erhält man zunächst:

Nach einem Klick auf "Weiter" ändert sich die Seite zu:

Tab Sonstiges

Hier kann man definieren welche Tabs und Paletten-Felder, wie zum Beispiel Sprache, im Backend dargestellt werden sollen.

Konfigurationen

Wenn direkt aus dem Dropdown Feld „Konfigurationen“ ausgewählt wird, dann wird immer die Standard-Konfiguration ausgewählt. Diese kann einfach so verwendet werden. Aber diese kann auch verändert werden.

TYPE:input

Mit Hilfe eines "simple input field" lässt sich auch eine automatische Datumsauswahl erzeugen. Dafür wird einfach das <eval>trim</eval> mit einem <eval>date</eval> ersetzt

  1. <config>
  2. <type>input</type>
  3. <size>30</size>
  4. <eval>date</eval>
  5. </config>

Das ergibt dann folgende Ansicht im Backend:

Um diese Eingabe dieses Feldes im Frontend ausgeben zu können muss der date-ViewHelper verwendet werden. Dieser lautet:

  1. <f:format.date>{field.datum}</f:format.date>

Das Ergebnis ist dann: "22-02-17".

Um das Datum in eine andere Form zu bringen, kann man auch verwenden:

  1. <f:format.date date="{field.datum}" format="y-m-d" />

Das Ergebnis lautet dann: "17-02-22".

TYPE:check

Auch bei einer Checkbox können weitere Felder hinzugefügt und sogar mit <cols> in einer Zeile angezeigt werden. Dazu wird der ursprüngliche Code wie folgt erweitert:

  1. <config>
  2. <type>check</type>
  3. <items type='array'>
  4. <numIndex index='0' type='array'>
  5. <numIndex index='0'>Label A</numIndex>
  6. <numIndex index='1'>0</numIndex>
  7. </numIndex>
  8. <numIndex index='1' type='array'>
  9. <numIndex index='0'>Label B</numIndex>
  10. <numIndex index='1'>1</numIndex>
  11. </numIndex>
  12. <numIndex index='2' type='array'>
  13. <numIndex index='0'>Label B</numIndex>
  14. <numIndex index='1'>2</numIndex>
  15. </numIndex>
  16. </items>
  17. <minitems>0</minitems>
  18. <maxitems>3</maxitems>
  19. <cols>3</cols>
  20. </config>

 Das ergibt dann folgendes Bild:

TYPE:select

Die "Automatical list of items" zeigt, wenn man die Standard Konfiguration nicht verändert, eine Liste aller vorhandenen Unterseiten in der Reihenfolge ihrer Seiten-Ids. Wenn man die angezeigte Reihenfolge in die im Seitenbaum angezeigte ändern will, oder bestimmen will, welche Unterseiten angezeigt werden, muss die Konfiguration um folgendes ergänzt werden:

  1. <foreign_table_where>AND pages.pid = 5 ORDER BY pages.sorting</foreign_table_where>

 Wenn man die Konfiguration zu

  1. <config>
  2. <type>select</type>
  3. <foreign_table>pages</foreign_table>
  4. <renderType>selectMultipleSideBySide</renderType>
  5. <minitems>0</minitems>
  6. <maxitems>10</maxitems>
  7. <config>

 ändert, dann wechselt die Ansicht der Auswahl wie folgt:

Wenn nun die Konfiguration noch um

  1. <multiple>1</multiple>

erweitert wird, können Elemente mehrfach ausgewählt werden.

 

Mit Hilfe von

  1. <enableMultiSelectFilterTextfield>1</enableMultiSelectFilterTextfield>

Kann zum rechten Auswahlfeld eine dynamische Suche hinzugefügt werden:

Eine weitere Auswahlansicht ist

  1. <renderType>selectCheckBox</renderType>

Mit dem Ergebnis:

Außerdem gibt es noch eine Baumansicht:

  1. <config>
  2. <type>select</type>
  3. <renderType>selectTree</renderType>
  4. <foreign_table>pages</foreign_table>
  5. <treeConfig>
  6. <parentField>pid</parentField>
  7. <appearance>
  8. <expandAll>1</expandAll>
  9. </appearance>
  10. </treeConfig>
  11. <maxitems>5</maxitems>
  12. </config>

Diese lässt sich mit:

  1. <rootUid>5</rootUid>

direkt unter <parentField> auf die ID einer Unterseite beschränken.

 

Soll bei der "Manuel list of items" das erste, standardmäßig ausgewählte Element leer sein, dann muss in der Konfiguration das erste Label leer bleiben. Zum Beispiel, wenn man die Header-Ebene auswählen möchte, dann sieht die Konfiguration wie folgt aus:

  1. <config>
  2. <type>select</type>
  3. <items type='array'>
  4. <numIndex index='0' type='array'>
  5. <numIndex index='0'> </numIndex>
  6. <numIndex index='1'>0</numIndex>
  7. </numIndex>
  8. <numIndex index='1' type='array'>
  9. <numIndex index='0'>H1</numIndex>
  10. <numIndex index='1'>1</numIndex>
  11. </numIndex>
  12. <numIndex index='2' type='array'>
  13. <numIndex index='0'>H2</numIndex>
  14. <numIndex index='1'>2</numIndex>
  15. </numIndex>
  16. <numIndex index='3' type='array'>
  17. <numIndex index='0'>H3</numIndex>
  18. <numIndex index='1'>3</numIndex>
  19. </numIndex>
  20. </items>
  21. <size>1</size>
  22. <minitems>1</minitems>
  23. <maxitems>1</maxitems>
  24. </config>

Das ergibt dann im Backend folgende Ansicht:

Bis auf die Baum-Ansicht können auch hier alle <renderType> verwendet werden.

 

Möchte man zu jedem der Elemente der manuellen Liste ein Bild oder Icon hinzufügen, so ist dies möglich durch:

  1. <numIndex index="1" type="array">
  2. <numIndex index="0">Layout 1</numIndex>
  3. <numIndex index="1">1</numIndex>
  4. <numIndex index="2">EXT:dce/layout1.jpg</numIndex>
  5. </numIndex>

Das entsprechende Bild muss im Ordner "typo3conf/ext/dce" vorhanden sein. Bei dem Standard-<renderType> müssen für alle Elemente Bilder angegeben werden. Dann ergibt dies folgende Ansicht:

Sollen die Icons auch unter der Auswahl angezeigt werden, muss folgende Zeile hinzugefügt werden:

  1. <showIconTable>1</showIconTable>

Wenn man

  1. <renderType>selectCheckBox</renderType>

verwendet, dann kann auch noch eine Beschreibung (description) hinzufügen mit Hilfe von:

  1. <numIndex index="1" type="array">
  2. <numIndex index="0">Layout 1</numIndex>
  3. <numIndex index="1">1</numIndex>
  4. <numIndex index="2">XT:dce/layout1.jpg</numIndex>
  5. <numIndex index="3">Beschreibung</numIndex>
  6. </numIndex>

Das sieht wie folgt aus:

TYPE:group

Wird "File upload" ausgewählt, dann sieht die Standard-Konfiguration wie folgt aus:

  1. <config>
  2. <type>group</type>
  3. <internal_type>file</internal_type>
  4. <allowed>jpg,jpeg,png,gif</allowed>
  5. <size>1</size>
  6. <minitems>0</minitems>
  7. <maxitems>1</maxitems>
  8. <uploadfolder>uploads/pics</uploadfolder>
  9. <show_thumbs>1</show_thumbs>
  10. </config>

Dadurch wird die im Backend ausgewählte Datei zu dem Ordner "uploads/pics" hinzugefügt. Jede erneute Auswahl des Bildes fügt das Bild wieder zu diesem Ordner hinzu und versieht es hinten mit einer fortlaufenden Nummer. Dadurch ist die Verwaltung der Bilder relativ schwer und sie lassen sich nicht so einfach ersetzen, da das Bild an jeder Stelle von Hand ausgetauscht werden muss. Man kann den Ordner natürlich ändern, aber auch entfernen. Dazu löscht man die gesamte Zeile <uploadfolder>. Dann wird keine neue Datei erzeugt, sondern direkt die Datei aus dem Backend verwendet. Es wird jedoch keine Verknüpfung auf die Datei gelegt. Das bedeutet, sie kann ohne Fehlermeldung über das Backend gelöscht werden und kann dann im Frontend nicht mehr angezeigt werden.

 

Mit Hilfe von "Link Pages and get pages as associative array" kann eine Reihe von Bildern schnell eingebunden werden. Benötigt wird dazu eine "Dateisammlung", wie sie Backend von Typo3 erzeugt werden kann. Die Konfiguration für dieses Element wird wie folgt geändert:

  1. <config>
  2. <type>group</type>
  3. <internal_type>db</internal_type>
  4. <allowed>sys_file_collection</allowed>
  5. <size>5</size>
  6. <minitems>0</minitems>
  7. <maxitems>999</maxitems>
  8. <show_thumbs>1</show_thumbs>
  9. <dce_load_schema>1</dce_load_schema>
  10. </config>

TYPE:miscellaneous

Wenn unter Konfiguration die „Display Conditions“ ausgewählt werden erhält man nur:

  1. <displayCond>FIELD:settings.relatedField:=:1</displayCond>

Dabei wird abgefragt, ob in einem Auswahlfeld eine bestimmte Auswahl getroffen wurde. Will man mehrere überprüfen, so benötigt man für eine Oder-Abfrage (OR):

  1. <displayCond>
  2. <OR>
  3. <numIndex index="0">FIELD:settings.detailauswahl:=:1</numIndex>
  4. <numIndex index="1">FIELD:settings.detailauswahl:=:2</numIndex>
  5. </OR>
  6. </displayCond>



und für eine Und-Abfrage (AND):

  1. <displayCond>
  2. <AND>
  3. <numIndex>FIELD:settings.detailauswahl:=:1</numIndex>
  4. <numIndex>FIELD:settings.bildauswahl:=:2</numIndex>
  5. </AND>
  6. </displayCond>

 

Der wichtige Unterschied zwischen AND und OR ist, dass bei einer OR-Abfrage jeder Überprüfung ein Index hinzugefügt werden muss. 

Konfiguration: Radiobuttons

Wenn der Type einer Checkbox von "check" zu "radio" geändert wird, können Radiobuttons verwendet werden:

  1. <config>
  2. <type>radio</type>
  3. <items type="array">
  4. <numIndex index="0" type="array">
  5. <numIndex index="0">Auswahl0</numIndex>
  6. <numIndex index="1">0</numIndex>
  7. </numIndex>
  8. <numIndex index="1" type="array">
  9. <numIndex index="0">Auswahl1</numIndex>
  10. <numIndex index="1">1</numIndex>
  11. </numIndex>
  12. <numIndex index="2" type="array">
  13. <numIndex index="0">Auswahl2</numIndex>
  14. <numIndex index="1">2</numIndex>
  15. </numIndex>
  16. </items>
  17. </config>

Wizard-Konfiguration: Tabelle

In den DCEs ist es leider nicht möglich eine Tabellenkonfiguration auszuwählen. Es ist aber möglich eine eigene Konfiguration für den Typo3 Standard Tabellen Wizard zu schreiben. Dazu benötigt man noch einen eigenen Tabellen ViewHelper, der die Daten entsprechend umsetzt. 

  1. <config>
  2. <type>text</type>
  3. <size>500</size>
  4. <row>500</row>
  5. <col>20</col>
  6. <wizards>
  7. <_PADDING>2</_PADDING>
  8. <link>
  9. <type>script</type>
  10. <title>LLL:EXT:cms/locallang_ttc.xlf:bodytext.W.table</title>
  11. <icon>content-table</icon>
  12. <module>
  13. <name>wizard_table</name>
  14. <urlParameters>
  15. <mode>wizard</mode>
  16. </urlParameters>
  17. </module>
  18. <params>
  19. <numNewRows>1</numNewRows>
  20. </params>
  21. </link>
  22. </wizards>
  23. </config>

 

Und führt zu dieser Ausgabe im Backend:

Ein Klick auf den Button öffnet den Wizard:

Wenn Daten in den Wizard eingegeben und gespeichert werden, dann sieht dies so aus:

FLUID-Programmierung

Die Templates der DCEs werden mit Fluid-Programmierung festgelegt. Das bedeutet, sie alleine bestimmen, wie die Backend-Eingaben im Frontend ausgegeben werden.

Fluid ist eine "Template engine". Sie ist einfach zu verwenden und zu erweitern. Diese Art der Programmierung wird seit einiger Zeit in Typo3 selbst und auch in den neueren Extensionen verwendet. Daher kommt sie auch in der Extension DCE zum Einsatz.

Ein großer Vorteil von Fluid ist es, dass sich bequem Abfragen, Schleifen und Bedingungen mit HTML und CSS verbinden lassen. 

Template Datei

Das Template kann in einer externen Datei geschrieben. Auf diese Weise lassen sich Templates schnell in verschiedenen Typo3 Systemen verwenden und einfacher in verschiedene Unter-Templates aufteilen.

Inline Template

Die zweite Möglichkeit ist, das Template direkt "Inline" auf diesem Reiter zu definieren. Dies ist sinnvoller, wenn ein einfaches Template verwendet wird, welches sich nicht in einem anderen DCE wiederholt.

Standardmäßig ist diese Möglichkeit ausgewählt. Die Standardvorgabe eines Inline-Templates sieht folgendermaßen aus:

  1. {namespace dce=ArminVieweg\Dce\ViewHelpers}
  2. <f:layout name="Default" />
  3. <f:section name="main"
  4. Your template goes here...
  5. </f:section> 

Der "namespace" beschreibt den Ort, an dem sich die entsprechenden Dateien in der Ordner-Struktur befinden. 

Mit <f:layout> wird das umschließende Layout bestimmt. Im Standardfall ist dies bei den DCEs festgesetzt als "Default" und fügt damit ein umschließendes <div> ein:

  1. <div class="tx-dce-pi1"
  2. Your template goes here...
  3. </div>

Soll das umschließende <div> entfernt werden, muss das "Default" durch ein "None" ersetzt werden. Dann wird ein leeres Layout verwendet.

  

Innerhalb der Section "main" wird das eigentliche Template geschrieben. Dort lassen sich die vorher definierten Variablen einfügen.

Über Die Schaltfläche "Template-Inhalt" lassen sich Variablen und einige "ViewHelper" direkt auswählen. Ein ViewHelper ist ein vordefiniertes Stück Code, das dabei hilft die eingegebenen Inhalte in der gewünschten Form umzusetzen.

Verfügbare Variablen

Wird nun eine der Variablen ausgewählt, wird sie folgendermaßen eingefügt:

  1. <f:section name="main">
  2. {field.text}
  3. </f:section>

Nun wird einfach die im Backend in das Eingabefeld gemachte Eingabe, bei Test als Klartext, bei Mehrfacheingabe als Array oder sonstiges, ausgegeben. Weitere Spezifikationen siehe nächste Kapitel.

Verfügbare Basis-Variablen

  • {dce} – Informationen über das DCE
    • {dce.uid} – gibt die ID des DCE zurück
    • {dce.title} – gibt den Titel des DCEs zurück
  • {contentObject} – Informationen über die Instanz
    • {contentObject.uid} – gibt die ID der DCE-Instanz zurück
    • {contentObject.pid} – gibt die Seiten-ID zurück, auf der sich die DCE-Instanz befindet
  • {TSFE} – TSFE-Objekt (tslib_fe)
    • {TSFE.id} – gibt die Seiten-ID zurück
    • {TSFE.lang} – gibt die aktuelle Sprache zurück
  • {page} – Informationen über die Seite
    • {page.uid} – gibt die Seiten-ID zurück
    • {page.pid} – gibt die DCE-ID zurück
    • {page.title} – gibt den Seitentitel zurück
  • {tsSetup} – ermöglicht Zugriff auf das Seiten TS

Meist verwendete View-Helper

f:count

  1. <f:count subject="{subject}" />

Zählt die Anzahl der Elemente inerhalbs eines Arrays


f:debug

  1. <f:debug>{subject}</f:debug>

Gibt alle Eigenschaften des Objekts als Debug aus

 

f:for

  1. <f:for each="{items}" as="item" iteration="iterator"></f:for>

Lässt eine FOR-Schleife über ein Array laufen

 

f:format.crop

  1. <f:format.crop maxCharacters="30">{text}</f:format.crop>

Verkürzt einen Text auf maximal 30 Buchstaben.

 

f:format.html

  1. <f:format.html>{text}</f:format.html> 

Verwendete HTML-Tags werden auch als solche umgesetzt

 

f:format.nl2br 

  1. <f:format.nl2br>{text}</f:format.nl2br>

Rahmen für PHPs nl2br Funktionen

 

f:if

  1. <f:if condition=""><f:then></f:then><f:else></f:else></f:if>

IF-Abfrage zur Überprüfung von Eigenschaften

 

f:image

  1. <f:image src="uploads/pics/{image}" alt="" />

Bindet ein Bild ein

 

f:link.email

  1. <f:link.email email="your@mailaddress.tld">Content</f:link.email>

E-Mail-Verlinkung

 

f:link.external

  1. <f:link.external uri="http://www.typo3.org" target="_blank">Website</f:link.external>

Verlinkt auf eine externe Website

 

f:link.page

  1. <f:link.page pageUid="1">Page</f:link.page>

Verlinkt per Seiten-ID auf eine interne Seite

 

f:render

  1. <f:render partial="NameOf/Partial" arguments="{fields:fields}" />

Rendert eine externe Partial-Datei

 

 

Text rendern

Texte können ganz normal mit <p> eingefügt werden. Dies gilt jedoch nur, wenn in den Eingabefeldern, egal ob RTE oder normales Feld, reiner Fließtext eingegeben wird. Wenn dort auch HTML-Tags verwendet werden, der Text aber nur als

  1. <f:section name="main">
  2. {field.text}
  3. </f:section>

eingebunden wird, dann werden die Tags auch als Klartext ausgegeben. Man erhält dann zum Beispiel mit der Eingabe: 

Die Ausgabe:

    <ul><li>Text ... </li><li>Text ... </li><li>Text ...</li></ul>

Um dies zu verhindern muss der Text mit dem "f.format.html-ViewHelper" gerendert werden:

  1. <f:section name="main">
  2. <f:format.html>{field.text}</f:format.html>
  3. </f:section>

Dann wird der Text auch als richtige Liste ausgegeben.

Bilder einfügen

Ein Bild kann auf unterschiedliche Arten eingefügt werden. Erst einmal ist wichtig, mit welcher Methode das Bild ausgewählt werden soll.

Dazu gibt es TYPE:group "File upload" und TYPE:fal "File Abstraction Layer". Wobei sich letzteres in Sektion und nicht Sektion unterteilt. 

TYPE:group „File upload“

Wenn das Bild mit Hilfe von "File upload" eingebunden wurde, kann es direkt mit dem "f:image-ViewHelper" eingefügt werden. Dazu muss der "uploadfolder" angegeben werden, wenn er in der Konfiguration festgelegt wurde. Gibt es dort keinen, dann reicht die Angabe der Variablen. Die Standardangabe wäre also:

  1. <f:image src="uploads/pics/{field.image}" alt="" />

Das Ergebnis ist ein normaler <img> HTML-Tag.

Wird der "File Abstraction Layer" verwendet, so lässt sich das Bild als FAL-Objekt einbinden. Dazu wird der "dce:fal-ViewHelper" verwendet:

  1. <f:for each="{dce:fal(field:'image', contentObject:contentObject)}" as="fileReference" />
  2. <f:image src="{fileReference.uid}" treatIdAsReference="1" />
  3. </f:for>

Das Ergebnis ist auch hier ein normaler <img>-Tag. Die "fileReference" lässt sich durch eine beliebige Bezeichnung ersetzen. Dies ist zum Beispiel nötig, wenn mehrere Dateien ineinander verschachtelt werden müssen.

Das FAL-Element kann auch als Hintergrundbild eingebaut werden:

  1. <f:for each="{dce:fal(field:'image', contentObject:contentObject)}" as="fileReference" />
  2. <div style="background-image: url('{f:uri.image(src:'{fileReference.uid}', treatIdAsReference='1')}');" /></div>
  3. </f:for>

 

Ab der Version 1.4 ist es möglich FAL-Bilder auch direkt, ohne den "dce:fal-ViewHelper". einzubinden. Dazu wird dann verwendet:

  1. <f:for each="{field.image}" as="fileReference" />
  2. <f:image image=&quot;{fileReference}&quot; />
  3. </f:for>

Dazu müssen zur Konfiguration zwei Zeilen hinzugefügt werden, diese sind aber in der neuen Standard-Konfiguration direkt vorhanden:

  1. <dce_load_schema>1</dce_load_schema>
  2. <dce_get_fal_objects>1</dce_get_fal_objects> 

Wird das Bild als FAL eingebaut, so kann eine Bildbeschreibung angegeben werden

Wenn man diese Bildbeschreibung im Frontend ausgeben möchte, muss dafür im DCE-Template folgender Code verwendet werden:

  1. <f:for each="{dce:fal(field:'image', contentObject:contentObject)}" as="fileReference">
  2. <f:image src="{fileReference.uid}" treatIdAsReference="1">
  3. <p>{fileReference.description}</p>
  4. </f:for>

Genauso kann auch die Title {fileReference.title}, der Alt-Tag {fileReference.alternative} und die Verlinkung {fileReference.link} verwendet werden. Das Problem ist nur, wenn das Bild ausgetauscht werden soll, zum Beispiel einfach durch dasselbe Bild mit einer besseren Qualität, dann ändern sich ja alt-Text, Titel und Beschreibung nicht. Von daher ist es empfehlenswert diese Informationen über zusätzliche Eingabefelder hinzuzufügen.

TYPE:fal „File Abstraction Layer (section use only)“

Wird ein FAL-Element in einer Sektion verwendet, dann wird das Bild nicht als "image", sondern als "file" eingebunden:

  1. <f:for each="{field.bilder}" as="bilder">
  2. <f:for each="{bilder.image -> dce:explode()}" as="imageUid">
  3. <img src="<f:uri.image src="file:{imageUid}" />">
  4. </f:for>
  5. </f:for>

 

Das geht natürlich auch als Hintergrundbild:

  1. <f:for each="{field.bilder}" as="bilder">
  2. <f:for each="{bilder.image -> dce:explode()}" as="imageUid">
  3. <div style="background-image:url('<f:uri.image src="file:{imageUid}" />')">
  4. </f:for>
  5. </f:for>

Responsive Bilder

Bilder sind durch FAL auch leicht responsiv verwendbar. Es wird einfach das Bild im größten verwendeten Format hochgeladen und die View-Helper sorgen für die verschiedenen Skalierungen des Bildes:

  1. <f:for each="{dce:fal(field:'image', contentObject:contentObject)}" as="fileReference">
  2. <picture>
  3. <source srcset="<f:uri.image src="{fileReference.uid}" treatIdAsReference="1" width="400" height="auto" />" media="(max-width: 400px)">
  4. <source srcset="<f:uri.image src="{fileReference.uid}" treatIdAsReference="1" width="700" height="auto" />" media="(max-width: 700px)>
  5. <source srcset="<f:uri.image src="{fileReference.uid}" treatIdAsReference="1" width="1000" height="auto" />" media="(max-width: 1000px)">
  6. <img src="<f:uri.image src="{fileReference.uid}" treatIdAsReference="1" width="1000" height="auto" />" >
  7. </picture>
  8. </f:for>

Das ergibt dann im HTML-Code:

  1. <picture>
  2. <source srcset="_processed_/csm_image_d299f7ab95.jpg" media="(max-width: 400px)">
  3. <source srcset="_processed_/csm_image_390vnj3099.jpg" media="(max-width: 700px)">
  4. <source srcset="_processed_/csm_image_8d7e1e819e.jpg" media="(max-width: 1000px">
  5. <img src="image.jpg">
  6. </picture>

Wichtig ist, das hinter source srcset stehen muss, während hinter img nur src stehen darf. Letzteres sorgt dafür, dass der Internet Explorer überhaupt etwas anzeigen kann und ersteres wird von allen anderen Browsern für die responsiven Bilder verwendet.

 

 

Eine weitere Möglichkeit ist es, Bilder mit Hilfe von Typoscript responsiv einzubinden. Dazu wird zunächst in Typoscript definiert, wie die responsiven Bilder aussehen sollen:

  1. lib{
  2. responsiveImage = IMAGE
  3. responsiveImage {
  4. file {
  5. import.current = 1
  6. treatIdAsReference = 1
  7. }
  8. layoutKey = picture
  9. layout {
  10. picture {
  11. element = <picture>###SOURCECOLLECTION###<img src="###SRC###" /></picture>
  12. source = <source srcset="###SRC###" media="###MEDIAQUERY###" />
  13. }
  14. }
  15. sourceCollection {
  16. small {
  17. width = 400
  18. mediaQuery = (max-width: 420px)
  19. }
  20. medium {
  21. width = 700
  22. mediaQuery = (max-width: 768px)
  23. }
  24. big {
  25. width = 1000
  26. mediaQuery = (max-width: 1024px)
  27. }
  28. }
  29. }
  30. }

 

Dann kann ein FAL-Bild einfach als cObject eingebunden werden:

  1. <f:for each="{field.image}" as="image">
  2. <f:cObject typoscriptObjectPath="lib.responsiveImage" data="{image.uid}"></f:cObject>
  3. </f:for>

 

 

 

Verlinkungen

Bei Verlinkungen wird zwischen internen und externen Links unterschieden. Beide Verlinkungen können auf unterschiedliche Weisen verwendet werden. Eine „unschöne“ aber funktionierende Lösung ist ein einfaches Eingabefeld, in das die Verlinkung geschrieben wird und dann mit einem <a>-Tag aufgerufen wird:

  1. <a href="{field.link}">Page</a>

Dies funktioniert immer mit externen und internen Links, hat aber den Nachteil, das absolute Verlinkungen angegeben werden müssen. 

Es gibt vier Konfigurationen mit denen sich Verlinkungen einbauen lassen:

  • TYPE:input “Typolink”
  • TYPE:select “Automatical list of items”
  • TYPE:group “Link internal page with suggest wizard”
  • TYPE:group “Link pages and get pages as associative array”

Die erste Möglichkeit eignet sich für interne, externe und Anker Verlinkungen, sowie die Auswahl von Dateien und E-Mail-Verlinkungen.
Wenn man eine Unterseite und einen Datensatz mit Hilfe von TYPE:input "Typolink" auswählt, dann wird im Frontend die Seiten-Id und die Datensatz-Id zurückgegeben. Es ist also sowohl möglich den "f:link.page-ViewHelper":

  1. <f:link.page pageUid="{field.link}">Page</f:link.page>

oder der "dce:typolink-ViewHelper" zu verwenden:

  1. <dce:typolink parameter="{field.link}";>Page</dce:typolink>

Wenn eine externe URL ausgewählt worden ist, dann bietet es sich an den "f:link.external-ViewHelper" zu verwenden:

  1. <f:link.external uri="{field.link}" target="_blank">Website</f:link.external>

Bei der Auswahl einer E-Mail-Adresse muss jedoch einer der beiden ViewHelper für interne Verlinkungen gewählt werden. Diese fügen dann vor der E-Mail-Adresse direkt ein "mailto:" ein.

Externe Verlinkungen

Bei einer externen Verlinkung ist normalerweise sowieso ein absoluter Link gegeben. Daher bietet sich ein einfaches Eingabefeld an, das dann mit dem "f:link.external-ViewHelper" verwendet wird:

  1. <f:link.external uri="{field.link}" target="_blank">Website</f:link.external>

Interne Verlinkungen

Mit folgenden drei Möglichkeiten, können ausschließlich interne Verknüpfungen zu Unterseiten erzeugt werden:

  • TYPE:select "Automatical list of items"
  • TYPE:group "Link internal page with suggest wizard"
  • TYPE:group "Link pages and get pages as associative array"

Die Rückgabe ist dabei jeweils die Seiten-Id. Um dieses auszuwerten, wird entweder der "f:link.page-ViewHelper":

  1. <f:link.page pageUid="{field.link}">Page</f:link.page>

oder der "dce:typolink-ViewHelper" verwendet:

  1. <dce:typolink parameter="{field.link}">Page</dce:typolink>

Ankerpunkte

Wenn ein Punkt auf derselben Seite, also ein Ankerpunkt erreicht werden soll, so kann dies einfach durch die Seiten-Id umgesetzt werden:

  1.  <f:link.page pageUid="{contentObject.pid}#{field.link}">Page</f:link.page>

oder:

  1.  <dce.typolink parameter="{contentObject.pid}#{field.link}">Page</typolink>

Tabelle

Tabellen-Konfiguration im FLUID verwenden zu können, muss man einen neuen ViewHelper definieren.

Dieser muss in den Ordner "EXT:dce/Classes/ViewHelpers" unter dem Namen "TabelleViewHelper.php" gespeichert werden und kann zum Beispiel so aussehen wie der von hier:

  1. <?php
  2. namespace ArminVieweg\Dce\ViewHelpers;
  3. use TYPO3\CMS\Core\Utility\GeneralUtility;
  4. class TabelleViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
  5.    /**
  6.    * @var \TYPO3\CMS\CssStyledContent\Controller\CssStyledContentController
  7.    * @inject
  8.    */
  9.    protected $cscController;
  10.     /**
  11.     * @var \TYPO3\CMS\Extbase\Configuration\ConfigurationManager
  12.     * @inject
  13.     */
  14.    protected $configurationManager;
  15.     /**
  16.     * Arguments Initialization
  17.     */
  18.     public function initializeArguments() {
  19.       $this->registerArgument('table', 'string', 'Die Tabellen-Daten, Delimiter ist das Pipe-Symbol', false, null);
  20.       $this->registerArgument('layout', 'string', 'Die Zahl, die an der Klasse contenttable-XX erscheint', false, null);
  21.    }
  22.      /**
  23.      * Rendert die Tabelle mit csc_styled_content
  24.      */
  25.      public function render() {
  26.        if (!$this->arguments['table']) {
  27.          $this->arguments['table'] = html_entity_decode($this->renderChildren());
  28.       }
  29.        $this->cscController->cObj = $this->configurationManager->getContentObject();
  30.       $this->cscController->cObj->data = $this->arguments;
  31.       return $this->cscController->render_table( null, array('field'=>'table') );
  32.     }
  33. }
  34. ?>

Dann wird die Tabelle ganz normal als Tabelle angezeigt.

 

Wenn das Einfügen der Tabelle direkt über die Variablen funktionieren soll, muss unter "EXT:/dce/Resources/Public/CodeSnippets/DceViewHelpers" eine Datei namens "tabelle.html" vorhanden sein, mit folgendem Inhalt:

  1. <dce:tabelle>{tabelle}</dce:tabelle>

IF-Abfragen

Eine IF-Abfrage besteht aus einer "condition", der Bedingung, einem "then"-Teil und einem "else"-Teil. Zunächst wird abgefragt, welche Bedingung erfüllt sein muss, um entweder bei Erfüllung den "then"-Teil, oder bei nicht Erfüllung den "else"-Teil auszuführen. Wobei der "else"-Teil auch weggelassen werden kann. IF-Abfragen können beliebig oft verschachtelt werden.

  1. <f:if condition="">
  2. <f:then>

  3. </f:then>
  4. <f:else>

  5. </f:else>
  6. </f:if>

Mit einer IF-Abfrage kann gesteuert werden, welcher HTML-Code im Frontend ausgegeben wird. Zunächst kann überprüft werden, ob ein Inputfeld generell ausgefüllt worden ist. Und dann gibt es zwei Möglichkeiten, wie die Eingaben für IF-Abfragen aussehen können. Mit einer Checkbox kann zum Beispiel  "entweder - oder" abgefragt werden und mit einer manuellen Liste lassen sich die eingegebenen "conditions" abfragen.

Vermeidung von leeren HTML-Tags

Mit Hilfe einer IF-Abfrage kann dann verhindert werden, das leere HTML-Elemente eingebaut werden. Wenn zum Beispiel einbaut wird:

  1. <h1>{field.header}</h1>

ergibt dies einen leeren HTML <h1>-Tag, wenn im Backend in das Feld für "header" nichts eingetragen wurde. Wird stattdessen geschrieben

  1. <f:if condition="{field.header}">
  2. <f:then>
  3. <h1>{field.header}</h1>
  4. </f:then>
  5. </f:if>

dann wird kein <h1>-Tag eingefügt, wenn das Feld für "header" nicht ausgefüllt wurde.

Manuelle Liste

Bei einer manuellen Liste können alle vorgegebenen Auswahl-Möglichkeiten überprüft werden. Zum Beispiel, die Auswahl der Header-Ebene. In der manuellen Liste werden die Auswahlmöglichkeiten "H1", "H2" und "H3" gegeben. Mit der IF-Abfrage kann man dann den entsprechenden Code ausgeben:

  1. <f:if condition="{field.headerebene}==1">
  2. <f:then>
  3. <h1>{field.headerebene}</h1>
  4. </f:then>
  5. </f:if>
  6. <f:if condition="{field.headerebene}==2">
  7. <f:then>
  8. <h2>{field.headerebene}</h2>
  9. </f:then>
  10. </f:if>
  11. <f:if condition="{field.headerebene}==3">
  12. <f:then>
  13. <h3>{field.headerebene}</h3>
  14. </f:then>
  15. </f:if>

Checkbox

Mit einer Checkbox kann zum Beispiel ausgewählt werden, ob ein Text fett sein soll oder nicht. Von der IF-Abfrage wird hier nun der Zustand geprüft. Wobei eine ausgefüllte Box ein "true" zurück gibt, und somit den "then"-Teil auslöst und eine nicht ausgefüllte "false" und damit den "else"-Teil. Zum Beispiel, wenn abgefragt wird, ob der Text fett sein soll, oder nicht:

  1. <f:if condition="{field.textfett}">
  2. <f:then>
  3. <b>{field.text}</b>
  4. </f:then>
  5. <f:else>
  6. {field.text}
  7. </f:else>
  8. </f:if>

FOR-Schleifen

Wenn eine Sektion verwendet wird, dann müssen die Eingaben aus dieser mit einer FOR-Schleife ausgegeben werden:

  1. <f:for each="{field.testsektion}" as="test">
  2. <h1>{test.header}</h1>
  3. </f:for>

Sollen nicht alle Elemente aus seiner Sektion verwendet werden, so lässt sich das zum Beispiel über einen Iterator steuern:

  1. <f:for each="{field.testsektion}" as="test" iteration="iterator">
  2. <f:if condition="{iterator.index} <= 5">
  3. <f:then>
  4. <h1>{test.header}</h1>
  5. </f:then>
  6. </f:if>
  7. </f:for>

Das bedeutet, dass nur die ersten fünf Iterationen der Sektion ausgegeben werden. Achtung, der Iterator beginnt bei 0 zu zählen! Mit folgendem Code lässt sich nur die erste Iteration ausgeben:

  1. <f:for each="{field.testsektion}" as="test" iteration="iterator">
  2. <f:if condition="{iterator.isFirst}">
  3. </f:then>
  4. <h1>{test.header}</h1>
  5. </f:then>
  6. </f:if>
  7. </f:for>

Wenn mit "Link Pages and get pages as associative array" eine Dateisammlung eingefügt werden soll, wird auch dafür eine FOR-Schleife verwendet:

  1. <f:for each="{field.testgroup}" as="collection">
  2. <f:for each="{collection.items}" as="item">
  3. <f:image src="{item.uid}" treatIdAsReference="{f:if(condition:'{item.originalFile}',then: '1', else: '0')}" />
  4. </f:for>
  5. </f:for>

Mit Hilfe von FOR-Schleifen ist es auch möglich einer Reihe von <div>-Elementen eine fortlaufende ID zuzuweisen:

  1. <f:for each="{field.items}" as="item" iteration="iterator">
  2. <div id="unique-name-{iterator.index}"></div>
  3. </f:for>

Soll die ID nicht nur auf dieser Seite, sondern allgemein einzigartig sein, so ist dies über die UID der Seite möglich. Diese wird mit {contentObject.pid} ausgelesen:

  1. <f:for each="{field.items}" as="item" iteration="iterator">
  2. <div id="unique-name-{contentObject.pid}-{iterator.index}"></div>
  3. </f:for>

Tipps und Beispiele

Tabs

Für eine bessere Übersichtlichkeit und einfachere Nutzung durch den Redakteur lassen sich die Tabs verwenden. Zum Beispiel kann man ein Tab für Text erstellen, eines für Bilder und eines für Videos. Mit Hilfe von If-Abfragen kann überprüft werden, welche von den Feldern ausgefüllt worden sind und diese dann entsprechend anzeigen lassen.

Überschrift und Text

Eine Überschrift lässt sich am einfachsten mit einem einfachen "Input-Field" einfügen. Für den Text lässt sich besser ein "Inherit RTE from TSconfig" verwenden, da in einem Fließtext häufig vom Redakteur Einstellungen vorgenommen werden müssen, wie zum Beispiel Listen oder Verlinkungen. Im Backend sieht das so aus:

In einem Template muss nun definiert werden, wie das Ergebnis im Frontend aussehen soll. Dazu müssen die vergebenen Variablen eingesetzt werden. Die Überschrift kann einfach in einen <h2>-Tag gesetzt werden, während der Text von einem View-Helper umgeben werden muss, damit die im Backend vorgenommenen HTML-Programmierungen umgesetzt werden können, denn ansonsten würden die HTML-Codierungen direkt ausgegeben werden. Dann würde zum Beispiel, bei einem manuell gesetzten <br>, kein Zeilenumbruch gemacht, sondern der Text „<br>“ ausgegeben.

  1. {namespace dce=ArminVieweg\Dce\ViewHelpers}
  2. <f:layout name="Default"/>
  3. <f:section name="main">
  4. <h2>{field.header}</h2>
  5. <f:format.html>{field.text}</f:format.html>
  6. </f:section>

Wenn im Backend vom Redakteur keine HTML-Codierungen von Hand hinzugefügt werden, dann wird der gesamte eingefügte Text durch ein umschließendes <p></p> eingerahmt.

Bildergalerie

Wenn in einer Bildergalerie lediglich Bilder dargestellt werden sollen, kann ein einfaches FAL-Objekt verwendet werden.  

Sollen zu den Bildern jeweils noch Texte vermerkt werden, lässt sich dies durch eine Sektion verwirklichen. Das Problem ist allerdings, das sich zu einer DCE-Instanz nicht beliebig viele Objekte hinzufügen lassen. Das bedeutet, im schlimmsten Falle kann man die Instant nicht mehr erweitern. Außerdem wird es schnell unübersichtlich, wenn es zu viele Elemente gibt.

 

Einfacher ist es, wenn man für jedes Element der Galerie eine eigene DCE-Instanz im Backend erzeugt. Man verwendet also bei der Erstellung des DCEs keine Sektion, sondern fügt die Eingabe-Felder direkt ein. Dann aktiviert man den DCE-Container und schreibt ein <div> um die gerenderten Elemente. Dann werden alle Bilder innerhalb dieses <div> angezeigt:

  1. <f:section name="main">
  2. <div class="wrapper">
  3. <f:render partial="Container/Dces" arguments="{dces:dces}">
  4. </div>
  5. </f:section>

Mit Hilfe von entsprechendem CSS und JS Code erzeugt man sich dann seine Bildergalerie.

Eine Bildergalerie, die auf diese Weise erzeugt wurde, gibt es hier

Jedes einzelne Produkt ist eine neue Instanz eines DCEs. Diese besteht aus einem Bild und einem Namen. Dann lässt sich auswählen, welchen Detaillierungsgrad das Bild haben soll.

Wird nun der letzte Punkt ausgewählt, so erweitern sich die Eingabemöglichkeiten. Es ist leider nicht möglich Eingabefelder auf anderen Tabs zu erzeugen.

Video und Poster per FAL

Wenn zum Beispiel ein Video und ein entsprechendes Poster per FAL ausgewählt werden können, dann erfolgt die Ausgabe für das Frontend durch folgenden Code:

  1. <f:for each="{dce:fal(field:'video', contentObject:contentObject)}" as="video">
  2. <f:for each="{dce:fal(field:'poster', contentObject:contentObject)}" as="poster">
  3. <video poster="{f:uri.image(src:'{poster.uid}',treatIdAsReference:'1')}">
  4. <source src="{f:uri.image(src:'{video.uid}',treatIdAsReference:'1')}"/>
  5. </video>
  6. </f:for>
  7. </f:for>

Mehrsprachigkeit

Wenn man zum Beispiel einen Button einbauen möchte, der immer den gleichen Text enthalten soll, so kann man diesen ja einfach fest kodieren im DCE. Hat man aber mehrere Sprachen auf der Website, so geht das nicht mehr ganz so einfach. Aber mit Hilfe einer "lang.xml" Datei und einem Verweis auf diese, ist auch das Problem leicht zu lösen. Man erstellt also eine lang.xml mit folgendem Inhalt:

  1. <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
  2. <T3locallang>
  3. <meta type="array">
  4. <typ>module</type>
  5. <description>Language labels for the DCEs in backend</description>
  6. </meta>
  7. <data type="array">
  8. <languageKey index="de" type="array">
  9. <label index="buttontext">Weiter</label>;
  10. </languageKey>
  11. <languageKey index="default" type="array">
  12. <label index="buttontext">Weiter</label>
  13. </languageKey>
  14. </data>
  15. </T3locallang>

Und schreibt dann ins FLUID-Template:

  1. <a href="#">
  2. <f:translate key="LLL:fileadmin/lang/dce.xml:buttontext">
  3. </a>

Auf diese Weise können mehrere Sprachen definiert werden. Wichtig ist nur zu wissen. Das Englisch, also "en" immer "default" ist. Auch wenn die eigentliche Default-Sprache Deutsch ist.

Vermeidung von leeren HTML-Tags

Erst einmal ist es so, dass ein einfaches Textfeld und ähnliche Elemente „required“ sind. Wenn es aber für den Redakteur möglich sein soll, nicht alle Textfelder ausfüllen zu müssen, so muss in der Konfiguration anstelle von

  1. <eval>trim,required</eval>

stehen:

  1. <eval>trim</eval>

Dann kann mit Hilfe einer IF-Abfrage verhindert werden, dass ein leerer Tag eingefügt wird, wenn das Feld nicht ausgefüllt wurde:

  1. <f:if condition="{test.header}">
  2. <f:then>
  3. <h1>{test.header}</h1>
  4. </f:then>
  5. </f:if>

Ist das Feld nicht ausgefüllt, so passiert einfach gar nichts. Steht in dem Feld etwas, wird der Tag samt Inhalt hinzugefügt.

Mit Hilfe von FLUID kann man in einem DCE auch einfach den Seitentitel einer Website auslesen und direkt ausgeben.

  1. <f:if condition="{page.navtitle}">
  2. <f:then>
  3. <h1>{page.navtitle}</h1>
  4. </f:then>
  5. <f:else>
  6. <h1>{page.title}</h1>
  7. </f:else>
  8. </f:if>

PDF einbinden

Ein PDF kann mit Hilfe von FAL-Objekten genauso wie ein Bild oder Video eingefügt werden. Wenn man aber hier den selben Code wie bei einem Bild verwendet, wird lediglich ein Bild der PDF angezeigt. 

Will man einen Button "Download" erzeugen, bei dem sich die PDF-Datei öffnet, so muss dies mit "publicUrl" umgesetzt werden:

  1. <f:for each="{field.pdf}" as="pdf">
  2. <a href="{pdf.publicUrl}" target="_blank">Download</a>
  3. </f:for>

Gleichzeitig kann man auch ein Bild der PDF anzeigen, bei dem sich dann auch der Download auf Klick öffnet:

  1. <f:for each="{field.pdf}" as="pdf">
  2. <a href="{pdf.publicUrl}" target="_blank">
  3. <f:image image="{pdf}"/>
  4. </a>
  5. </f:for>