From 53be3ef8986ff07ed6af15167a3ca28dec31c61b Mon Sep 17 00:00:00 2001 From: Ilja Melnicenko Date: Tue, 21 Jul 2026 11:44:31 +0200 Subject: [PATCH] design-parity: RTE field rendered escaped by custom template (literal

) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the fragile "store raw bodytext only" workaround with the durable fix: when a custom Fluid partial renders an RTE field (enableRichtext=true, e.g. tx_heroitem.bodytext), the backend RTE->DB transform wraps it in

on every editor save, and a bare {field} / f:format.nl2br render escapes it -> literal

on the page. Render RTE fields with f:format.html. Add the general rule (check TCA enableRichtext; sweep your own/overridden partials for nl2br/bare RTE output) and note core templates already do this. Bump to v1.2. Co-Authored-By: Claude Opus 4.8 (1M context) --- typo3-t3bootstrap-live-design-parity/SKILL.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/typo3-t3bootstrap-live-design-parity/SKILL.md b/typo3-t3bootstrap-live-design-parity/SKILL.md index 3797ee0..2e24a53 100644 --- a/typo3-t3bootstrap-live-design-parity/SKILL.md +++ b/typo3-t3bootstrap-live-design-parity/SKILL.md @@ -3,7 +3,7 @@ name: typo3-t3bootstrap-live-design-parity description: "Match a TYPO3 v14 t3bootstrap-based build (local DDEV) to a reference LIVE site page by page — the frontend/design phase after a v11->v14 upgrade. Use when making an upgraded TYPO3 site look like its old/live counterpart, when doing per-page visual parity against a reference URL, when content that exists in the DB isn't rendering after a v11->v14 migration, or when customizing a t3bootstrap sitepackage's templates/SCSS/settings. Covers: the Playwright compare loop (computed style + CSS rule), the settings-vs-SCSS decision, recurring structural fixes (stranded colPos, missing templateLayout partials, template partialRootPaths precedence/shadowing, on-demand component CSS, unregistered CTypes), a full visual-parity checklist (layout/width, typography, colors, links/buttons, equal-sizing, icons, borders, footer, header/nav, hero carousel), and cache-safe techniques (full-bleed bands, image-border restyle, responsive crop variants, client-side randomisation, FAL-via-DataHandler). Assumes the site already boots on v14 (see the v11->v14 upgrade skill)." metadata: author: Wappler - version: "1.1" + version: "1.2" --- # TYPO3 v14 t3bootstrap — live-design parity @@ -191,9 +191,20 @@ These are v11→v14 migration artifacts, not design; they recur across many page clone the sibling `tt_content` row and its `sys_file_reference` via `ConnectionPool` (unset `uid`, repoint the ref's `uid_local`/`uid_foreign`) — the copied file-count column stays correct, so it sidesteps the `uid_foreign=0` gotcha entirely. - - **Plain-text bodytext fields (hero-item etc.):** some CTypes store `bodytext` as PLAIN text and the - template wraps it in `

` + escapes on render. Storing your own `

` (or html-escaping) - double-escapes → literal `<p>` shows on the page. Store the raw sentence only. + - **RTE field rendered escaped by a custom template → literal `

` on the page.** Symptom: after an + editor edits+saves an element (e.g. a hero slide — even just its title), its rich-text field shows + literal `

` in the FE. Cause: the field is **RTE** (`enableRichtext=true` in TCA — e.g. + `tx_heroitem.bodytext` in `t3bootstrap/hero-item`), so the backend's RTE→DB transform wraps the value + in `

` on every save, but the custom Fluid partial renders it as ESCAPED plain text + (`

{…bodytext -> f:format.nl2br()}

` or a bare `{…}`) → the tags are escaped and shown. FIX = + render it as the RTE HTML it is: `{record.data. -> f:format.html()}` (lib.parseFunc_RTE), and + drop the manual `

`/`nl2br`. This renders editor-saved `

` correctly AND wraps raw + (script-imported) text in a paragraph — so no per-slide data cleanup. (A bulk-import script that + stores RAW text into an RTE field hides this until the first editor save — don't rely on that; + fix the template.) **General rule:** whenever a custom template renders a field, check the field's TCA + `enableRichtext` — if true, use `f:format.html`, never bare `{field}` or `f:format.nl2br` (both + escape). Core/t3b_core templates already do this (e.g. image caption `text_visible`, news `teaser`), + so the risk is only in your own/overridden partials — sweep them for `nl2br`/bare RTE-field output. - **Applying customer copy across DDEV+staging:** key the UPDATE on a stable identifier (e.g. the bg **image filename** via `tt_content→sys_file_reference→sys_file`), since row uids differ per env.