CMS: Absatz-Tags aus dem Rich-Text-Editor erscheinen nicht mehr als Text
Der Editor packt eingefügten Text in <p>; Felder wie die FAQ-Antwort gibt die Website als Text aus, die Tags waren sichtbar. Beim Speichern entfernt unwrapParagraphs() die Absätze (ein Absatz ohne <p>, mehrere mit <br><br>, Blockinhalte unverändert). cms_inline() gibt die Felder als bereinigtes Inline-HTML aus – auch schon gespeicherte Texte mit <p> erscheinen sauber, Fett und Hervorhebung werden dargestellt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
07816dce19
commit
451e738c8b
20 changed files with 147 additions and 23 deletions
|
|
@ -48,6 +48,30 @@ final class CmsFluxEditorHtmlTransformer
|
|||
return self::marksToSecondarySpans($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Der Editor packt jeden Text in Absätze – auch eingefügten Klartext (12.10.2026). Für Felder,
|
||||
* die die Website innerhalb einer Zeile oder eines eigenen Absatzes ausgibt, wird daraus
|
||||
* Inline-HTML: ein Absatz ohne `<p>`, mehrere durch `<br><br>` getrennt, reiner Text als
|
||||
* Klartext. Enthält der Text Blockelemente (Überschriften, Listen …), bleibt er unverändert.
|
||||
*/
|
||||
public static function unwrapParagraphs(string $html): string
|
||||
{
|
||||
$html = trim((string) preg_replace('#<p[^>]*>(\s| |<br\s*/?>)*</p>#i', '', $html));
|
||||
|
||||
if ($html === '' || ! str_contains($html, '<p')) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
if (preg_match('#<(?!/?(?:p|strong|b|em|i|mark|span|br|a)\b)[a-z]#i', $html) === 1) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$html = (string) preg_replace('#</p>\s*<p[^>]*>#i', '<br><br>', $html);
|
||||
$html = trim((string) preg_replace('#^<p[^>]*>|</p>$#i', '', $html));
|
||||
|
||||
return str_contains($html, '<') ? $html : html_entity_decode($html, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, array<string, mixed>|array{_value: string}> $items
|
||||
* @return array<int, array<string, mixed>|array{_value: string}>
|
||||
|
|
@ -92,7 +116,7 @@ final class CmsFluxEditorHtmlTransformer
|
|||
$out = [];
|
||||
foreach ($item as $key => $value) {
|
||||
if (in_array($key, self::RICH_TEXT_JSON_FIELDS, true) && is_string($value)) {
|
||||
$out[$key] = self::fromEditor($value);
|
||||
$out[$key] = self::unwrapParagraphs(self::fromEditor($value));
|
||||
} else {
|
||||
$out[$key] = $value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,37 @@ if (! function_exists('references_page_enabled')) {
|
|||
}
|
||||
}
|
||||
|
||||
if (! function_exists('cms_inline')) {
|
||||
/**
|
||||
* CMS-Text für die Ausgabe innerhalb einer Zeile oder eines Absatzes (12.10.2026): Klartext
|
||||
* wird escaped, Editor-HTML auf Inline-Auszeichnung reduziert (fett, kursiv, Hervorhebung,
|
||||
* Links, Zeilenumbrüche) – Absatz-Tags aus dem Editor erscheinen so nicht als Text.
|
||||
*/
|
||||
function cms_inline(mixed $value): \Illuminate\Support\HtmlString
|
||||
{
|
||||
$text = trim((string) $value);
|
||||
|
||||
if (! str_contains($text, '<')) {
|
||||
return new \Illuminate\Support\HtmlString(e(html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8')));
|
||||
}
|
||||
|
||||
$html = \App\Services\CmsFluxEditorHtmlTransformer::unwrapParagraphs(
|
||||
\App\Services\CmsFluxEditorHtmlTransformer::fromEditor($text)
|
||||
);
|
||||
|
||||
if (! str_contains($html, '<')) {
|
||||
return new \Illuminate\Support\HtmlString(e($html));
|
||||
}
|
||||
$html = (string) preg_replace('#</(p|div|li|h[1-6])>\s*<\1[^>]*>#i', '<br><br>', $html);
|
||||
$html = strip_tags($html, '<strong><b><em><i><span><br><a>');
|
||||
// Nur harmlose Attribute: keine Event-Handler, keine javascript:-Links.
|
||||
$html = (string) preg_replace('#\s+on[a-z]+\s*=\s*("[^"]*"|\'[^\']*\'|[^\s>]+)#i', '', $html);
|
||||
$html = (string) preg_replace('#href\s*=\s*(["\'])\s*javascript:[^"\']*\1#i', 'href="#"', $html);
|
||||
|
||||
return new \Illuminate\Support\HtmlString(trim($html));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('whatsapp_link')) {
|
||||
/**
|
||||
* Klick-zum-Chat-Link, sofern im CMS eine Nummer hinterlegt ist (global.contact.whatsapp).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue