Backend Layouts, Grid Elements, eigene CE's ohne TemplaVoilà

Backend Layouts

Seit TYPO3 4.5 im Core, ab 6.0 wird auch die standardmäßige Spaltenansicht über ein Default-Backendlayout gerendert.
-> Implementierung von Drag&Drop einfacher und endlich im Core.

Backend Layouts

  1. Anlegen von Backend-Layouts mit Grid-Wizard im Backend
  2. Zuweisung des Ordners als General Record Storage Pid
  3. Anbindung des Backend-Layouts an Templates für das Frontend

Mehrsprachigkeit? Nichts neues...

Backend-Layout an das Frontend andocken

page = PAGE
page {
  10 = FLUIDTEMPLATE
  10 {
    layoutRootPath = {$layoutsPath}
    file.stdWrap.cObject = CASE
    file.stdWrap.cObject {
      # slide the template
      key.data = levelfield:-1, backend_layout_next_level, slide
      key.override.field = backend_layout
      # default template file
      default = TEXT
      default.value = {$templatesPath}/Pages/index.html
      # template file for backend-layout with ID 2
      2 = TEXT
      2.value = {$templatesPath}/Pages/fullcontent.html
    }
}

Oldschool Template

PAGE.10 = TEMPLATE
PAGE.10 {
   template = FILE
   template.file.cObject = CASE
   template.file.cObject {
     key.data = levelfield:-1, backend_layout_next_level, slide
     key.override.field = backend_layout
     key.append = TEXT
     key.append.dataWrap = X{field:layout}

     default = TEXT
     default.value = fileadmin/templates/default.html
     1X0 = TEXT
     1X0.value = fileadmin/templates/be_1_fe_default.html
     1X1 = TEXT
     1X1.value = fileadmin/templates/be_1_fe_1.html
     1X2 = TEXT
     1X2.value = fileadmin/templates/be_1_fe_2.html
     2X0 = TEXT
     2X0.value = fileadmin/templates/be_2_fe_default.html
     2X1 = TEXT
     2X1.value = fileadmin/templates/be_2_fe_1.html
     2X2 = TEXT
     2X2.value = fileadmin/templates/be_2_fe_2.html
   }
}
Quelle: http://lists.typo3.org/pipermail/typo3-team-core/2012-July/052026.html
Backend Layouts Templavoila
+ Bordmittel ~ Separate Extension, (betreut von Core-Dev)
+ Freie Wahl der Template-Engine ~ "Alles aus einer Hand"
- Konfiguration kann nicht ausgelagert werden ~ Auslagerung soll funktionieren
+++ Kein Mapping updaten nach Template-Änderung ~ Lebensretter sein, wenn z.B. die Templates gelöscht wurden
- Workspaces funktionieren erst seit ein paar Monaten richtig (Änderung von Layouts) +++ Mit richtigen Einstellungen sind Workspaces kein Problem!
- Sprachhandling "unflexibel" +++ Flexibel, getestet, übersichtlich

Container-Elemente

Backend Layouts Templavoila
keine nativ vorhanden, beliebige Verschachtelung.
Vorsicht bei Mehrsprachigkeit und Workspaces!
mod.web_txtemplavoilaM1.
useLiveWorkspaceForReferenceListUpdates = true

Dafür gibt es Grid-Elements

Alternativen zu Grid Elements

  • kb_nescefe → Entwicklung eingeschlafen, Bug in 4.5 mit Security Token nach über einem Jahr behoben!
  • fedext/flux → Viel Magie: Aus Fluidtemplate wird Backend-Ansicht und Content-Element mit Flexform generiert
  • multicolumn

Grid-Elements
mehr als nur Grids

  • Drag&Drop in TYPO3 < 6.0
  • kopieren mit Strg-Taste
  • neue Elemente anlegen per D&D
  • Und bringt auch ein paar neue Bugs mit :-/
  • Scheint auch noch einige Probleme mit 6.0 zu haben (Stand vom 22.11)

Grid Elements 2.0 - evt. Teil von TYPO3 6.1

Kein offizielles Core-Projekt?

Gleicher Wizard wie bei Backend Layouts

Die Features laut Doku (Auszug)

  • Comfortable point and click wizard to create backend layout structures
  • Flexforms used for configurational stuff only, can be derived from existing data structures
  • Original colPos and sorting fields still working
  • Top level layouts to exclude certain types of Grid Elements from being used within other Grid Elements
  • Drag & drop move and copy actions for the page module
  • New content element wizard overlay to drag in new content elements
  • Paste icons for pasting copies and references into grid columns
  • Completely TypoScript based frontend output

Wie kriegt man die Ausgabe ins Frontend?

# Gridlayout
tt_content.gridelements_pi1.20.10.setup {
        # ID of gridelement
        1 < lib.gridelements.defaultGridSetup
        1 {
                columns {
                        # colPos ID
                        50 < .default
                        50.wrap = <div class="colLeft">|</div>
                        # colPos ID
                        51 < .default
                        51.wrap = <div class="colRight">|</div><div class="clear">&nbsp;</div>
                }
                wrap = <div class="contentRow">|</div><div class="clear">&nbsp;</div>
        }
}

Unser Fazit:

Für viele Projekte verwendbar, bei komplexeren Projekten (Multilanguage und Workspaces) werden wir nach wie vor auf Templavoila setzen

Was packt man in die Backend-Layouts und Grid Elements?

Eigene Content-Elemente

(Bekannte) Frameworks für eigene Content-Elemente

  • templavoila: FCEs funktionieren nicht Standalone, sind nur umständlich versionier-/transportierbar, laut Bugtracker viele Probleme mit 4.7
  • fedext/flux/fluidcontent: Alles per Fluid Template konfigurierbar, generiert Flexforms, riesige Sammlung an ViewHelpern. Magic?
  • dce - Dynamic Content Elements: Elemente werden im Backend per Wizard zusammengeklickt und in DB gespeichert -> keine Versionierung
  • wec_contentelements: Einfache API, Datei-Struktur muss Konvention verfolgen

Problem

  • zuviel Magie kann und wird bei Updates Schwierigkeiten machen
  • was passiert, wenn der Autor keine Lust mehr hat?
  • wir stellen uns aktuell die Frage, wie wir
    • kb_nescefe los werden
    • sr_feuser_register ersetzen
    • gridelements in 6.0 verwenden
    • wann Templavoila mit 6.0 kompatibel wird
    • Generelles Problem bei Extensions: es kann lange dauern, bis diese mit neuen Versionen verwendet werden können

Dabei ist das gar nicht so schwer

ext_tables.php

$pluginSignature = $extensionName . '_pi1';
$TCA['tt_content']['columns']['CType']['config']['items'][] = array('LLL:EXT:my_ext/Resources/Private/Language/locallang_db.xml:plugin_Pi1', $pluginSignature, '../typo3conf/ext/my_ext/Resources/Public/Images/Icon/pi1.gif');

$TCA['tt_content']['types'][$pluginSignature]['showitem'] = '
        --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general,
        header, header_layout,
        bodytext;LLL:EXT:cms/locallang_ttc.xml:bodytext_formlabel;;richtext:rte_transform[flag=rte_enabled|mode=ts_css], rte_enabled;LLL:EXT:cms/locallang_ttc.xml:rte_enabled_formlabel,
        --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access';

TypoScript

tt_content.myext_pi1 = FLUIDTEMPLATE
tt_content.myext_pi1 {
        layoutRootPath = {$layoutsPath}
        file = {$templatesPath}/Content/text.html
}

text.html

<f:if condition="{data.header_layout} == 1">
        <h1>{data.header}</h1>
</f:if>
<f:if condition="{data.header_layout} == 2">
        <h2>{data.header}</h2>
</f:if>
<f:format.html>{data.bodytext}</f:format.html>
FLUIDTEMPLATE kann auch gegen TEXT, TEMPLATE usw. ausgetauscht werden.
Die Daten sind genau so vorhanden, wie sie aus der Datenbank ausgelesen werden.
→ Ideal geeignet für einfachere Strukturen, dank Fluid sind ViewHelper und einfache Kontroll-Strukturen möglich.

Wann reicht das nicht mehr aus:
v.a. bei komplexeren Eingabe-Möglichkeiten, z.B. IRRE-/DB-Relationen im Content-Element
→ Ausweg: Content-Element durch Extbase schicken und die Möglichkeiten von Models nutzen

ext_tables.php

$extensionName = 'akaccordion';

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
	$_EXTKEY,
	'Accordion',
	'Accordion'
);

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'Accordion');

$pluginSignature = $extensionName . '_accordion';
$TCA['tt_content']['types'][$pluginSignature]['showitem'] = '
        CType;;4;button;1-1-1,
        header,
        header_layout,
        tx_akaccordion_accordion_content,
        --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.visibility;visibility, --palette
--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access';

ext_localconf.php

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
	'AK.' . $_EXTKEY,
	'Accordion',
	array('Content' => 'accordion',),
	// non-cacheable actions
	array(),
	\TYPO3\CMS\Extbase\Utility\ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
);

TypoScript

plugin.tx_akaccordion {
  persistence.classes {
    AK\AkAccordion\Domain\Model\TtContent {
      subclasses.akaccordion_accordion = AK\AkAccordion\Domain\Model\Plugins\Accordion
    }
    AK\AkAccordion\Domain\Model\Plugins\Accordion {
      mapping {
        recordType = akaccordion_accordion
        tableName = tt_content
        columns.tx_akaccordion_accordion_content.mapOnProperty = rows
      }
    }
  }
}
config.tx_extbase.persistence.classes {
  AK\AkAccordion\Domain\Model\TtContent {
    mapping.tableName = tt_content
  }
}
Basis-Modell für tt_content kann z.B. aus news-Extension kopiert werden
Eigene Subclasses erhalten weitere Logik (für Conditions) oder die erweiterten Eigenschaften
/**
 * Determine, if the content element has videos
 *
 * @return boolean
 */
public function getHasVideo() {
    if ($this->getVideoMp4() || $this->getVideoOgg() || $this->getVideoWebm()) {
            return TRUE;
    }
    return FALSE;
}

ak_accordion/Classes/Domain/Model/Plugins/Accordion.php

  namespace AK\AkAccordion\Domain\Model\Plugins;
  class Accordion extends \AK\AkAccordion\Domain\Model\TtContent {
  	/**
  	 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<AK\AkAccordion\Domain\Model\AccordionContent>
  	 */
  	protected $rows;

  	/**
  	 * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $rows
  	 * @return void
  	 */
  	public function setRows($rows) {
  		$this->rows = $rows;
  	}

  	/**
  	 * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
  	 */
  	public function getRows() {
  		return $this->rows;
  	}
  }

ak_accordion/Classes/Controller/ContentController.php

namespace AK\AkAccordion\Controller;<br>
class ContentController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
 * @return void
 */
public function accordionAction() {
    $data = $this->configurationManager->getContentObject()->data;
    $this->view->assign('content', $this->contentRepository->findByUid($data['uid']));
}

ak_accordion/Resources/Private/Templates/Content/Accordion.html

<div class="accordion">
	<f:for each="{content.rows}" as="row">
		<h3>{row.head}</h3>
		<div>
			<f:if condition="{row.image}">
				<div style="float: left; padding-right: 10px;">
					<f:image src="uploads/tx_akaccordion/{row.image}" alt="" maxWidth="160" maxHeight="80" />
				</div>
			</f:if>
			<f:format.nl2br>{row.bodytext}</f:format.nl2br>
		</div>
	</f:for>
</div>

Wenn das ganze jetzt noch in den Wizard soll

ext_localconf.php

t3lib_extMgm::addPageTSConfig('<INCLUDE_TYPOSCRIPT: source="FILE:EXT:' . $_EXTKEY . '/Configuration/TsConfig/PageTs/wizard.ts">');

wizard.ts

mod.wizards.newContentElement.wizardItems.common.elements.ak_accordion {
  icon = ../typo3conf/ext/ak_accordion/Resources/Public/Icons/Wizard/plugin_accordion.png
  title = LLL:EXT:ak_accordion/Resources/Private/Language/locallang_wizard.xlf:plugin_accordion
  description = LLL:EXT:ak_accordion/Resources/Private/Language/locallang_wizard.xlf:plugin_accordion_description
  tt_content_defValues {
    CType = akaccordion_accordion
  }
}

mod.wizards.newContentElement.wizardItems.common.show := addToList(ak_accordion)

Hier gibts die Extension:

https://github.com/akiessling/ak_accordion

Weiterführende Links

  • http://fedext.net/
  • http://blog.mittwald.de/cms/responsive-typo3-3-backend-layouts-und-grid-elements/
  • Der Weg weg von Templavoila
    http://vimeo.com/41665329
  • Content-Element Wizard: http://buzz.typo3.org/people/steffen-kamper/article/the-new-content-element-wizard-in-version-43/