diff --git a/redmine-issue-workflow/SKILL.md b/redmine-issue-workflow/SKILL.md index 77bf908..2d65310 100644 --- a/redmine-issue-workflow/SKILL.md +++ b/redmine-issue-workflow/SKILL.md @@ -3,7 +3,7 @@ name: redmine-issue-workflow description: "Read and update issues on a self-hosted Redmine via its REST API from the CLI — list/read tickets, add notes, change status, edit an existing journal note in place, and download attachments. Use when a project tracks its work/bugs in Redmine and you need to look up 'the next fixes', check a ticket's details, mark work done, or maintain a collection ('Sammelticket') ticket. Covers: API-key auth via header (never inline the secret), the issues/journals/attachments endpoints, Textile (NOT Markdown) formatting, localized statuses, and the posting-style rules (keep customer-visible notes minimal — strike through or 'erledigt', don't write the bug's cause; don't post unless asked)." metadata: author: Wappler - version: "1.3" + version: "1.4" --- # Redmine issue workflow (REST API, CLI) @@ -52,6 +52,14 @@ Redmine renders **Textile** by default. Consequences: - Strike-through = `-text-` (Markdown `~~…~~` does nothing). - A leading `#` is an **ordered-list** item, not a heading (Markdown `#` headings render as `
  1. `). - Bold `*text*`, italic `_text_`, inline code `@code@`. +- **⚠ A strike-through ENDS at the first `-` inside the text.** Wrapping a whole sentence that contains + an arrow (`->`) closes the `` right there, leaving the tail — often the action item, "-> please + clarify" — un-struck, i.e. still looking open. Inserting a single space (`. ->`) makes that dash read + as an opener instead and the strike-through runs to the end. **HTML is no way out: Redmine escapes + `` in journal notes and the raw tag shows.** +- **Verify what you wrote actually RENDERED.** The API only tells you the source was stored. Fetch the + issue page with the same API-key header and grep for `` — it renders the Textile server-side, so + you see exactly what the customer sees. Worth it whenever you strike text through in place. ## Posting style (team rules — important) - **Don't post unless asked.** The user often does the Redmine updates themselves; offer/confirm first. diff --git a/typo3-staging-to-live-cutover/SKILL.md b/typo3-staging-to-live-cutover/SKILL.md index 9b3fe85..3bf559d 100644 --- a/typo3-staging-to-live-cutover/SKILL.md +++ b/typo3-staging-to-live-cutover/SKILL.md @@ -3,7 +3,7 @@ name: typo3-staging-to-live-cutover description: "Promote an approved TYPO3 staging site to production — the go-live step AFTER a staging environment exists. Use when a TYPO3 site is about to go live, when a staging/preview site must become the public site, when asked to clean up a staging server before launch, or when preparing a launch checklist for a shared/managed host. Covers: what must NOT travel to live (DB dumps, one-off SQL/PHP scripts, .bak files, error logs), the environment-specific config that must change (trustedHostsPattern, displayErrors, site base, DB credentials, mail), removing basic-auth/staging locks, indexing and redirects, scheduler and SSL, plus verification and rollback. Assumes the build already runs on staging (see the staging-deploy skill for that)." metadata: author: Wappler - version: "1.1" + version: "1.2" --- # TYPO3 — staging → live cutover @@ -135,6 +135,17 @@ Every one of these is pinned to staging and silently wrong on live. --- ## Phase 5 — Verify, then keep a way back +- **⚠ Some things CANNOT be tested before the cutover — find out which, early.** Third-party services + embedded in the site (portals, booking or download systems, maps, payment widgets) commonly restrict + who may frame them via `content-security-policy: frame-ancestors …`, listing only the LIVE domain. + On staging the browser then blocks the embed in **every** browser — it is the provider's + server-side policy, not a browser quirk, so "please test it in Chrome and Edge" is impossible to + fulfil there. Check with `curl -sI | grep -i content-security-policy`, and confirm in + the console (*"Framing … violates … The request has been blocked"*). Then either ask the provider to + add the staging host, or schedule that test for right after go-live and say so in the ticket rather + than leaving it looking unfinished. **You can still test your own half meanwhile** — that the page + passes the right parameters through, rejects foreign hosts, and survives the extra query parameter + without a cHash error. - **Rollback plan before the switch**: a final DB dump plus the previous DNS values, written down. Store the dump outside the docroot and **delete it once the launch is accepted** — otherwise it becomes exactly the Phase 1 problem on the live server. diff --git a/typo3-t3bootstrap-live-design-parity/SKILL.md b/typo3-t3bootstrap-live-design-parity/SKILL.md index 2f267ec..c0cb671 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, the t3b_core spacing system (spacing.yaml / tx_t3b_spacing) and why spacing must never be fixed in SCSS, 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 incl. why Bootstrap autoplay cannot be switched off via the interval), diagnosing regressions caused by an editor's SAVE (CKEditor dropping undeclared classes, FlexForm selects with no empty item flipping to "yes"), 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.5" + version: "1.6" --- # TYPO3 v14 t3bootstrap — live-design parity @@ -66,6 +66,30 @@ placeholders below from the site you're matching; keep a per-project log of what (getComputedStyle + walk `document.styleSheets` for the selector). Don't assume inheritance. 3. Diff vs DDEV → decide **setting vs SCSS** (below) → apply → flush → re-screenshot → verify. +## When the report is a rendering artefact, not a defect +Some "it looks broken" reports are sub-pixel rasterisation: a hairline that washes out, a circle whose +cap renders as a straight edge, an outline that vanishes. They are **display-dependent**, which is why +one person sees them and another does not, and why they come and go with the zoom level. + +- **First ask whether the reference site does the same.** If live emits the identical asset at the + identical size, it is not a regression — say so before spending a day on it. +- **A single zoom level proves nothing.** An element's box lands on a fractional device-pixel position + that depends on zoom AND on where it sits in the page. A change that looks like a fix at 100 % can + be measurably worse at 120 %. Always sweep several zoom levels **and** several sub-pixel offsets. +- **Measure the whole sweep in ONE call instead of a screenshot per variant.** Build each variant as an + SVG data-URL, `drawImage` it into a canvas at the exact device size and offset, and read the edge + rows with `getImageData`. Same rasteriser as the page, no screenshot round-trips: + ```js + ctx.drawImage(img, 0, offset, size, size); // size = base * zoom, offset = 0 … 0.8 + const d = ctx.getImageData(0, 0, n, n).data; // then count alpha>128 per row + ``` + Compare the top and bottom edge rows; a large difference is the asymmetry the user is seeing. +- **Know when to stop and say so.** Geometry often cannot fix it: shrinking a radius just moves the + bad zoom levels, thickening an inner ring changes nothing because the OUTER edge does the + rasterising, and making the icon bigger scales the artefact with it. Report the measurements and let + the customer decide between living with it and redrawing the asset — that is a design decision, not + a bug fix. Do not ship a change that your own numbers say is not an improvement. + ## Settings vs SCSS decision - **Setting** (`config/sites//settings.yaml`) for anything mapped in the theme's `Configuration/TypoScript/Plugin/Setup/tx_wsscss.typoscript`: `design.color.{primary,secondary, @@ -184,6 +208,23 @@ rewrite parts of it, and whatever was never expressible in the backend gets norm ## Layer 1 — Structural fixes (content that won't render). Do these FIRST. These are v11→v14 migration artifacts, not design; they recur across many pages. +- **⚠ Site-set page TSconfig does NOT reach records in storage folders beside the site root.** A site + set's `Configuration/Sets//page.tsconfig` only applies to pages in that site's ROOTLINE. + Storage folders for news, addresses, jobs are frequently SIBLINGS of the site root under a common + parent, not descendants — so TCEFORM you put in the set never reaches the editing form of those + records, while it visibly works on normal pages. Symptom: your TCA/TCEFORM change "does nothing" + for exactly one record type. **Check the storage folder's pid, not a content page:** + `BackendUtility::getPagesTSconfig()` in a CLI bootstrap, and compare with a site page. + **Fix:** move it to the extension's **global** `Configuration/page.tsconfig`, which TYPO3 loads for + every page. Load order then decides who wins — your sitepackage must load AFTER the extension you + are overriding (`vendor/bin/typo3 extension:list` to confirm), which it normally does. +- **The crop variant OFFERED to the editor may not be the one RENDERED.** Extensions ship global + page TSconfig that **replaces** the crop variants of a field with the single ratio their own layout + wants. If your templates request a different variant, an editor can crop all day with no effect and + the image is emitted uncropped. Trace BOTH ends before touching anything: which variant the template + asks for (often a setting such as `settings.imageFormat`, with a fallback for the literal value + `default`), and which variants the form offers at that record's pid. They must be the same name. + - **Stranded `colPos=1` (the #1 recurring bug).** v11 content sitting at `colPos 1` (or 2/3) is not rendered by the v14 backend layout → the page looks half-empty though the content is in the DB. Find it site-wide: @@ -239,6 +280,24 @@ These are v11→v14 migration artifacts, not design; they recur across many page - **Repeated items (cards/teasers/logos/icon tiles):** live usually forces **equal height AND width** across the row (`height:100%` in an equal-height row; images `object-fit:cover` + fixed height; logo boxes equal size). DDEV often renders ragged — measure siblings, don't assume. + - **⚠ A FIXED HEIGHT on a cropped image box drifts in aspect ratio across breakpoints.** The height + stays put while the column width grows, so the same box is e.g. 1.58 on desktop and 1.82 on a + phone — and then **no single crop variant can fit both**, which reads as "the crop is off" on one + device. Use `aspect-ratio: / ; height: auto` instead so the box keeps ONE ratio everywhere, + then one crop variant is enough. Measure live's box before choosing the ratio; it usually already + holds a constant one. + - **⚠ Wrapped labels under tiles: reserve the line box, or the grid rhythm breaks.** In a wrapping + Bootstrap row each flex line sizes itself from its tallest item, so one two-line label makes that + whole row taller and the icon-to-icon pitch varies. Give the label `min-height: × + line-height` **and zero the label `

    `'s bottom margin** — otherwise that margin is added on + exactly the tiles that actually reach the maximum, which are the ones you were trying to level. + Derive `maxLines` per breakpoint by measuring, and **check the narrowest device (320px), not just + 360** — the extra column narrowness there routinely needs one line more. + - **⚠ `:has()` cannot be nested inside `:has()` — the whole rule is silently discarded.** A selector + like `.a:has(.x):has(+ .a:has(.x))` is invalid CSS, so the browser drops it entirely and you get + no error anywhere. Very easy to write when chaining "frame that is followed by another frame" + rules. If a rule seems to have no effect, check the computed value on the element first; a + property that never appears at all points at an invalid selector, not at specificity. - **background-media hero image** (textmedia with `asBackground`, usually empty text — e.g. section landing/"Auftraggeber" pages): the image is a CSS background on a grid column sitting on a grey band. Live renders it **flush + container-width**; DDEV insets it (frame `t3b-pt-l/pb-l` padding + a diff --git a/typo3-v11-to-v14-ddev-upgrade/SKILL.md b/typo3-v11-to-v14-ddev-upgrade/SKILL.md index d1cdab0..9852698 100644 --- a/typo3-v11-to-v14-ddev-upgrade/SKILL.md +++ b/typo3-v11-to-v14-ddev-upgrade/SKILL.md @@ -3,7 +3,7 @@ name: typo3-v11-to-v14-ddev-upgrade description: "Bring an existing TYPO3 v11 site up and booting on TYPO3 v14 LTS (v14.3) locally under DDEV, starting from a v11 SQL dump + the old sitepackage. Use when upgrading/migrating a TYPO3 v11 (or v12/13) project to v14 for local dev, when a v11 database dump must be made to boot on v14, when a t3bootstrap-based v11 site needs its composer/config/schema/upgrade-wizards/site-sets brought to v14, or when after such an upgrade a non-admin editor can't edit content (no edit icons / missing Media tab). Covers: composer.json rework to ^14 + private git repos & composer registry auth, config/system/settings.php, the v14 .htaccess, database:updateschema, backend admin, upgrade wizards (incl. confirmable + one-way ones), language packs, wiring t3bootstrap TypoScript via site sets, fixing non-admin editor permissions (be_groups explicit_allowdeny :ALLOW-format conversion, v14 CType allow-list, non_exclude_fields), and the recurring v11->v14 traps. NOT for fresh installs and NOT for server deployment (see the konsoleH staging-deploy skill for that)." metadata: author: Wappler - version: "1.1" + version: "1.2" --- # TYPO3 v11 → v14 upgrade (local, DDEV) @@ -174,5 +174,24 @@ found" is usually a false alarm from curling `localhost`** instead of ` = , = 1 WHERE <> '' AND ( = '' OR IS NULL)`, and verify + afterwards that no row was touched which should not have been. + - **Then check whether anything RENDERS the switch.** A flag that no template evaluates — not even + the owning extension's own templates — is exactly why the data looked lost. Grep the templates for + the property before assuming the display side works. + - Fluid has **no `!` operator**: write `{x} && {flag} == 0` / `== 1`, not `!{flag}`. +- **⚠ Verify against the reference site before calling something a regression.** Two tickets can + describe the same missing element and be different things: on one page the old site really did show + it (a migration loss), on another it never did (a new wish). Fetch the live page and count the + occurrences. It changes what you promise, and it saves the "why does it look different from before" + conversation later. Each step verified + a snapshot before wizards = a reversible, debuggable upgrade.