Eigene Inhaltstypen

Beim Einsatz von TYPO3 als Redaktionssystem wird im allgemeinen schon recht viel geboten. Die Inhaltselemente die mit geliefert werden enthalten eine Vielzahl an Optionen. Mit diesen kann ein geschickter Administrator durch passende Konfiguration die meisten Anforderungen umsetzen.

Irgendwann kommt dann aber der Tag an dem ein Kunde dann doch die Anforderung hat, dass dieser oder jener Inhaltstyp genau so und nicht anders wie von ihm angegeben umgesetzt werden muss. Wenn noch dazu vorab die absolut verständliche Anforderung gestellt wurde kein TemplaVoila einzusetzen, dann wird die Luft auf einmal recht dünn.

Hmm, wie war das nochmal mit der Erzeugung eigener Inhalte? Und was hat da Peter auf dem TYPO3Camp nochmal über "Single Table Inheritance" erzählt? Alles total interessant gewesen, aber jetzt muss ich eine Aufwandsschätzung in 2 Stunden abliefern und hab noch nicht den leisesten Hauch einer Ahnung.

But wait sinner, the good is out to help you. In diesem Artikel werden wir Schritt für Schritt erklären was notwendig ist um einen individuellen Inhaltstypen zu erhalten. Und für alle die zu ungeduldig sind, ist am Ende noch eine Extension verlinkt die als Basis dienen kann.

Grundlage für komplexe Inhalte

Was in aller Welt sind komplexe Inhalte wird wohl die erste Frage sein, die einem bei dieser Überschrift durch den Kopf geht. Nun komplexe Inhalte kennt man in TYPO3 mindestens so lange wie es IRRE Elemente (inline relational record editing) gibt. Dabei werden die eigentlichen Inhaltselemente um weitere Inhaltsteile erweitert.

Das heißt also, wir haben einen Inhaltstyp, der Kinderelemente enthält. Zum Beispiel findet sich dieses Verhalten bei der Extension powermail. Jedes Formular ist ein Inhaltselement. Die Feldgruppen sind wiederrum Kinderelemente, die als weiteres Unterelement Felder enthalten.

Um genau dieses Verhalten in unserem Inhalt zu erhalten, erweitern wir den standard Inhalt der in der Tabelle tt_content gespeichert wird um 2 Felder. Zum einen fügen wir das Feld child hinzu. Dies dient dem Inhaltstyp zur Anzeige der Unterelemente. Rein von der Datenbank Struktur wäre das nicht nötig, da aber TYPO3 kein Feld im Backend darstellen mag, dass kein Datenbankfeld zugeordnet hat müssen wir das Feld anlegen.

Zum anderen benötigen wir noch das Feld parent. Dieses wird beim Abspeichern des Elternelements mit der ID befüllt und stellt die Verbindung zwischen Eltern- und Kindelement. Die Darstellung im TYPO3 Backend erfolgt als Selectbox. Damit ist es im nachhinein noch möglich ein Kindelement einem anderen Oberelement zuzuordnen.

Der folgende Codeblock zeigt die SQL Anweisung mit der die Tabelle tt_content um die beiden Felder erweitert wird. Dieser ist in der Datei ext_tables.sql im obersten Ordner der Extension zu speichern.

#
# tt_content
#
CREATE TABLE tt_content (
  child int(11) DEFAULT '0' NOT NULL,
  parent int(11) DEFAULT '0' NOT NULL
);
Benötigte Felder einfügen (ext_tables.sql)

Backend Felder

Nachdem der Datenbank mitgeteilt wurde, dass sie doch so freundlich sein soll unsere Werte zu speichern fehlt eine Möglichkeit dass der Redakteur im Backend auch wirklich Unterelemente anlegen kann, diese im Elternelement angezeigt werden und nachträglich einem anderen Element zu geordnet werden können.

Dazu werden je Feld TCA (Table Configuration Array) Anweisungen benötigt. Diese teilen TYPO3 mit wie die Darstellung erfolgen soll.

Das child-Feld ist vom Type inline und stellt eine Bearbeitung im Elternelement sicher. Da sowohl das Kind- wie auch das Elternelement in der gleichen Tabelle gespeichert werden, enthält der foreign_table Wert entsprechend auch tt_content. Wichtig ist, dass foreign_field den Namen des verweisenden Feldes parent enthält. Damit wäre das Kindelement Feld so gut wie fertig. Zu beachten ist, dass maxitems willkürlich auf 15 gesetzt wurde.

Bearbeitungsmarke

Dieser Artikel befindet sich in Bearbeitung und ich bin leider bisher nur bis hier her gekommen. In Kürze also mehr.

$tempColumns = array(
  'child' => array(
    'exclude' => 0,
    'label' => 'LLL:EXT:extension/Resources/Private/Language/locallang_db.xml:tt_content.child',
    'config' => array(
      'type' => 'inline',
      'foreign_table' => 'tt_content',
      'foreign_field' => 'parent',
      'foreign_sortby' => 'sorting',
      'appearance' => array(
        'collapseAll' => true,
        'expandSingle' =>; true,
        'levelLinksPosition' => 'both',
      ),
      'maxitems' => 15,
    ),
  ),
  'parent' => array(
    'exclude' => 0,
    'label' => 'LLL:EXT:extension/Resources/Private/Language/locallang_db.xml:tt_content.parent',
    'config' => array(
      'type' => 'select',
      'foreign_table' =>; 'tt_content',
      'foreign_table_where' => ' AND tt_content.uid != ###THIS_UID### AND tt_content.pid = ###CURRENT_PID### AND tt_content.parent = 0',
      'maxitems' => 1,
      'items' => array(
        array('LLL:EXT:extension/Resources/Private/Language/locallang_db.xml:tt_content.noparent', ''),
      ),
    ),
  ),
);
t3lib_extMgm::addTCAcolumns('tt_content', $tempColumns);
Felder für die Eingabe konfigurieren (ext_tables.php)
t3lib_extMgm::addPlugin(
  array(
    'LLL:EXT:extension/Resources/Private/Language/locallang_db.xml:CType.I.newType',
    'newType',
  ),
  'CType'
);
Type registrieren (ext_tables.php)
$GLOBALS['TCA']['tt_content']['types']['newType']['showitem'] =
      '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general,
      --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header,
      child,
    --div--;LLL:EXT:cms/locallang_ttc.xml:tabs.appearance,
      --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.frames;frames,
    --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';
Formular des Elements definieren (ext_tables.php)
tt_content.newType = COA
tt_content.newType {
  20 = CONTENT
  20 {
    table = tt_content

    select {
      pidInList = this
      orderBy = sorting
      where = parent=###parent###
      markers {
        parent.field = uid
      }
    }
    renderObj < tt_content
    renderObj.text.20.crop = 300 | ... | 1
  }

  stdWrap.wrap = <div class="wrapOfElements">|</div>
}
Ausgabe in der Seite definieren
Meine Mission

Ziel meiner Veröffentlichungen ist es, meine Begeisterung für die Programmierung und das über die Jahre gewonnene Wissen mit anderen Entwicklern zu teilen. Dabei ist es mir wichtig, Lösungen zu thematisieren für die ich in Suchmaschinen keine Antworten finden konnte. Außerdem versuche ich die von mir veröffentlichten Extensions an Beispielen zu erläutern.

evoWeb © 2019