TYPO3-Datenbanktabellen um neue Felder erweitern

Anhand zweier neuer Seiteneigenschaften zeige ich, wie man in TYPO3 eigene Datenbankfelder hinzufügt. Wir werden die Tabellen 'pages' und 'pages_language_overlay' über eine kleine TYPO3-Extension erweitern.

Ziel

Wir richten uns zwei neue Seiteneigenschaften ein: Ein weiteres Textfeld zur freien Verfügung sowie eine eigene Checkbox. Das Textfeld wird sowohl in der Originalsprache als auch bei alternativen Seitensprachen pflegbar sein. Die Checkbox hingegen wird in diesem Beispiel nur in der Originalsprache verwendet werden, weil die Funktion dahinter global für alle Sprachen der jeweiligen Seite gelten soll.

tl;dr

Die fertige Extension findet ihr auf Github:

Demo herunterladen

Dateistruktur

Um die Datenbanktabellen in TYPO3 erweitern zu können, bedarf es einer bestimmten Ordner- und Dateistruktur in unserer Extension:

  • in Configuration/TCA/Overrides werden neue Felder für bestehende Tabellen konfiguriert. Die Dateien müssen den exakten Namen der Datenbanktabelle tragen.
  • in Resources/Private/Language habe ich die Bezeichnungen für das Backend in englischer und deutscher Sprache hinterlegt. Dies ist der saubere Ansatz, man könnte aber auch die Namen (ohne Übersetzung) direkt ins $TCA schreiben.
  • ext_emconf.php enthält die Extension-Konfiguration. Ohne diese Datei wird die Extension in TYPO3 gar nicht erst angezeigt.
  • ext_icon.png ist als Icon im Extension Manager zu sehen
  • in der ext_localconf.php sorgen wir dafür, dass unser Textfeld im Frontend mehrsprachig ausgegeben werden kann
  • in der ext_tables.sql erweitern wir die MySQL-Datenbank von TYPO3

Die Extension habe ich in diesem Fall pages_addfields genannt.

Grundsätzliche Konfiguration der Extension

In der Konfigurationsdatei ext_emconf.php finden sich Titel und Beschreibung der Extension, die Versionsnummer, Angaben zum Autor und ggf. Abhängigkeiten, z.B. zur TYPO3-Version. Unsere Extension wird mindestens mit den beiden LTS-Versionen 6.2 und 7.6 kompatibel sein.

ext_emconf.php

<?php
 
$EM_CONF[$_EXTKEY] = array(
    'title' => 'Additional pages field(s)',
    'description' => 'Provides a basic example how to extend pages with your own fields.',
    'category' => 'example',
    'author' => 'Sebastian Klein',
    'author_email' => 'sebastian@sklein-medien.de',
    'state' => 'alpha',
    'internal' => '',
    'uploadfolder' => '0',
    'createDirs' => '',
    'clearCacheOnLoad' => 0,
    'version' => '1.0.0',
    'constraints' => array(
        'depends' => array(
            'typo3' => '6.2.0-7.6.99',
        ),
        'conflicts' => array(
        ),
        'suggests' => array(
        ),
    ),
);

Neue Datenbankfelder anlegen

Über die Datei ext_tables.sql werden die neuen Datenbankfelder ergänzt. Es muss hier der Befehl CREATE TABLE verwendet werden – TYPO3 erkennt bei der Installation der Extension, ob die Tabelle bereits existiert und fügt der bestehenden Tabelle dann nur die neuen Felder hinzu.

Die Verwendung des Extension-Keys im Feldnamen (hier: tx_pagesaddfields) ist nicht notwendig, vermeidet aber Kollisionen mit anderen Extensions, die ggf. Felder gleichen Namens anlegen könnten.

ext_tables.sql

#
# Modifying pages table
#
CREATE TABLE pages (
    tx_pagesaddfields_customtext varchar(255) DEFAULT '' NOT NULL,
    tx_pagesaddfields_customcheckbox TINYINT(1) UNSIGNED DEFAULT '0' NOT NULL
);
 
#
# Modifying pages_language_overlay table
#
CREATE TABLE pages_language_overlay (
    tx_pagesaddfields_customtext varchar(255) DEFAULT '' NOT NULL
);

Falls nachträglich Änderungen am SQL vorgenommen werden, muss die Extension einmal de- und re-installiert werden, damit TYPO3 die Anpassungen erkennt und übernimmt. 

Table Configuration Array ($TCA)

Damit TYPO3 die Datenbankfelder verwendet, müssen sie über das $TCA bekannt gemacht und konfiguriert werden.

Im ersten Schritt werden die neuen Felder konfiguriert: als Input-Feld und Checkbox. Ein ganz kurzer Überblick über die Konfiguration:

  • label: der Name des Feldes im Backend. Könnte hartkodiert hinterlegt werden, hier wird aber die locallang.xlf verwendet
  • exclude: wenn gesetzt, gehört dieses Feld zu den sogenannten "Erlaubten Ausschlussfeldern", die erst über eine Backend-Benutzergruppe editierbar gemacht werden müssen
  • config: die Art des Feldes. Hier verwenden wir ganz simple Einstellungen für unsere Felder, diese ließen sich aber auch erweitern

Anschließend fügen wir die Felder über die TYPO3 API-Methode addTCAcolumns der bestehenden Tabelle hinzu. Mit addToAllTCAtypes lassen wir die Felder im TCEFORM erscheinen. Zuletzt fügen wir unsere neue Palette den Seiteneigenschaften hinzu.

Bei der Konfiguration der alternativen Seitensprache gehen wir in diesem Beispiel davon aus, dass die neue Checkbox global für alle Sprachen einer Seite gelten soll. Daher wird hier nur das Textfeld eingerichtet.

Configuration/TCA/Overrides/pages.php

<?php
if (!defined('TYPO3_MODE')) {
  die ('Access denied.');
}
 
// Configure new fields:
$fields = array(
  'tx_pagesaddfields_customtext' => array(
    'label' => 'LLL:EXT:pages_addfields/Resources/Private/Language/locallang_db.xlf:pages.tx_pagesaddfields_customtext',
    'exclude' => 1,
    'config' => array(
      'type' => 'input',
      'max' => 255
    ),
  ),
  'tx_pagesaddfields_customcheckbox' => array(
    'exclude' => 1,
    'label' => 'LLL:EXT:pages_addfields/Resources/Private/Language/locallang_db.xlf:pages.tx_pagesaddfields_customcheckbox',
    'config' => array(
      'type' => 'check',
      'default' => 0
    )
  )
);
 
// Add new fields to pages:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('pages', $fields);
 
// Make fields visible in the TCEforms:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
  'pages', // Table name
  '--palette--;LLL:EXT:pages_addfields/Resources/Private/Language/locallang_db.xlf:pages.palette_title;tx_pagesaddfields', // Field list to add
  '1', // List of specific types to add the field list to. (If empty, all type entries are affected)
  'after:nav_title' // Insert fields before (default) or after one, or replace a field
);
 
// Add the new palette:
$GLOBALS['TCA']['pages']['palettes']['tx_pagesaddfields'] = array(
  'showitem' => 'tx_pagesaddfields_customcheckbox,tx_pagesaddfields_customtext'
);

Configuration/TCA/Overrides/pages_language_overlay.php

<?php
if (!defined('TYPO3_MODE')) {
  die ('Access denied.');
}
 
// Configure new field:
$fields = array(
  'tx_pagesaddfields_customtext' => array(
    'label' => 'LLL:EXT:pages_addfields/Resources/Private/Language/locallang_db.xlf:pages.tx_pagesaddfields_customtext',
    'exclude' => 1,
    'config' => array(
      'type' => 'input',
      'max' => 255
    ),
  )
  // In this example, we assume that the custom checkbox is only used in the original language. So, no need to configure it here.
);
 
// Add new field to translated pages:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('pages_language_overlay', $fields);
 
// Make field visible in the TCEforms:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
  'pages_language_overlay', // Table name
  '--palette--;LLL:EXT:pages_addfields/Resources/Private/Language/locallang_db.xlf:pages.palette_title;tx_pagesaddfields', // Field list to add
  '', // List of specific types to add the field list to. (If empty, all type entries are affected)
  'after:nav_title' // Insert fields before (default) or after one, or replace a field
);
 
// Add the new palette:
$GLOBALS['TCA']['pages_language_overlay']['palettes']['tx_pagesaddfields'] = array(
  'showitem' => 'tx_pagesaddfields_customtext'
);

Lokalisierung der Backend-Labels

Die Verwendung der Lokalisierungs-Dateien hat nichts mit der Ausgabe im Frontend zu tun. Vielmehr geht es hier um die Mehrsprachigkeit im Backend. Die Labels, also die Benennung unserer Felder, können auf diese Weise für fremdsprachige Backend-Benutzer übersetzt werden.

Verlinkt wird die Sprachdatei – wie oben gesehen – mit LLL:EXT:pages_addfields/Resources/Private/Language/locallang_db.xlf:, nach dem Doppelpunkt folgt die ID des lokalisierten Inhalts. Bei gewählter Fremdsprache Deutsch im Backend sucht TYPO3 nach der Datei mit vorangestelltem Kürzel de. und der Übersetzung im target-Element.

Resources/Private/Language/locallang_db.xlf

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xliff version="1.0">
    <file source-language="en" datatype="plaintext" original="messages" date="2016-06-18T12:03:24Z"
          product-name="pages_addfields">
        <header/>
        <body>
            <trans-unit id="pages.palette_title">
                <source>My custom fields</source>
            </trans-unit>
            <trans-unit id="pages.tx_pagesaddfields_customtext">
                <source>Custom text field</source>
            </trans-unit>
            <trans-unit id="pages.tx_pagesaddfields_customcheckbox">
                <source>Custom checkbox</source>
            </trans-unit>
        </body>
    </file>
</xliff>

Resources/Private/Language/de.locallang_db.xlf

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xliff version="1.0">
    <file source-language="en" datatype="plaintext" original="messages" date="2016-06-18T12:03:24Z"
          product-name="pages_addfields" target-language="de">
        <header/>
        <body>
            <trans-unit id="pages.palette_title">
                <source>My custom fields</source>
                <target>Meine benutzerdefinierten Felder</target>
            </trans-unit>
            <trans-unit id="pages.tx_pagesaddfields_customtext">
                <source>Custom text field</source>
                <target>Benutzerdefiniertes Textfeld</target>
            </trans-unit>
            <trans-unit id="pages.tx_pagesaddfields_customcheckbox">
                <source>Custom checkbox</source>
                <target>Benutzerdefinierte Checkbox</target>
            </trans-unit>
        </body>
    </file>
</xliff>

Den übersetzten Inhalt des Textfelds im Frontend ausgeben

Wenn wir zum jetzigen Zeitpunkt eine alternative Seitensprache anlegen und unser Textfeld befüllen, wird dieser Wert korrekt in der Datenbanktabelle pages_language_overlay gespeichert. Würde man aber versuchen, deren Inhalt auszugeben, wäre man enttäuscht: Es würde nur der Wert der Originalsprache ausgegeben.

Damit TYPO3 den Inhalt des neuen Textfeldes in der alternativen Seitensprache auch im Frontend verwendet, muss man das Feld zu den pageOverlayFields hinzufügen. Das könnte man nun über das TYPO3 Installations-Tool in die LocalConfiguration.php einpflegen, viel praktischer geht das aber über die ext_localconf.php unserer Extension:

<?php
if (!defined('TYPO3_MODE')) {
  die ('Access denied.');
}
 
$TYPO3_CONF_VARS['FE']['pageOverlayFields'] .= ',tx_pagesaddfields_customtext';

Fertig. Was jetzt?

Wie ihr die neuen Felder nutzt, bleibt euch überlassen. Ihr könntet beispielsweise die Ausgabe des Textfelds davon abhängig machen, ob die Checkbox gewählt wurde:

10 = TEXT
10.field = tx_pagesaddfields_customtext
10.if.isTrue.field = tx_pagesaddfields_customcheckbox
Zurück