Intranet des Klinikums Marburg

zum Konzern

Zoominar Container

Obwohl man schon mit Hilfe von Backend-Layouts den Nutzern von TYPO3 sehr viel Möglichkeiten bieten kann, Ihre Inhalte flexibel und in mehreren Spalten zu präsentieren, stößt man hier oft schnell an Grenzen. Spätestens wenn man selbst oder der Kunde Inhalte flexibel in verschiedenen Spalten darstellen will, kommt man um den Einsatz einer Lösung für Grid- oder Container-Elemente nicht herum.

Der “Platzhirsch” für solche Grid-Container war bisher die Extension “gridelements”. Diese hat jedoch auch einige Nachteile.

Seit einigen Monaten gibt es eine neue Extension für die Umsetzung solche Anforderungen: die Extension “container”.

Dabei handelt es sich um eine schlanke und moderne Alternative, die sich relativ einfach einrichten lässt, und mit der auch TYPO3-Upgrades sehr viel leichter zu machen sind als bei anderen Lösungen.

Die Container-Extension von b13 erlaubt das Hinzufügen von Layout-„Containern“ zu Inhaltsbereichen (https://b13.com/de/blog/flexible-container-und-grids-fuer-typo3) und https://github.com/b13/container/blob/master/README.md.

Da der Aufbau für 2-Spalte, 3-Spalter, 4-Spalter, Akkordion und Tabs weitestgehend identisch ist, gibt es weiter unten nur eine Erläuterung oder TYPO3-WoWa-Anleitung - Zoominar: Container

Erläuterung

Die Extension Container installieren (https://extensions.typo3.org/extension/container aktuell in der Version 1.3.0), sie erscheint dann unter EXT und muss ggf. noch aktiviert werden!

Unter EXT:infoneu1g/Configuration/TCA/Overrides/ erstellen wir eine Datei namens tt_content.php mit folgendem Inhalt (von hier kopiert und angepasst: https://github.com/b13/container/blob/master/README.md):

 

<?php
//2 Spalten
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class)->configureContainer(
    (
        new \B13\Container\Tca\ContainerConfiguration(
            '2cols', // CType
            '2 Spalten', // label
            '50% / 50%', // description
            [
                [
                    ['name' => 'Linke Spalte', 'colPos' => 201, 'disallowed' => ['CType' => '2cols,3cols,4cols']],
                    ['name' => 'Rechte Spalte', 'colPos' => 202, 'disallowed' => ['CType' => '2cols,3cols,4cols']]
                ]
            ] // grid configuration
        )
    )
    // set an optional icon configuration
    ->setIcon('EXT:container/Resources/Public/Icons/container-2col.svg')
    //->setSaveAndCloseInNewContentElementWizard(false) 
);
// override default settings
$GLOBALS['TCA']['tt_content']['types']['2cols']['showitem'] = 'sys_language_uid,CType,header,header_layout,header_position,layout,colPos,tx_container_parent';

//3 Spalten
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class)->configureContainer(
    (
    new \B13\Container\Tca\ContainerConfiguration(
        '3cols', // CType
        '3 Spalten', // label
        '33% / 33% / 33%', // description
        [
            [
                ['name' => 'Linke Spalte', 'colPos' => 201, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']],
                ['name' => 'Mittlere Spalte', 'colPos' => 202, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']],
                ['name' => 'Rechte Spalte', 'colPos' => 203, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']]
            ]
        ] // grid configuration
    )
    )
    ->setIcon('EXT:container/Resources/Public/Icons/container-3col.svg')
    //->setSaveAndCloseInNewContentElementWizard(false)
);
// override default settings
$GLOBALS['TCA']['tt_content']['types']['3cols']['showitem'] = 'sys_language_uid,CType,header,header_layout,header_position,layout,colPos,tx_container_parent';

//4 Spalten
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class)->configureContainer(
    (
    new \B13\Container\Tca\ContainerConfiguration(
        '4cols', // CType
        '4 Spalten', // label
        '4 Spalten mit je 25%', // description
        [
            [
                ['name' => 'Linke Spalte', 'colPos' => 201, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']],
                ['name' => 'Mittlere Spalte links', 'colPos' => 202, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']],
                ['name' => 'Mittlere Spalte rechts', 'colPos' => 203, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']],
                ['name' => 'Rechte Spalte', 'colPos' => 204, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']]
            ]
        ] // grid configuration
    )
    )
    ->setIcon('EXT:container/Resources/Public/Icons/container-4col.svg')
    //->setSaveAndCloseInNewContentElementWizard(false)
);
// override default settings
$GLOBALS['TCA']['tt_content']['types']['4cols']['showitem'] = 'sys_language_uid,CType,header,header_layout,header_position,layout,colPos,tx_container_parent';

//Akkordion
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class)->configureContainer(
    (
        new \B13\Container\Tca\ContainerConfiguration(
            'accordion', // CType
            'Accordeon', // label
            'Akkordeon-Effekt', // description
            [
                [
                    ['name' => 'Akkordeon', 'colPos' => 1001, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']]
                ]
            ] // grid configuration
        )
    )
    // set an optional icon configuration
    ->setIcon('EXT:container/Resources/Public/Icons/container-accord.svg')
    ->setSaveAndCloseInNewContentElementWizard(true)
);
$GLOBALS['TCA']['tt_content']['types']['accordion']['showitem'] = 'sys_language_uid,CType,header,header_layout,header_position,layout,colPos,tx_container_parent';

//Tabs
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class)->configureContainer(
    (
    new \B13\Container\Tca\ContainerConfiguration(
        'tabs', // CType
        'Tabs', // label
        'Tabs-Reiter', // description
        [
            [
                ['name' => 'Tabs Elemente', 'colPos' => 2001, 'disallowed' => ['CType' => '2cols,3cols,4cols,accordion,tabs']]
            ]
        ] // grid configuration
    )
    )
        // override default configurations
        ->setIcon('EXT:container/Resources/Public/Icons/container-tabs.svg')
        ->setSaveAndCloseInNewContentElementWizard(true)
);
// override default settings
$GLOBALS['TCA']['tt_content']['types']['tabs']['showitem'] = 'sys_language_uid,CType,header,header_layout,layout,colPos,tx_container_parent';

 

Der Schalter ->setSaveAndCloseInNewContentElementWizard(false) in tt_content.php sorgt dafür das beim Erstellen eines neuen Inhaltselements sofort in dieses gewechselt wird, um direkt die Inhalte eingeben zu können.
 

Damit das Ganze auch im Frontend gut aussieht erstellen wir unter EXT:infoneu1g/Configuration/TypoScript/Setup eine Datei namens ext.container.typoscript mit diesem Inhalt:

 

tt_content.2cols < lib.contentElement
tt_content.2cols {
  templateName = 2cols
  templateRootPaths.10 = EXT:vt9/Resources/Private/Extensions/Container/Templates
  dataProcessing {
    201 = B13\Container\DataProcessing\ContainerProcessor
    201 {
      colPos = 201
      as = childrenLeft
    }
    202 = B13\Container\DataProcessing\ContainerProcessor
    202 {
      colPos = 202
      as = childrenRight
    }
  }
}

tt_content.3cols < lib.contentElement
tt_content.3cols {
  templateName = 3cols
  templateRootPaths.10 = EXT:vt9/Resources/Private/Extensions/Container/Templates
  dataProcessing {
    201 = B13\Container\DataProcessing\ContainerProcessor
    201 {
      colPos = 201
      as = childrenLeft
    }
    202 = B13\Container\DataProcessing\ContainerProcessor
    202 {
      colPos = 202
      as = childrenCenter
    }
    203 = B13\Container\DataProcessing\ContainerProcessor
    203 {
      colPos = 203
      as = childrenRight
    }
  }
}

tt_content.4cols < lib.contentElement
tt_content.4cols {
  templateName = 4cols
  templateRootPaths.10 = EXT:vt9/Resources/Private/Extensions/Container/Templates
  dataProcessing {
    201 = B13\Container\DataProcessing\ContainerProcessor
    201 {
      colPos = 201
      as = childrenLeft
    }
    202 = B13\Container\DataProcessing\ContainerProcessor
    202 {
      colPos = 202
      as = childrenCenterLeft
    }
    203 = B13\Container\DataProcessing\ContainerProcessor
    203 {
      colPos = 203
      as = childrenCenterRight
    }
    204 = B13\Container\DataProcessing\ContainerProcessor
    204 {
      colPos = 203
      as = childrenRight
    }
  }
}

tt_content.accordion < lib.contentElement
tt_content.accordion {
  templateName = Accordion
  templateRootPaths.10 = EXT:vt9/Resources/Private/Extensions/Container/Templates
  dataProcessing {
    1001 = B13\Container\DataProcessing\ContainerProcessor
    1001 {
      colPos = 1001
      as = children
    }
  }
}

tt_content.tabs < lib.contentElement
tt_content.tabs {
  templateName = Tabs
  templateRootPaths.10 = EXT:vt9/Resources/Private/Extensions/Container/Templates
  dataProcessing {
    2001 = B13\Container\DataProcessing\ContainerProcessor
    2001 {
      colPos = 2001
      as = children
    }
  }
}

 

Unter EXT:infoneu1g/Resources/Private/Extensions erstellen wir den Ordner Container und darin den Ordner Templates. Hier müssen die Dateien 2cols.html und 3cols.html und 4cols.html erstellt werden.

Inhalt 2cols.html:

 

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default"/>
<f:section name="Main">
	<div class="row">
		<f:if condition="{childrenLeft}">
			<div class="col-md-6">
				<f:for each="{childrenLeft}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
		<f:if condition="{childrenRight}">
			<div class="col-md-6">
				<f:for each="{childrenRight}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
	</div>
</f:section>
</html>

 

Inhalt 3cols.html:

 

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default"/>
<f:section name="Main">
	<div class="row">
		<f:if condition="{childrenLeft}">
			<div class="col-lg-4 col-md-6">
				<f:for each="{childrenLeft}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
		<f:if condition="{childrenCenter}">
			<div class="col-lg-4 col-md-6">
				<f:for each="{childrenCenter}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
		<f:if condition="{childrenRight}">
			<div class="col-lg-4 col-md-6">
				<f:for each="{childrenRight}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
	</div>
</f:section>
</html>

 

Inhalt 4cols.html:

 

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default"/>
<f:section name="Main">
	<div class="row">
		<f:if condition="{childrenLeft}">
			<div class="col-lg-3 col-md-6">
				<f:for each="{childrenLeft}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
		<f:if condition="{childrenCenterLeft}">
			<div class="col-lg-3 col-md-6">
				<f:for each="{childrenCenterLeft}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
		<f:if condition="{childrenCenterRight}">
			<div class="col-lg-3 col-md-6">
				<f:for each="{childrenCenterRight}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
		<f:if condition="{childrenRight}">
			<div class="col-lg-3 col-md-6">
				<f:for each="{childrenRight}" as="child">
					<f:format.raw>{child.renderedContent}</f:format.raw>
				</f:for>
			</div>
		</f:if>
	</div>
</f:section>
</html>

 

Accordion.html:

 

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default"/>
<f:section name="Main">
<!--f:debug>{_all}</f:debug-->
    <div class="row">
        <f:if condition="{children}">
            <div class="col-md-12">
                <div id="accordion" class="accordion">
                    <div class="card">
                    <f:for each="{children}" as="child">
                        <div class="card-header">
                        <details>
                            <summary>
                                 <h2 class="mb-0 btn btn-link btn-block text-left">
                                     {child.header -> f:format.raw()}
                                 </h2>
                            </summary>
                                <div class="accordion_content" style="border:1px solid rgb(193, 193, 211); padding:5px; background-color: #fff;">
                                    {child.bodytext -> f:format.raw()}
                                </div>
                        </details>
                        </div>
                    </f:for>
                    </div>
                </div>
            </div>
        </f:if>
    </div>
</f:section>
</html>

 

Tabs.html:

 

<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
      data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:section name="Main">
    <div id="tabpanel-{data.uid}"
         class="ce-tabpanel tabpanel{f:if(condition:'{data.pi_flexform.style}', then:' {data.pi_flexform.style}')}"
         role="tabpanel">
        <nav class="tab-navigation">
            <div class="nav nav-tabs" id="tab-{data.uid}" role="tablist">
                <f:for each="{children}" as="child" iteration="iterator">
                    <button class="nav-link{f:if(condition:'{iterator.index}==0',then:' active')}"
                            id="tab-{child.uid}"
                            data-toggle="tab"
                            data-target="#tab-content-{child.uid}"
                            data-bs-toggle="tab"
                            data-bs-target="#tab-content-{child.uid}"
                            type="button"
                            role="tab"
                            aria-controls="tab-content-{child.uid}"
                            aria-selected="{_selected}">
                        <span>{child.header}</span>
                    </button>
                </f:for>
            </div>
        </nav>
        <div class="tab-content" id="tab-content-{data.uid}">
            <f:for each="{children}" as="child" iteration="iterator">
                <div class="ce-tab-pane tab-pane fade{f:if(condition:'{iterator.index}==0',then:' show active')}"
                     id="tab-content-{child.uid}"
                     role="tabpanel"
                     aria-labelledby="tab-{child.uid}">
                     <span>{child.bodytext -> f:format.raw()}</span>
                </div>
            </f:for>
        </div>
    </div>
</f:section>
</html>

 

Damit nun nicht geschachtelte Container entstehen, installiert man die Extension Content Defender (https://extensions.typo3.org/extension/content_defender), ggf. nach der Installation --> Wartung --> Analyze Database laufen lassen. Und unter Erweiterungen diese aktivieren.

In tt_content.php kann folgender Code-Schnipsel hinzugefügt werden:
'allowed' => ['CType' => 'header, textmedia']],
Bedeutet das bei Typ (CType) nur header und textmedia erlaubt sind.

Aber in unsere tt_content.php soll es genau anders herum sein, nämlich das bestimmte Typen nicht erlaubt sind (ist weiter oben schon eingefügt):
'disallowed' => ['CType' => '2cols,3cols,4cols']],
Bedeutet das wir in einen solchen Container nicht weitere Container hinzufügen können, also keine Verschachtelungen möglich sind.
 

Ggf. die Datei container-accord.svg in den oben genannten Ordner (EXT:container/Resources/Public/Icons/) kopiert werden, irgendwoher holen.

 

Folgendes muss in customstyles.css oder in eine andere CSS-Datei eingefügt werden:

 

/* fuer Akkordion: entfernt das Dreieck/Pfeil vor dem Akkord-Titel */
details summary::marker {
  content:'';
}

 

 

Sinnvoll ist es wenn in 3cols-, 4cols-, Accordion- und Tabs.html keine der anderen gesetzt werden dürfen! So ist es weiter oben eingebaut.

Also nur in 2cols.html darf man Akkordion oder Tabs hinzufügen, siehe auch Mehrspalter+Akkordion.