CKEditor in TYPO3 sauber konfigurieren

veröffentlicht am 04.02.2022

Den CKEditor in TYPO3 mit webpack und extra Plugins vorbildlich konfigurieren.

TYPO3 liefert den CKEditor 4 als Richtext-Editor mit. Beim Aufsetzen einer neuen Seite ist das Ganze dann erst mal recht ernüchternd: CKEditor-Ansicht ungestylt

Wir wollen Redakteur:innen (und uns selbst) jedoch ein besseres Erlebnis liefern als das, oder? Der Gedanke beim CKEditor ist ja auch, dass es ein WYSIWYG-Editor sein soll.
Und da wollen wir hin: CKEditor-Ansicht gestylt

Vorbereitende Konfiguration

TYPO3 selbst hat eine sehr ausführliche Dokumentation, wie man den CKEditor einrichtet. Im Folgenden daher nur eine kurze Beschreibung, wie wir die Konfiguration selbst einbinden.
Die Konfiguration wird im YAML-Format geschrieben. Wir packen diese natürlich in unser SitePackage z.B. in

sitepackage/Configuration/RTE/Default.yaml

Diese YAML-Datei füllen wir gleich, erst noch weitere Konfiguration. In unserer ext_localconf.php ergänzen wir

1
2
3
4
5
6
7
8
...
// Preset global registrieren
if (empty($GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['sitepackage'])) {
    $GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['sitepackage'] = 'EXT:sitepackage/Configuration/RTE/Default.yaml';
}

// PageTS hinzufügen
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('@import "EXT:sitepackage/Configuration/TsConfig/Page/RTE.tsconfig"');

Das Letztere gibt an, dass wir eine TSconfig brauchen. Man kann mehrere Konfigurationen hinterlegen. Wir wollen erst mal nur eine Konfiguration für alles, daher steht in unserer RTE.tsconfig nur

 RTE.default.preset = sitepackage

YAML-Konfiguration

Achtung, jetzt kommt die komplette YAML-Konfiguration. Das meiste wird auch in der TYPO3 Configuration Reference erklärt. Daher werden anschließend nur wesentliche Punkte der Konfiguration erläutert.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Dies steht in der Default.yaml.

imports:
  - { resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml" }
  - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml" }
  - { resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Plugins.yaml" }

editor:
  externalPlugins:
    sitepackage_responsivetable:
      resource: "EXT:sitepackage/Resources/Public/CKEditor/Plugins/Table/plugin.js"
    sitepackage_dataattributes:
      resource: "EXT:sitepackage/Resources/Public/CKEditor/Plugins/DataAttributes/plugin.js"
  config:
    contentsCss: "EXT:sitepackage/Resources/Public/Build/rte.css"
    bodyClass: "color-text font-base stack"
    autoGrow_bottomSpace: 50
    autoGrow_maxHeight: 900
    autoGrow_onStartup: 'true'

    stylesSet:
      - { name: "Label",            element: "p",         attributes: { "class": "label" } }
      - { name: "Caption",          element: "p",         attributes: { "class": "caption" } }
      - { name: "Positive end",     element: "ul",        attributes: {                     "data-type": "positive-end",      "role": "list" } }
      - { name: "Positive start",   element: "ul",        attributes: {                     "data-type": "positive-start",    "role": "list" } }
      - { name: "Negative end",     element: "ul",        attributes: {                     "data-type": "negative-end",      "role": "list" } }
      - { name: "Individual icons", element: "ul",        attributes: {                     "data-type": "individual-icons",  "role": "list" } }
      - { name: "Button Primary",   element: "a",         attributes: { "class": "button",  "data-type": "primary" } }
      - { name: "Button Secondary", element: "a",         attributes: { "class": "button",  "data-type": "secondary" } }

    toolbarGroups:
      - { name: styles, groups: [ format, styles ] }
      - { name: basicstyles, groups: [ basicstyles ] }
      - { name: paragraph, groups: [ list, indent, blocks, align ] }
      - "/"
      - { name: links, groups: [ links ] }
      - { name: clipboard, groups: [ clipboard, cleanup, undo ] }
      - { name: editing, groups: [ spellchecker ] }
      - { name: insert, groups: [ insert ] }
      - { name: tools, groups: [ table, specialchar ] }
      - { name: document, groups: [ mode ] }

    format_tags: "p;h1;h2;h3;h4;h5"
    extraAllowedContent: "div;*(*)[data-*]"

    justifyClasses:
      - text-left
      - text-center

    extraPlugins:
      - justify
      - autolink
      - wordcount
      - autogrow

    removePlugins:
      - image

    removeButtons:
      - Anchor
      - Superscript
      - Subscript
      - Underline
      - Strike
      - JustifyBlock
      - JustifyRight

Hausgemachte Plugins

Zeilen 9 - 13

 9
10
11
12
13
  externalPlugins:
    sitepackage_responsivetable:
      resource: "EXT:sitepackage/Resources/Public/CKEditor/Plugins/Table/plugin.js"
    sitepackage_dataattributes:
      resource: "EXT:sitepackage/Resources/Public/CKEditor/Plugins/DataAttributes/plugin.js"
Hier werden zwei hausgemachte Plugins eingebunden.

sitepackage_responsivetable

Dieses Plugin stellt sicher, dass Tabellen auch responsiv (quer scrollbar) sind.

sitepackage_dataattributes

Dies ermöglicht in HTML-Tags zusätzliche data-type-Attribute hinzuzufügen. Dies ist in dem Beispielprojekt nötig, da zu einer Liste auch individuelle (aber vordefinierte) Icons hinzugefügt werden können sollen. Liste mit indivduellen Icons, erstellt per Plugin

Eine solche Extension zu erstellen ist gar nicht schwer. Die CKEditor-Doku lehrt dies pädagogisch vorbildlich am Beispiel eines Simple CKEditor 4 Plugin.

Styling mit webpack

Vorab die relevanten Zeilen und deren Bedeutung:

15
16
    contentsCss: "EXT:sitepackage/Resources/Public/Build/rte.css"
    bodyClass: "color-text font-base stack"

Zeile 15
Dies ist die CSS-Datei, mit welcher wir den CK-Editor mit Styling beliefern damit richtiges WYSIWYG-Gefühl aufkommt.

Zeile 16
Ein paar zusätzliche Klassen. Hierbei handelt es sich um Klassen die im Frontend dem Body-Tag hinzugefügt werden und für das Styling nötig sind.

Im CKEditor wollen wir nicht das gesamte CSS der Website laden, sondern nur jene Teile, die für das Styling des Textes relevant sind. Je nach Komplexität des Projektes geht das ansonsten auf die Performance im Backend.
Wir arbeiten in unseren TYPO3-Projekten mit Webpack Encore und der Extension typo3_encore von Sebastian Schreiber. An dieser Stelle: Vielen Dank für diese tolle Extension! 👏

Passgenaue CSS-Datei mit webpack erstellen

In der webpack.config.js fügen wir einen Style Entry hinzu, weil wir nur eine CSS-Datei erstellen wollen:

.addStyleEntry('rte', './assets/rte.scss')

In der rte.scss laden wir dann nur die für die Typografie notwendigen SCSS-Dateien, die wir natürlich alle fein aufgesplittet haben und somit modular laden können. Damit wirklich immer alle relevanten Styles geladen werden, schreiben wir alle Styles für den CKEditor eine eine SCSS-Datei und laden diese in der rte.scss:.

// Pull in global typography
@import 'basics/rte-styles';

Vorteil:
Wenn wir später noch mehr Textstyling hinzufügen werden wir auch nur in dieser Datei arbeiten und es wir automatisch auch im CKEditor erscheinen. Nice.

Interessante extraPlugins

Plugin autogrow

Zeilen 17 - 19 und 54

17
18
19
    autoGrow_bottomSpace: 50
    autoGrow_maxHeight: 900
    autoGrow_onStartup: 'true'
50
51
52
53
54
    extraPlugins:
      - justify
      - autolink
      - wordcount
      - autogrow
Standardmäßig sind die CKEditor-Fenster in TYPO3 recht klein. Man kann auch die Fenster so konfigurieren, dass sie größer sind, aber noch besser ist unserer Meinung nach das autogrow Plugin. Die Bedeutung der Zeilen 15 - 17 lässt sich wohl nicht besser beschreiben als in der Config-Doku von CKEditor.

Kurz mag ich es dennoch zusammenfassen: Das Eingabefenster hat leer seine vorkonfigurierte Höhe, wächst jedoch mit der Eingabe bis zu einer bestimmten Höhe und lässt unterhalb bis zu dieser Höhe immer etwas Luft. Das ist sehr angenehm, weil der Text dann nicht immer am unteren Rand klebt.

Plugin wordcount

Zeile 52

50
51
52
extraPlugins:
- justify
- autolink
Das Plugin wordcount lässt fast schon Word-Gefühle aufkommen. Wir sehen wir direkt in TYPO3 die Anzahl an Sätzen, Wörtern und Zeichen: Ansicht des CKEditor-Plugins wordcount Das ist nun natürlich nicht sooo notwendig aber doch manchmal ganz schön um zu sehen was man geschafft hat.

Sonstiges

Natürlich entfernen wir alle Buttons die Redakteur:innen nicht benutzen sollen (Zeilen 57 - 64), anderenfalls kommt am Ende nicht bei rum, was wir uns gewünscht haben…
Außerdem sind es weniger Buttons und das ist für die Bedienung grundsätzlich nicht verkehrt.

So, geschafft. Das war ein Ritt. Danke und bis zum nächsten Mal! 👋