Hinweis: Gemacht hab ich das Ganze bei einem Upgrade von TYPO3 10.4.21 auf die aktuellste TYPO3 11.5 LTS Version. Gridelements war Version 9.5.0 und die aktuelle Version der Container Extension ist 1.4.2.
Bei meinem Projekt waren die Grids als Datensätze in der Datenbank angelegt. Die Config dazu sieht so aus:
mod.web_layout.BackendLayouts { exampleKey { title = Zweispaltig (Teaser-Texte lang) icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif config { backend_layout { colCount = 2 rowCount = 1 rows { 1 { columns { 1 { name = Links colPos = 10 allowed { CType = header,text,textpic,image,textmedia,bullets,form_formframework } } 2 { name = Rechts colPos = 20 allowed { CType = header,text,textpic,image,textmedia,bullets,form_formframework } } } } } } } } }
Für die Container Configuration brauche ich nur den Titel, die Beschreibung und die Configuration.
Die Config für den Container sieht dann so aus:
$containerRegistry->configureContainer( ( new \B13\Container\Tca\ContainerConfiguration( 'container-5', 'Zweispaltig (Teaser-Texte lang)', '', [ [ [ 'name' => 'Links', 'colPos' => 10, 'allowed' => [ 'CType' => 'header,text,textpic,image,textmedia,bullets,form_formframework' ] ], [ 'name' => 'Rechts', 'colPos' => 20, 'allowed' => [ 'CType' => 'header,text,textpic,image,textmedia,bullets,form_formframework' ] ], ] ] ) ) );
Als CType nehme ich einfach container-{id} und hänge die ID des Grids aus der Datenbank daran.
Die colPos übernehme ich aus den Grids.
Die Extensions Gridelements verwendet für die Spalten (Columns) ein eigenes Feld in der Datenbank (
tx_gridelements_columns
) und Container verwendet die Spalte colPos
aus dem Core. Daher kann es bei der Verwendung von Backend Layouts mit den gleichen colPos zu Problemen bei der Ausgabe im FE kommen (Content Elemente werden dann zB doppelt angezeigt!). Ich empfehle die ColPos für Container mit 10 zu präfixen. Also aus z.B. 1 wird 101 usw.Tipp am Rande: Für die allowed CTypes braucht es ohne Gridelements die Extension content_defender.
Nun folgt der aufwendigere Teil, in der Datenbank:
Um die Grids (selbst) in einen Container zu verwandeln bauen wir eigentlich nur den Ctype um:
UPDATE `tt_content` SET `CType`=CONCAT('container-', `tx_gridelements_backend_layout`) WHERE `CType`='gridelements_pi1';
Schwieriger wird es für den Content der Grids:
UPDATE `tt_content` SET `colPos`= `tx_gridelements_columns`,`tx_container_parent`=`tx_gridelements_container` WHERE `colPos`=-1;
Note: Sollte auch mit verschachtelten Grids funktionieren, hatte ich bei dem Projekt aber nicht und daher auch nicht getestet.
Funktioniert natürlich auch mit verschachtelten Grids.
Nun fehlt nur noch das Template. Dieses ist entweder beim Gridelement schon als Datei angelegt oder wird mit TypoScript gebaut. In meinem Fall via TS:
tt_content { gridelements_pi1.20.10.setup { 5 < lib.gridelements.defaultGridSetup 5 { columns { 10 < .default 10 { wrap = <div class="longfacts-spalte-1">|</div> } 20 < .10 20 { wrap = <div class="longfacts-spalte-2">|</div> } } wrap = <section id="longfacts" class="wrapper style2"><div class="inner"><div class="posts"><section class="facts-gesamt">|</section></div></div></section> } } }
Daraus baue ich nun ein richtiges Fluidtemplate:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true"> <f:layout name="Default"/> <f:section name="Main"> <section id="longfacts" class="wrapper style2"> <div class="inner"> <div class="posts"> <section class="facts-gesamt"> <div class="longfacts-spalte-1"> <f:if condition="{children_10}"> <f:for each="{children_10}" as="child"> <f:format.raw>{child.renderedContent}</f:format.raw> </f:for> </f:if> </div> <div class="longfacts-spalte-2"> <f:if condition="{children_20}"> <f:for each="{children_20}" as="child"> <f:format.raw>{child.renderedContent}</f:format.raw> </f:for> </f:if> </div> </section> </div> </div> </section> </f:section> </html>
Und dann fehlt noch die TypoScript Config.
Zuerst die Standard Config für die Container Extensions (um die Templates von FSC – Fluid Styled Content – auch zu verwenden)
lib.containerElement =< lib.contentElement lib.containerElement { layoutRootPaths { 100 = EXT:fluid_styled_content/Resources/Private/Layouts 110 = EXT:theme/Resources/Private/Layouts/Container } templateRootPaths { 100 = EXT:fluid_styled_content/Resources/Private/Templates 110 = EXT:theme/Resources/Private/Templates/Container } partialRootPaths { 100 = EXT:fluid_styled_content/Resources/Private/Partials 110 = EXT:theme/Resources/Private/Partials/Container } dataProcessing { 10 = B13\Container\DataProcessing\ContainerProcessor } }
und dann die Config für den Container selbst:
tt_content.container-5 < lib.containerElement tt_content.container-5 { templateName = Container-5 }
Und schon sind alle ehemaligen Gridelements Container Elemente.