Das WYSIWYG-Feld stellt Benutzern einen fortschrittlichen Richt-Text-Editor mit vielfältigen Möglichkeiten auf Basis des ProseMirror-Frameworks zur Verfügung. So können nicht nur Texte formatiert, sondern auch benutzerdefinierte Elemente (z.B. Bildergalerie) zur Verfügung gestellt und durch die Benutzer genutzt werden.
Der Hauptvorteil des WYSIWYG-Feldes ist seine flexible Integration, sowohl in einfacher als auch in komplexer Form. Als Entwickler kannst du entweder den direkt nutzbaren HTML-Code-Output des WYSIWYG-Feldes verwenden oder für eine tiefere Integration in dein Projekt die JSON-Ausgabe heranziehen. Dadurch lässt sich der Inhalt präzise an die spezifischen Anforderungen eines Projekts anpassen.
WYSIWYG-Feld im Headless-Kontext
In Flyo werden alle Einträge (Inhalte) unabhängig vom jeweiligen Ausgabekanal verwaltet. Das bedeutet, dass in den Feldern der Entitäten keine Informationen gespeichert werden, die spezifisch für das Styling eines Ausgabekanals (z.B. Webseite, Digital Signage-Screen oder Newsletter) sind.
Eine Webseite stellt beispielsweise ein Bild anders dar als ein Newsletter. Deshalb sollten Styling-Informationen nicht Teil der Einträge (Inhalte) in Flyo sein. Mit Flyo kannst du deshalb benutzerdefinierte Elemente für den WYSIWYG-Editor erstellen, die durch den Nutzer eingefügt werden können. Diese Elemente enthalten die relevanten Informationen (z.B. für einen Bilder-Slider), während im jeweiligen Ausgabekanal (z.B. die Webseite) definiert ist, wie das Element dargestellt wird.
Informationen aus WYSIWYG-Felder können entweder im JSON-Format oder im HTML-Format abgerufen werden. Während das JSON-Objekt einzig die Informationen enthält, liefert die HTML-Ausgabe auf Wunsch eine Grundform des Stylings mit.
Beispiele folgen.
Benutzerdefinierte Elemente
Ein benutzerdefiniertes Element ist ein selbst erstelltes Element, das über die Grundfunktionalität des Richt-Text-Editors hinausgeht. Als Entwickler kannst du die Eigenschaften des Elements definieren und die Darstellung seines Inhalts im HTML-Code steuern. Der Benutzer des Richt-Text-Editors kann das Element über einen Einfügen-Button im Editor seinem Inhalt hinzufügen. Diese benutzerdefinierten Elemente ermöglichen es, den Editor um komplexe Inhalte zu erweitern, die von der Frontend-Ausgabe unterstützt werden.

Beispiele für benutzerdefinierte Elemente
- Video-Embed-Elemente: YouTube, Vimeo oder andere Videoquellen, die direkt in den Text eingebettet werden können.
- Bilderkarussells: Interaktive Diashows, die mehrere Bilder in einem rotierenden Format anzeigen.
- Interaktive Karten: Google Maps oder andere Kartendienste, die benutzerdefinierte Markierungen und Routen anzeigen können.
- Produktkataloge: Spezifische Layouts für die Darstellung von Produkten mit Bild, Beschreibung, Preis und Bewertungsoptionen.
- Umfragen und Quizze: Interaktive Formulare, die Benutzerfeedback sammeln oder Wissen testen.
- Benutzerdefinierte Widgets: Beispielsweise Wetter-Widgets, Aktienkurse oder Echtzeitdaten von APIs.
- Formulare: Benutzerdefinierte Kontakt- oder Anmeldeformulare, die direkt im Text eingebettet werden können.
- Code-Snippets: Formatierte Codeblöcke für technische Dokumentationen oder Blogposts.
Diese benutzerdefinierten Elemente erweitern die Möglichkeiten des Flyo WYSIWYG-Editors erheblich und bieten Entwicklern und Nutzern flexible, anpassbare und interaktive Inhalte.
Hinzufügen von benutzerdefinierten Elementen zum Richt-Text-Editor
Benutzerdefinierte Elemente können für jedes Feld mit dem Feldtyp "Text Editor" definiert werden. Dies geschieht über Einstellungen → Entitäten → Entität X → Felder → Einstellungen. Dabei hast du die Flexibilität, für jedes WYSIWYG-Feld eigene benutzerdefinierte Elemente zu definieren. Unterschiedliche Entitäten können also auch unterschiedliche benutzerdefinierte Elemente enthalten.
Das folgende Bild illustriert den Prozess der Erstellung eines benutzerdefinierten Elements:
- (1) Als Eigenschaften des Elements gelten HTML-Attribute, die verschiedene Feldtypen wie Text, mehrzeiligen Text, Bild, Bilder, Datum, Farbe, Checkbox, Radio, Select und weitere umfassen können.
- (2) Der Name des Elements ist für die Verwendung im JSON-Code essentiell. Er muss einzigartig sein und darf keine Leerzeichen beinhalten.
Für die Definition der HTML-Ausgabe wird das Template-System Latte verwendet. Hierbei können alle Attribute mit {$name} angesprochen werden. Die so erstellte HTML-Ausgabe ersetzt dann das Element im HTML-Code. Dies ermöglicht die Verwendung komplexer benutzerdefinierter Elemente selbst in Ausgabekanälen mit einfacher HTML-Struktur. In diesem Abschnitt findest du Informationen zur Template Engine von Flyo.
Hinweis:
Bei der Arbeit mit den Eigenschaftstypen Bilder oder Dateien ist die Verwendung einer foreach-Schleife erforderlich:
<div>
{foreach $images as $image}
{if $image}
<img src="{$image}" alt="{$image}" />
{/if}
{/foreach}
</div>Einfügen eines benutzerdefinierten Elements im Editor
Das oben definierte Element wird im Editor folgendermassen dargestellt:

- (1) Das Element wird durch Klicken auf den "Einfügen"-Knopf hinzugefügt.
- (2) Die definierten Optionen werden angezeigt und können vom Benutzer bearbeitet werden.
Die JSON und HTML Ausgabe in einer Integration sieht dann wie folgt aus:
JSON:
{
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. "
}
]
},
{
"type": "Images",
"attrs": {
"images": [
{
"source": "https://storage.flyo.cloud/img1_0ae75102.png",
"caption": null,
"copyright": null,
"name": "img1.png"
},
{
"source": "https://storage.flyo.cloud/img2_98928571.png",
"caption": null,
"copyright": null,
"name": "img2.png"
}
],
"title": "This is the gallery title"
}
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet"
}
]
}
]
}Html:
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. </p>
<div>
<h3>This is the gallery title</h3>
<img src=\"https://storage.flyo.cloud/img1_0ae75102.png\" />
<img src=\"https://storage.flyo.cloud/img2_98928571.png\"/>
</div>
<p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet</p>Benutzerdefinierte Elemente aus einer anderen Organisation importieren
Liefert eine andere Flyo-Organisation ihre Inhalte über ein API SDK, kannst du sie mit der Import-Integration übernehmen, benutzerdefinierte Elemente eingeschlossen. Ein typischer Fall sind Blogbeiträge, die in beiden Organisationen erscheinen sollen.
Damit ein Element dabei ankommt, muss es hier unter demselben Elementnamen existieren und seine Eigenschaften müssen dieselben Identifier tragen. Bezeichnungen, Reihenfolge und HTML-Vorlage dürfen sich unterscheiden, die Darstellung bestimmst immer du. Bilder innerhalb der Elemente werden in deine Dateiverwaltung kopiert. Verweise auf Einträge, Seiten oder Dateien der Quellorganisation, ob als Eigenschaft eines Elements oder als Link im Fliesstext, werden entfernt, weil sie hier ins Leere führen würden. Was es hier nicht gibt, wird weggelassen und im Protokoll der Integration als Hinweis aufgeführt.
Die Einzelheiten stehen unter Import-Integration, Feldtyp wysiwyg.
Rekursive Inhalteingabe
Falls die Notwendigkeit besteht, den WYSIWYG-Editor dynamisch weiterhin innerhalb des Content-Elements zu nutzen, kann diese Option aktiviert werden. Dadurch kann der Benutzer die Funktionalität und Bequemlichkeit des Editors innerhalb des Elements weiterhin nutzen und sogar zusätzliche benutzerdefinierte Elemente einfügen oder verschachteln:

- (1) Die Option für die rekursive Inhalteingabe wird aktiviert.
- (2) In der HTML-Ausgabe steht nun die vordefinierte Variable {$content} zur Verfügung, die den Inhalt des Elements enthält.

- (1) Das Content-Element wird nun im Editor angezeigt und kann bearbeitet werden. Durch die aktivierte Option Rekursive Inhalteingabe kann der Benutzer weiterhin Inhalte eingeben, wie er es gewohnt ist, einschliesslich Formatierungen. Es ist sogar möglich, weitere benutzerdefinierte Elemente einzufügen, also eine Verschachtelung vorzunehmen.
- (2) Ein weiteres benutzerdefiniertes Element wurde als Rekursion eingefügt.
Die JSON und HTML Ausgabe in einer Integration sieht dann wie folgt aus:
JSON:
{
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. "
}
]
},
{
"type": "InfoBox",
"attrs": {
"author": "Flyo System"
},
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hier ist es mglich auch WYSIWYG Funktionalität zu verwenden wie "
},
{
"type": "text",
"marks": [
{
"type": "bold"
}
],
"text": "Fett"
},
{
"type": "text",
"text": " oder "
},
{
"type": "text",
"marks": [
{
"type": "italic"
}
],
"text": "Kursiv"
},
{
"type": "text",
"text": ", oder sogar andere Custom Element:"
}
]
},
{
"type": "Images",
"attrs": {
"images": [
{
"source": "https://storage.flyo.cloud/img1_0ae75102.png",
"caption": null,
"copyright": null,
"name": "img1.png"
}
],
"title": "Gallery Custom Element"
}
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet"
}
]
}
]
}HTML:
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. </p>
<div class=\"infobox\">
<p>Hier ist es mglich auch WYSIWYG Funktionalität zu verwenden wie <strong>Fett</strong> oder <em>Kursiv</em>, oder sogar andere Custom Element: </p>
<div>
<h3>Gallery Custom Element</h3>
<img src=\"https://storage.flyo.cloud/img1_0ae75102.png\" alt=\"https://storage.flyo.cloud/img1_0ae75102.png\" />
</div>
<p>Autor: Flyo System</p>
</div>
<p>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet</p>Inhalte, die als HTML ankommen
Der Editor speichert ein WYSIWYG-Feld als Dokument (das JSON) und erzeugt daraus das HTML. Kommt ein Inhalt nur als HTML an, zum Beispiel über eine Import-Integration, einen POST oder PUT über das API SDK oder eine KI-Automation, erstellt Flyo dieses Dokument beim Speichern selbst. Der Eintrag sieht im Editor danach genau so aus wie auf der Webseite, und er lässt sich dort ohne Umwege weiterbearbeiten.
Was übernommen wird
Übernommen wird alles, was der Editor selbst kann:
| HTML | Im Editor |
|---|---|
<p>, <br> | Absatz, Zeilenumbruch |
<h1> bis <h6> | Überschrift |
<ul>, <ol>, <li> | Aufzählung, nummerierte Liste |
<blockquote> | Zitat |
<pre>, <code> | Codeblock, Code im Text |
<hr> | Trennlinie |
<strong>, <b>, <em>, <i>, <s>, <del> | Fett, kursiv, durchgestrichen |
<a href="…"> | Link auf eine Webadresse, eine E-Mail-Adresse (mailto:) oder eine Telefonnummer (tel:). target="_blank" bleibt erhalten |
Blöcke, die der Editor nicht kennt (<div>, <section>, <article> und ähnliche), werden zu Absätzen, damit die Wörter davor und danach nicht zusammenkleben.
Bilder und Videos
Bilder und Videos gibt es im Editor nur als benutzerdefinierte Elemente. Flyo übernimmt sie deshalb nur, wenn das WYSIWYG-Feld ein Element mit dem passenden Elementnamen und einer Eigenschaft src hat:
| Im HTML | Elementname | Die Eigenschaft src erhält |
|---|---|---|
<img src="…" alt="…"> | image | Das Bild, heruntergeladen in deine Dateiverwaltung. alt landet in der Eigenschaft alt, wenn das Element eine hat |
<iframe> mit einem YouTube-Video | youtube | Die Einbettungsadresse https://www.youtube.com/embed/<Video-ID> |
<iframe> mit dem Vimeo-Player | vimeo | Die Video-ID |
Die Vorlagen «Bild», «YouTube» und «Vimeo» unter Organisation → Administration → Benutzerdefinierte Elemente sind genau so aufgebaut. Übernimmst du sie in das Feld, funktioniert die Übernahme ohne weitere Einstellungen.
- Ein Bild braucht eine vollständige Webadresse (
https://…). Ist die Datei in deiner Dateiverwaltung bereits vorhanden (gleiche Prüfsumme), wird sie wiederverwendet statt ein zweites Mal abgelegt. - YouTube wird in allen gängigen Adressformen erkannt (
youtube.com/embed/…,youtube.com/watch?v=…,youtube.com/shorts/…,youtu.be/…,youtube-nocookie.com/embed/…). Gespeichert wird immer die Einbettungsadresse, die aus der Video-ID neu aufgebaut wird. Parameter wieautoplayoderstartentfallen. - Vimeo wird über die Player-Adresse
player.vimeo.com/video/<Video-ID>erkannt.
Was weggelassen wird
- Bilder und Videos, für die das Feld kein passendes Element hat
- Andere eingebettete Inhalte:
<iframe>anderer Dienste (zum Beispiel Facebook oder Google Maps),<video>,<audio>, SVG-Grafiken - Bilder ohne vollständige Webadresse, zum Beispiel eingebettete
data:-Bilder oder relative Pfade - Tabellen: Der Text der Zellen bleibt als Absätze erhalten
- Formatierungen, die der Editor nicht kennt: Farben, Schriftgrössen, Unterstreichungen, Ausrichtung, CSS-Klassen und Inline-Styles. Der Text bleibt erhalten
- Scripts und Styles
Der Text selbst geht dabei nie verloren. Weil das HTML aus dem Dokument erzeugt wird, fehlt das Weggelassene aber auch auf der Webseite. Bei einem Import listet das Protokoll der Integration auf, was bei welchen Quell-IDs weggelassen wurde. Bei Schreibzugriffen über das API SDK und bei KI-Automationen geschieht das ohne Meldung.
Ausgabe
API
Die API liefert für ein WYSIWYG-Feld ausschliesslich den HTML-Code als String:
"inhalt": "<p>Lorem ipsum dolor sit amet...</p>"SDK / Nitro CMS
Integrationen wie Nitro CMS oder der API SDK liefern für ein WYSIWYG-Feld ein Objekt, das beide Formate enthält — HTML und JSON:
"inhalt": {
"html": "<p>Lorem ipsum dolor sit amet...</p>",
"json": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Lorem ipsum dolor sit amet..."
}
]
}
]
}
}Der JSON-Output basiert auf dem ProseMirror-Dokumentenmodell und kann mit jeder ProseMirror-kompatiblen Library verarbeitet werden. Flyo bietet bereits fertige Libraries für JavaScript und PHP an:
So kannst du flexibel wählen, ob du mit HTML oder JSON arbeiten möchtest, abhängig von den Anforderungen deines Projekts.
Leerer Wert
"inhalt": ""
