TYPO3 7 LTS Fluid Styled Content: Spezialmenü "Auflistung der Unterseiten" mit Bild aus Seiteneigenschaften

Update vom 03.05.2016: Dieser Artikel ist nicht mehr ganz aktuell. Es gibt eine neue Variante mit DataProcessing, welche ich in einem neuen Artikel zum Thema FAL Bilder im FLUIDTEMPLATE vorstelle.

 

Zum Artikel "DataProcessor, GridElements und FAL Bilder im FluidTemplate (4 Beginners)"


Die TYPO3 7 LTS bringt als Nachfolger von CSS Styled Content (css_styled_content) eine neue und bessere Extension für Inhaltselemente mit: Fluid Styled Content (fluid_styled_content). Diese Extension bringt das neue Text & Media Element mit, ausserdem sind die Spezialmenüs, um Beispielsweise eine automatische Auflistung der Unterseiten im Inhaltsbereich zu ermöglichen, hier auch enthalten. Der Vorteil von Fluid Styled Content liegt an den Fluid Templates die genutzt werden können. Hier ist es relativ einfach, die Templates in den eigenen Template Ordner in /fileadmin auszulagern und anzupassen. In diesem Artikel geht es um die Spezialmenüs, da es hier zwei Fallstricke gibt: In den Fluid Templates ist es nicht möglich, auf die in den Seiteneigenschaften hinterlegten Bilder im Reiter Media zu zugreifen. Ausserdem stimmt die Sortierung bei selbst hinzugefügten Seiten nicht mit der Eingabebebox oder dem Seitenbaum überein. Um dass zu ändern, zeige ich hier eine von mehreren Möglichkeiten.

 
Background: Warum ist es mit TYPO3 7.6.0 denn nicht möglich, die Bilder anzuzeigen?

Der Umstand ist wohl dem derzeitigen Stand des TYPO3 Cores geschuldet. Dem Fluid Template werden Variablen übergeben, mit denen man auf die Felder der Seite Zugriff  hat. Das für uns relevante Feld heisst "media". Dummerweise ist in diesem Feld nur eine Zahl gespeichert. Keine UID einer Datei oder einer File Reference, nein, nur die Anzahl der Dateien, die Verknüpft wurden. Die Dateien selbst werden über die Tabelle sys_file_reference verbunden. Unter Fluid gibt es aber derzeit keine Möglichkeit, auf sys_file_reference zu zugreifen. Wir haben also keine Bordmittel zur Verfügung, um eine Auflösung des Feldes "media" auf die Tabelle "sys_file" über "sys_file_reference" zu machen. Das ist ziemlich doof.

 
Die Lösung heisst (leider oder Gott sei Dank "vhs")

Nunja, über das fluidtypo3.org Projekt gibt es vermutlich genauso viele Zugeneigte wie auch Abgeneigte Entwickler und Integratoren. Allerdings ist wohl unumstritten, das dieses Projekt eine Menge nützlicher Werkzeuge mitbringt, die einem das Leben einfacher machen. Für TYPO3 7 LTS empfiehlt sich die Nutzung der Version "development", da diese auf dem neusten Stand ist (https://fluidtypo3.org/viewhelpers/vhs/development.html).

 
Und was benötige ich davon nun genau?

"Eigentlich" nur den v:resource.record.fal Aber: Zusätzlich zu dem fehlenden Zugriff auf die Bildresourcen gibt es ja noch ein Bug mit der Sortierung, wenn das Spezialmenü "Menü ausgewählter Seiten" (Type: 0) genutzt wird. Die Sortierung, die im Feld in welches die Seiten eingetragen werden müssen, wird nicht beachtet. Eigentlich auch nicht die Sortierung der Seiten im Seitenbaum (zumindest wenn die Auswahl über mehrere Ebenen geht). Schuld daran ist der ViewHelper "ce:menu.list". Um den Bug zu beseitigen, sollte ce:menu.list durch den v:iterator.explode ersetzt werden. Bei der automatischen Auflistung "Menü der Unterseiten ausgewählter Seiten mit Inhaltsangabe" (Type: 4) ist was die Sortierung betrifft, alles gut.

Doch fangen wir ganz vorne an. Um die Templates überhaupt anpassen zu können, sollten diese in /fileadmin ausgelagert werden. Die Templates liegen bei TYPO3 7 LTS in diesem Verzeichnis:

/typo3/sysext/fluid_styled_content/Resources/Private/

Die Ordner "Layouts", "Partials" und "Templates" sollten mit Ihrem gesamten Inhalt in ein Verzeichnis nach /fileadmin kopiert werden. In meinem Beispiel kommen die Ordner in dieses Verzeichnis:

fileadmin/templates/hmr/fluid_content/

Damit die Templates von dort geladen werden, ist es nötig, den neuen Speicherort über die Constanten zu definieren:

 


 

 

styles.templates {
    # cat=content/templates/b1; type=string; label= Default fallback path of Fluid Templates for all defined content elements
    templateRootPath = fileadmin/templates/hmr/fluid_content/Templates/Content/
    # cat=content/templates/b2; type=string; label= Default fallback path of Fluid Partials for all defined content elements
    partialRootPath = fileadmin/templates/hmr/fluid_content/Partials/
    # cat=content/templates/b3; type=string; label= Default fallback path of Fluid Layouts for all defined content elements
    layoutRootPath = fileadmin/templates/hmr/fluid_content/Layouts/
}

Bei mir schauen die Verzeichnisse entsprechend so aus:

 
Problemkind 1: Menü ausgewählter Seiten (Type: 0), Zugriff auf Media und korrekte Sortierung 

Template Listing Type-0.html:

  1. <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"

  2.       xmlns:ce="http://typo3.org/ns/TYPO3/CMS/FluidStyledContent/ViewHelpers"

  3.       data-namespace-typo3-fluid="true"

  4.       xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"

  5.       v:schemaLocation="https://fluidtypo3.org/schemas/vhs-master.xsd">

  6.  

  7.     <v:iterator.explode as="pages" content="{data.pages}" glue=",">

  8.         <div class="ce-sitemap-4">

  9.             <f:for each="{pages}" as="pageUid">

  10.                 <v:page.info as="page" pageUid="{pageUid}">

  11.                     <f:link.page pageUid="{page.uid}">

  12.                         {page.title}

  13.                     </f:link.page>

  14.  

  15.                     <f:if condition="{v:resource.record.fal(table:'pages', field:'media', uid:'{page.uid}')->f:count()} > 0">

  16.                         <v:resource.record.fal

  17.                                 table="pages"

  18.                                 field="media"

  19.                                 uid="{page.uid}"

  20.                                 as="media">

  21.  

  22.                             <f:if condition="{media.0.type}==2">

  23.                                 <f:link.page pageUid="{page.uid}">

  24.                                     <f:image

  25.                                            src="{media.0.id}"

  26.                                            maxWidth="250"

  27.                                            class="img-responsive" />

  28.                                 </f:link.page>

  29.                             </f:if>

  30.                         </v:resource.record.fal>

  31.                     </f:if>

  32.                     <f:if condition="{page.abstract}">

  33.                         <f:then>

  34.                             <f:format.html>{page.abstract}</f:format.html>

  35.                         </f:then>

  36.                         <f:else>

  37.                             <f:if condition="{page.description}">

  38.                                 <f:then>

  39.                                     <f:format.html>{page.description}</f:format.html>

  40.                                 </f:then>

  41.                                 <f:else>

  42.                                     <f:if condition="{page.subtitle}">

  43.                                         <f:then>

  44.                                             <f:format.html>{page.subtitle}</f:format.html>

  45.                                         </f:then>

  46.                                     </f:if>

  47.                                 </f:else>

  48.                             </f:if>

  49.                         </f:else>

  50.                     </f:if>

  51.                 </v:page.info>

  52.             </f:for>

  53.         </div>

  54.     </v:iterator.explode>

  55. </html>

  56.  

 

In Zeile 7 kommt der v:iterator.explode zum Einsatz. Da die ausgewählten Seiten, die in der Auswahlbox des Spezialmenüs im Backend als String gespeichert werden (schaut dann so aus: 3,5,4,2,33,53), erreichen wir mit dem iterator.explode eine Schleife. {data.pages} ist das Feld, was die ausgewählten Seiten enthält.

In Zeile 15 habe ich eine Condition eingefügt, um zu prüfen, ob denn überhaupt Bilder in den Seiteneigenschaften im Reiter "Media" abgelegt wurden. Hier kommt der v:resource.record.fal in Verbindung mit f:count zum Einsatz.

In Zeile 16 wird der ViewHelper nochmal ausgeführt. Die wichtigsten Angaben sind "table=pages", "field=media" und "uid={page.uid}". Der ViewHelper holt uns nun alle Dateien aus "sys_file" über die Tabelle "sys_file_reference" die zugeordnet sind.

In Zeile 22 wird noch geprüft, ob das Mediaobjekt vom Typ "Image" ist.

In Zeile 23 beginnt die Ausgabe des Bildes. Da ich nur das erste Bild benötige, greife ich direkt über {media.0.id} für den f:image ViewHelper darauf zu. Natürlich kann auch ein "f:for each" in Zeile 24 stehen um alle Bilder auszugeben.

 
Problemkind 2: Menü der Unterseiten ausgewählter Seiten mit Inhaltsangabe (Type: 4)

Eigentlich ist das genau das selbe. Lediglich der v:iterator.explode wird nicht benötigt, ce:menu.directory tut seinen Dienst perfekt. Zur Vollständigkeit hier noch mein Listing, welches im groben und ganzen dem oberen entspricht:

  1. <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"

  2.       xmlns:ce="http://typo3.org/ns/TYPO3/CMS/FluidStyledContent/ViewHelpers"

  3.       data-namespace-typo3-fluid="true"

  4.       xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"

  5.       v:schemaLocation="https://fluidtypo3.org/schemas/vhs-master.xsd">

  6.  

  7.     <ce:menu.directory pageUids="{pageUids}" as="pages">

  8.         <div class="ce-sitemap-4">

  9.             <f:for each="{pages}" as="pageUid">

  10.                 <v:page.info as="page" pageUid="{pageUid}">

  11.                     <f:link.page pageUid="{page.uid}">

  12.                         {page.title}

  13.                     </f:link.page>

  14.  

  15.                     <f:if condition="{v:resource.record.fal(table:'pages', field:'media', uid:'{page.uid}')->f:count()} > 0">

  16.                         <v:resource.record.fal

  17.                                 table="pages"

  18.                                 field="media"

  19.                                 uid="{page.uid}"

  20.                                 as="media">

  21.  

  22.                             <f:if condition="{media.0.type}==2">

  23.                                 <f:link.page pageUid="{page.uid}">

  24.                                     <f:image

  25.                                             src="{media.0.id}"

  26.                                             maxWidth="250"

  27.                                             class="img-responsive" />

  28.                                 </f:link.page>

  29.                             </f:if>

  30.                         </v:resource.record.fal>

  31.                     </f:if>

  32.                     <f:if condition="{page.abstract}">

  33.                         <f:then>

  34.                             <f:format.html>{page.abstract}</f:format.html>

  35.                         </f:then>

  36.                         <f:else>

  37.                             <f:if condition="{page.description}">

  38.                                 <f:then>

  39.                                     <f:format.html>{page.description}</f:format.html>

  40.                                 </f:then>

  41.                                 <f:else>

  42.                                     <f:if condition="{page.subtitle}">

  43.                                         <f:then>

  44.                                             <f:format.html>{page.subtitle}</f:format.html>

  45.                                         </f:then>

  46.                                     </f:if>

  47.                                 </f:else>

  48.                             </f:if>

  49.                         </f:else>

  50.                     </f:if>

  51.                 </v:page.info>

  52.             </f:for>

  53.         </div>

  54.     </ce:menu.directory>

  55.  

  56. </html>

  57.  

 

 

Hat Dir mein Beitrag gefallen? Du darfst gerne einen Kommentar hinterlassen!