CKEditor-5-Integration für REDAXO mit profilbasierter Konfiguration, REDAXO-Medien- und Link-Dialogen, Snippets, Style-Management und Import/Export-Workflows.
Aktuelle Beta-Version: 7.0.0-beta1
- Umstellung auf den offiziellen CKEditor-5-Build als Basis
- Neue native Runtime-Plugins und überarbeitete Dialoge
- Templates durch Snippets ersetzt
- Erweiterter Profil-Export/Import inklusive abhängiger Daten:
- profiles
- style_groups
- styles
- snippets
- Neue Entwicklerdokumentation in
dev.md - Bereinigung von Legacy- und verwaisten Vendor-/Runtime-Dateien
- Neue globale Defaults-Seite (
Profiles > Defaults > Global settings) für Mentions, Sprog-Ersetzungen, yTables, Medien-Defaults und Schriftfamilien-Defaults - Neuer Editor-Typ
classic_balloonsowie konfigurierbare Balloon-Toolbar im Profilmanager - Verbesserte Merge-/Fallback-Logik zwischen Profilwerten und globalen Defaults
- UX-Fixes im Profil-/Defaults-Widget-Handling (Mention-Beispiele, stabile Placeholder, robuste Toggle-/Collapse-Initialisierung)
- Neues QuickEdit-Befehlsmenü über
/, global schaltbar und über andere AddOns erweiterbar
- Moderne CKEditor-5-Integration im REDAXO-Backend
- Theme-Unterstützung (
dark,auto,notheme) - Sprachabhängige Platzhalter sowie UI-/Content-Sprachsteuerung
- Höhensteuerung per Datenattributen (
data-min-height,data-max-height) - Stabile Initialisierung für dynamische/repetierende Felder (z. B. MBlock)
- Profilmanager für Editor-Konfigurationen
- Drag-and-drop-/Tag-basierter Profil-Editor
- Expertenmodus mit
expert_definition+expert_suboption - Vorschau-Seite mit Integrationsbeispielen und Profil-Details
- Einzelne Styles mit Element/Klassen und optionalem CSS
- Style-Gruppen mit JSON-Konfiguration und optionalem CSS
- Snippets pro Profil auswählbar (Ersatz für Templates)
- Auto-generiertes Backend-CSS aus Style-/Gruppen-Definitionen
- REDAXO-Medienintegration (
openREXMedia) für Bildeinfügen/-ersetzen - REDAXO-Linkintegration (
openLinkMap, Medienlinks,mailto:,tel:, YTable) - Bild-Upload-Endpunkt für Mediapool-Uploads
- Absicherung der Bild-Link-Funktion in der Bild-Toolbar (
linkImage)
- Native Addon-Plugins zur Laufzeit:
RedaxoLinkIntegrationRedaxoMediaImageRedaxoClearWidgetRedaxoQuickEditRedaxoSnippetsRedaxoPastePlainTextToggleRedaxoMarkdownPasteToggleRedaxoMinimapToggleRedaxoVideoWidgetTest
- Unterstützung externer Plugins über Registry und JS-Konfiguration
- Toolbar-Alias-Transformationen für externe Plugins
QuickEdit öffnet im Editor über / eine Befehlsliste an der Cursorposition. Angezeigt werden nur Befehle, die zur aktuellen Profilkonfiguration passen, zum Beispiel nur aktivierte Überschrift-Ebenen oder nur Medien-/Widget-Aktionen, wenn der zugehörige Toolbar-Eintrag im Profil vorhanden ist.
Die Funktion kann global unter CKEditor 5 > Profiles > Defaults > Global settings deaktiviert werden. Gespeichert wird im normalen rex_config_form-Format; |1| aktiviert QuickEdit, null oder ein leerer Wert deaktiviert es. Wenn der Config-Key noch gar nicht existiert, ist QuickEdit aus Kompatibilitätsgründen standardmäßig aktiv.
Andere AddOns können eigene Menüeinträge ergänzen, indem sie eine JavaScript-Datei laden, bevor Editor-Instanzen erzeugt werden. Empfohlen ist die Registrierung über die CKE5-PluginRegistry im eigenen AddOn, zum Beispiel in boot.php:
<?php
use Cke5\PluginRegistry;
if (rex::isBackend() && rex_addon::get('cke5')->isAvailable()) {
PluginRegistry::addPlugin(
'my_quickedit_commands',
rex_url::addonAssets('my_addon', 'js/cke5-quickedit-commands.js')
);
}Die geladene JavaScript-Datei erweitert window.CKE5_QUICKEDIT_COMMANDS:
window.CKE5_QUICKEDIT_COMMANDS = window.CKE5_QUICKEDIT_COMMANDS || [];
window.CKE5_QUICKEDIT_COMMANDS.push({
id: 'myQuickAction',
label: 'Meine Aktion',
keys: ['mein', 'aktion'],
icon: 'M',
toolbarItem: 'link',
execute: function (editor) {
editor.execute('link', 'https://redaxo.org');
}
});Unterstützte Eigenschaften:
id: eindeutiger technischer Name des Befehls.label: Text im QuickEdit-Menü.keys: optionale Suchbegriffe für die Filterung nach/....icon: kurzer Text/Icon für die linke Spalte.toolbarItem: Toolbar-Eintrag, der im Profil vorhanden sein muss.toolbarAny: alternative Toolbar-Einträge, von denen mindestens einer vorhanden sein muss.command: CKEditor-Command, der ausgeführt werden soll.commandArgs: optionale Argumente füreditor.execute(command, commandArgs).execute(editor): eigene Ausführungslogik, wenn kein Standard-Command reicht.
Ein Eintrag wird nur angezeigt, wenn sein toolbarItem bzw. eines der toolbarAny-Items im aktiven Profil vorhanden ist. Bei command muss der CKEditor-Command zusätzlich registriert sein.
- Addon installieren (Installer oder Deployment).
- REDAXO-Update/Install-Routine ausführen.
- Unter
CKEditor 5 > Profilesmindestens ein Profil konfigurieren. - Profil im Textarea über
data-profileverwenden.
<textarea
class="form-control cke5-editor"
data-profile="default"
data-lang="<?php echo \Cke5\Utils\Cke5Lang::getUserLang(); ?>"
data-content-lang="<?php echo \Cke5\Utils\Cke5Lang::getOutputLang(); ?>"
name="REX_INPUT_VALUE[1]"
>REX_VALUE[1]</textarea><textarea
class="form-control cke5-editor"
data-profile="default"
data-min-height="220"
data-max-height="700"
data-lang="<?php echo \Cke5\Utils\Cke5Lang::getUserLang(); ?>"
name="REX_INPUT_VALUE[2]"
>REX_VALUE[2]</textarea>REX_VALUE[id="1" output="html"]$mform = new MForm();
$mform->addTextAreaField(1, [
'label' => 'Text',
'class' => 'cke5-editor',
'data-profile' => 'default',
'data-lang' => \Cke5\Utils\Cke5Lang::getUserLang(),
'data-content-lang' => \Cke5\Utils\Cke5Lang::getOutputLang(),
]);
echo $mform->show();$id = 1;
$mform = new MForm();
$mform->addFieldset('Accordion');
$mform->addTextField("$id.0.title", ['label' => 'Titel']);
$mform->addTextAreaField("$id.0.text", [
'label' => 'Text',
'class' => 'cke5-editor',
'data-profile' => 'default',
'data-lang' => \Cke5\Utils\Cke5Lang::getUserLang(),
'data-content-lang' => \Cke5\Utils\Cke5Lang::getOutputLang(),
]);
echo MBlock::show($id, $mform->show());{"class":"cke5-editor","data-profile":"default","data-lang":"de","data-content-lang":"de"}- Toolbar verwendet CKEditor-IDs (
link,insertImage,snippets, ...). - Legacy-Aliase werden intern migriert/normalisiert, wo nötig.
- Snippets werden pro Profil ausgewählt.
- Style-Gruppen und Styles werden pro Profil gewählt und zusammengeführt.
- Im Profil-Editor können Platzhalter pro REDAXO-Sprache gesetzt werden.
Mehrere Profilfelder erwarten JSON-Eingaben. Hier sind funktionierende Startbeispiele.
Damit definierst du manuelle Link-Decorator. Ein typischer Anwendungsfall sind Bootstrap-ähnliche Link-Buttons.
[
{
"btnPrimary": {
"mode": "manual",
"label": "Button Primary",
"attributes": {
"class": "btn btn-primary",
"role": "button"
}
}
},
{
"btnOutline": {
"mode": "manual",
"label": "Button Outline",
"attributes": {
"class": "btn btn-outline-secondary",
"role": "button"
}
}
},
{
"nofollow": {
"mode": "manual",
"label": "Nofollow setzen",
"attributes": {
"rel": "nofollow"
}
}
}
]Hinweis: Dieses JSON wird in link.decorators des generierten CKEditor-Profils zusammengeführt.
Exklusive Decorator-Gruppen (immer nur einer gleichzeitig):
Wenn mehrere manuelle Decorators gegenseitig exklusiv sein sollen (z. B. Button-Varianten, Farb-Varianten, Badge-Varianten), gib ihnen denselben Wert in redaxoExclusiveGroup.
Beispiel:
[
{
"btnPrimary": {
"mode": "manual",
"label": "Button Primary",
"classes": "btn btn-primary",
"redaxoExclusiveGroup": "linkButtonStyle"
}
},
{
"btnSuccess": {
"mode": "manual",
"label": "Button Success",
"classes": "btn btn-success",
"redaxoExclusiveGroup": "linkButtonStyle"
}
},
{
"nofollow": {
"mode": "manual",
"label": "Nofollow setzen",
"attributes": {
"rel": "nofollow"
}
}
}
]Ergebnis: Im Link-Dialog kann immer nur ein Decorator aus linkButtonStyle aktiv sein. Unabhängige Decorators wie nofollow bleiben parallel nutzbar.
Definiert eigene Mention-Feeds.
[
{
"marker": "@",
"minimumCharacters": 1,
"feed": ["@support", "@sales", "@redaktion", "@admin"]
},
{
"marker": "#",
"minimumCharacters": 1,
"feed": ["#news", "#release", "#event", "#faq"]
}
]Sprog-Ersetzungen sind JSON-basiert und werden über den Marker { angeboten.
[
{ "id": "{{company}}", "text": "Friends Of REDAXO" },
{ "id": "{{support_mail}}", "text": "support@example.org" },
{ "id": "{{hotline}}", "text": "+49 000 123456" }
]Definiert feste Größenoptionen für die Bild-Toolbar.
[
{ "name": "resizeImage:original", "label": "Original", "value": null },
{ "name": "resizeImage:25", "label": "25%", "value": "25" },
{ "name": "resizeImage:50", "label": "50%", "value": "50" },
{ "name": "resizeImage:75", "label": "75%", "value": "75" }
]Hinweis: Das Addon normalisiert die Namen intern beim Profilaufbau.
Ergänzt zusätzliche Typing-Transformationen.
[
{ "from": "->", "to": "→" },
{ "from": "<-", "to": "←" },
{ "from": "(c)", "to": "©" },
{ "from": "(r)", "to": "®" }
]Erlaubt zusätzliche Elemente/Attribute/Klassen/Styles.
[
{
"name": "regex(/^(section|article|div)$/)",
"attributes": true,
"classes": true,
"styles": true
},
{
"name": "a",
"attributes": ["target", "rel", "data-bs-toggle", "data-bs-target"],
"classes": ["btn", "btn-primary", "btn-outline-secondary"],
"styles": false
}
]Sperrt bestimmte Muster, selbst wenn sie anderweitig erlaubt sind.
[
{
"name": "script",
"attributes": true,
"classes": true,
"styles": true
},
{
"name": "*",
"attributes": ["on.*"]
}
]Erweiterte Roh-Konfiguration, die direkt in das generierte Profil-JSON gemerged wird. Mit Vorsicht einsetzen.
{
"removePlugins": ["Autoformat"],
"heading": {
"options": [
{ "model": "paragraph", "title": "Paragraph", "class": "ck-heading_paragraph" },
{ "model": "heading2", "view": "h2", "title": "H2", "class": "ck-heading_heading2" }
]
}
}Hinweis: removePlugins aus diesem Feld wird mit der bestehenden Liste zusammengeführt.
- Immer gültiges JSON verwenden (doppelte Anführungszeichen, keine trailing commas).
- Mit kleinen JSON-Blöcken starten und zuerst in einem Profil testen.
- Wenn etwas nicht greift, in der Profilvorschau das generierte JSON prüfen.
Templates sind nicht mehr Teil des aktiven Workflows. Für wiederverwendbare Inhaltsbausteine werden Snippets verwendet.
Empfohlener Ablauf:
- Snippets unter
Profiles > Customise > Snippetsanlegen. - Snippets einem oder mehreren Profilen zuweisen.
- Button
snippetsin der Toolbar aktivieren.
Profiles > Export exportiert gewählte Profile inklusive Abhängigkeiten.
Export-Payload enthält:
profilesstyle_groupsstylessnippets
Profiles > Import unterstützt:
- neues Bundle-Format (Profile + Abhängigkeiten)
- Legacy-Format (nur Profile)
Beim Bundle-Import erfolgt ein ID-basiertes Upsert für die abhängigen Tabellen, danach der Profilimport.
CKEditor 5 > Config bietet:
- Lizenzschlüssel-Konfiguration
- Upload/Ersetzen der Editor-Runtime (
.js,.js.map) - Upload/Ersetzen von Übersetzungsdateien (
.js)
Standard-Runtimepfad ist der moderne Build unter:
assets/addons/cke5/vendor/ckeditor5-modern/
Programmgesteuert ein Expertenprofil anlegen:
use Cke5\Creator\Cke5ProfilesApi;
$definition = json_encode([
'toolbar' => [
'items' => ['heading', '|', 'bold', 'italic', 'link', 'snippets', 'undo', 'redo'],
],
], JSON_UNESCAPED_UNICODE);
Cke5ProfilesApi::addProfile(
'project_expert',
'Projekt-Expertenprofil',
$definition,
null
);Kombinierbar sind:
- statisches Custom-CSS in Addon-/Projekt-Assets
- generiertes CSS aus Style-/Gruppen-Definitionen
- optionale externe CSS-Pfade pro Style/Style-Gruppe
Bei Änderungen an Styles/Style-Gruppen werden die Backend-CSS-Artefakte neu erzeugt.
Für Build-Quellen, Runtime-Plugin-Architektur und Einbindung externer Plugins siehe:
PLUGIN_DEVELOPMENT.md
- Prüfen, ob die Textarea die Klasse
cke5-editorbesitzt. - Prüfen, ob
data-profileauf ein vorhandenes Profil zeigt. - Prüfen, ob
cke5profiles.jserzeugt und geladen wurde.
- Prüfen, ob
linkImagein der Bild-Toolbar enthalten ist. - Prüfen, ob der Build das Plugin
LinkImageenthält. - Nach JS-Änderungen Backend hart neu laden.
- Übersetzungspfad und Dateien in der Config-Seite prüfen.
- Prüfen, ob Profil-/Benutzersprache zu vorhandenen CKEditor-Translation-Dateien passt.
Projekt-Lead
Danke an alle Contributors, die CKEditor 5 für REDAXO über die Jahre mitgestaltet haben!
Top Contributors
| Contributor | |
|---|---|
| 1 | crydotsnake |
| 2 | interweave-media |
| 3 | staabm |
| 4 | nandes2062 |
| 5 | TobiasKrais |
| 6 | schuer |
| 7 | marcohanke |
| 8 | eaCe |
Ein herzliches Dankeschön auch an aeberhard, Bio-GitHub, dergel, V-Simos, VIEWSION, ynamite und ischfr.
Bildnachweise
Demo-Inhalt Bild: Frankfurt am Main Skyline von Leonhard_Niederwimmer auf Pixabay — kostenlos nutzbar unter der Pixabay Content License.
Friends of REDAXO Logo: friendsofredaxo.github.io — © Friends of REDAXO.
Ein Projekt von Friends Of REDAXO