diff --git a/.agents/skills/t3bootstrap-site-settings/SKILL.md b/.agents/skills/t3bootstrap-site-settings/SKILL.md new file mode 100644 index 0000000..a42371e --- /dev/null +++ b/.agents/skills/t3bootstrap-site-settings/SKILL.md @@ -0,0 +1,698 @@ +--- +name: t3bootstrap-site-settings +description: Configure a T3Bootstrap-based TYPO3 v14 project via Site Settings — the structured YAML/Backend-Editor surface that replaces TypoScript constants. Catalog of ~200+ typed settings exposed by `t3bootstrap/template`, `t3bootstrap/core`, and the major add-on sets (blog, gallery), grouped by category (header, navigation, design colors, design fonts, body, footer, meta/favicons, search, assets, breakpoints, container widths, spacing steps, icons, buttons, privacy, expert, CTA-bar with social links). Includes the YAML structure for `config/sites//settings.yaml`, the special custom setting types (`ctabaritemlist`, `ctabuttonlist`, `calltoactionlist`) that t3bootstrap ships, a cookbook of common configuration tasks, and anti-patterns. Use this skill whenever changing colors, fonts, navigation behavior, header layout, sticky behavior, mobile menu type, dark mode, breakpoints, spacing system, footer content, search wiring, favicon/manifest, social links, or any other declarative configuration in a T3Bootstrap project. +--- + +# T3Bootstrap Site Settings + +Use this skill to configure a T3Bootstrap-based TYPO3 v14 project via **Site Settings** +instead of TypoScript constants. The stack ships ~200+ typed settings across two +`settings.definitions.yaml` files (plus add-on definitions) — this catalog tells you +which key controls what, where it's defined, and how to set it. + +> **Companion skills:** +> - [`t3bootstrap-site-package`](../t3bootstrap-site-package/SKILL.md) — get the right sets into the site config first; settings only take effect once the providing set is listed in `dependencies`. +> - [`t3bootstrap-overrides`](../t3bootstrap-overrides/SKILL.md) — when a setting doesn't expose what you need, escalate to SCSS/Fluid override. + +## How Settings Are Resolved (v14) + +TYPO3 v14 unifies "typed Site Settings" and TypoScript constants: + +1. Each extension's `Configuration/Sets//settings.definitions.yaml` declares + typed settings with category, default value, label, optional `enum`. +2. **Defaults** live next to the definitions in `settings.yaml` (only set if non-default). +3. A site can **override** any setting in `config/sites//settings.yaml`. +4. Every typed setting is **automatically also exposed as a TypoScript constant** under + the same dotted path — so `{$header.logo}` still works in TypoScript and Fluid layouts. + +### Three Places You Can Set a Value + +| Where | When to use | +| --- | --- | +| **TYPO3 backend → Site Management → Settings** | Editor / integrator works in the UI. Persisted to `config/sites//settings.yaml` automatically. Reviewable in git. ✅ **Default choice.** | +| `config/sites//settings.yaml` direct edit | When committing infrastructure config in a feature branch without going through the backend. Same file the UI writes. | +| Customer extension's `Configuration/Sets/Site/settings.yaml` | Default values that should ship with the project — useful for white-label installs or "this customer always wants dark mode". | + +**Precedence** (highest wins): site `settings.yaml` > customer set `settings.yaml` > upstream set `settings.yaml` > definition default. + +### Inspecting Values + +```bash +# All current effective settings for a site (claude-diagnostics) +ddev exec vendor/bin/typo3 site:settings --site= + +# A single dotted path resolved as a TypoScript constant +ddev exec vendor/bin/typo3 ts:constants --path=header.logo +``` + +## Settings From `t3bootstrap/template` + +`vendor/t3bootstrap/template/Configuration/Sets/Template/settings.definitions.yaml` — the +biggest definitions file in the stack. Categories prefixed `template.*`. + +### Meta / Favicons / Manifest + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `headercomment` | string | `T3Bootstrap Template by WapplerSystems. https://t3bootstrap.de` | HTML comment in ``. Set to `''` to hide. | +| `meta.favicon` | string | `EXT:template/Resources/Public/Images/favicon.png` | Primary favicon path | +| `meta.faviconPng16` / `meta.faviconPng32` | string | `''` | PNG favicon variants | +| `meta.appleTouchIcon57` / `72` / `114` / `144` | string | `''` | Legacy Apple touch icons | +| `meta.appleTouchIcon` | string | `''` | Modern 180×180 Apple touch icon | +| `meta.androidIcon192` / `meta.androidIcon512` | string | `''` | Chrome/Android icons | +| `meta.maskIcon` | string | `''` | Safari mask SVG | +| `meta.maskIconColor` | string | `#000000` | Safari mask color | +| `meta.webmanifest` | string | `''` | Path to `site.webmanifest` | +| `meta.themeColor` | string | `''` | `` | +| `meta.cssClass` | string | `''` | Extra class on `` | +| `meta.cssClassAria` | string | `''` | `` class for `aria-language` modes | +| `meta.referrer` | enum | `same-origin` | Referrer-Policy (8 options) | + +> The `typo3-skills:typo3-favicon-manifest` skill covers the full route-enhancer wiring for `/site.webmanifest`. + +### Header + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `header.logo` | string | `EXT:template/Resources/Public/Images/logo.svgz` | Logo file path | +| `header.logoHighContrast` | string | `''` | High-contrast variant (loaded when contrast mode active) | +| `header.layout` | enum | `4` | 0=Standard, 1=Logo right of nav, 2=Logo left above nav, 3=Centered, 4=Logo left next to nav full-height, 5=Logo left + nav+meta-links right | +| `header.searchbox` | bool | `false` | Show searchbox in header | +| `header.isSticky` | bool | `true` | Sticky header on scroll | +| `header.slogan` | string | `''` | HTML slogan text | +| `header.title` | string | `''` | HTML title text | + +### Body + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `body.backgroundMedia.slide` | bool | `false` | If page has no `background_media`, slide up the rootline for inheritance | +| `body.callToAction.enabled` | bool | `false` | Show floating CTA-bar (social links / contact icons) | +| `body.callToAction.position` | enum | `right` | `left` or `right` | +| `body.callToAction.class` | string | `d-none d-lg-flex` | Visibility utility classes | + +### Footer + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `footer.logo` | string | `EXT:template/Resources/Public/Images/logo.svgz` | Footer logo path | +| `footer.logoHighContrast` | string | `''` | High-contrast variant | +| `footer.contentPageId` | int | `0` | Page UID holding the footer content elements (typical pattern: one sysfolder for all sites) | +| `footer.copyright` | string | `''` | Copyright line | +| `footer.creditsEnabled` | bool | `true` | Show "Created with …" credits line | +| `footer.credits` | string | `''` | Override credits HTML | +| `footer.callToAction` | bool | `false` | Show CTA-bar in footer | + +### Navigation — Main + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `navigation.main.enabled` | bool | `true` | Show main nav | +| `navigation.main.entryLevel` | int | `0` | Page-tree level to start at | +| `navigation.main.levels` | int | `3` | How deep to render | +| `navigation.main.menuType` | enum | `smartmenus` | `default` / `bootstrap` / `smartmenus` / `megamenu` / `onepage` / `overlay-menu` | +| `navigation.main.megaMenuPid` | int | `0` | UID of the megamenu page (when `menuType: megamenu`) | +| `navigation.main.overlayMenuPid` | int | `0` | UID for `overlay-menu` | +| `navigation.main.includeSpacer` | bool | `false` | Render spacer pages | +| `navigation.main.showAccessProtectedPages` | bool | `false` | Show login-required pages | +| `navigation.main.includeNotInMenu` | bool | `false` | Show hidden-in-menu pages | +| `navigation.main.excludeUidList` | string | `''` | Comma-list of UIDs to skip | +| `navigation.main.showIcon` | bool | `true` | Render page-level icons | + +### Navigation — Sub / Mobile / Language / Footer / Meta / Breadcrumb / ARIA + +The same parameter shape (`entryLevel`, `levels`, `enabled`, `excludeUidList`, …) repeats +for each of these. Key per-group differences: + +| Group | Notable keys | +| --- | --- | +| `navigation.sub.*` | Defaults `entryLevel: 1`, `levels: 3`, `enabled: true`. Sidebar/sub-menu rendering. | +| `navigation.mobile.*` | `menuType` (`mmenu` / `offcanvas` / `overlay-menu`), `useAjax` (mmenu only), `showSearchbox`, `showLanguage`, `expandSubmenus` | +| `navigation.language.*` | `enabled`, `hideCurrent`, `hideUnavailable`, `layout` (`Dropdown`/`Row`), `itemLayout` (`FlagAndLabel`/`Flag`/`Label`), `showInMetaNavigation`, `showAlwaysInMainNavigation` | +| `navigation.footer.*` | `enabled`, `folderPageId` (the page holding the footer-menu pages/shortcuts) | +| `navigation.meta.*` | Meta-nav with `folderPageId`, `includeSpacer`, `showIcon`, `excludeUidList` | +| `navigation.breadcrumb.position` | enum: `0`=none, `1`=under header, `2`=under nav | +| `navigation.breadcrumb.entryLevel` | int — typically `0` | +| `navigation.aria.*` | ARIA-bar: `enabled`, `easy-language.linkType` (`none`/`page`/`language`), `easy-language.pageId`, `easy-language.languageId`, `help.pageId` | +| `navigation.overlayMenuSection` | bool — let menu float over content (full-bleed hero pages) | +| `navigation.menu.abstract.previewImageCropVariant` | string — crop variant for abstract-menu previews | + +### Search + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `search.searchPageId` | int | `0` | UID of the search-results page (carries the indexed_search plugin). **Required** if the searchbox is shown. | +| `search.indexedSearch.indexingOn` | bool | `false` | Enable indexing of cached pages | +| `search.indexedSearch.indexExternalsOn` | bool | `false` | Index linked external files | +| `search.indexedSearch.indexMetaTagsOn` | bool | `false` | Index meta-tag content | + +### Design — Layout & Color + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `design.layout` | enum | `full` | `full` (edge-to-edge) or `boxed` (centered max-width) | +| `design.color.primary` | string | `''` | Primary brand color (CSS color) | +| `design.color.secondary` | string | `''` | Secondary brand color | +| `design.color.body-color` | string | `''` | Body text color | +| `design.color.headings-color` | string | `''` | Heading color | +| `design.color.header-bg` | string | `''` | Header background | +| `design.color.header-middle-bg` | string | `''` | Header middle band (layouts 2/3) | +| `design.color.footer-bg` | string | `''` | Footer background | +| `design.color.mobile-menu-bg` | string | `''` | Off-canvas / mmenu background | +| `design.color.page-bg` | string | `''` | Page background (in `boxed` layout) | +| `design.color.dark-header` | bool | `false` | Marks the header background as dark (flips text color) | +| `design.color.main-nav-dark` | bool | `false` | Marks main nav background as dark | + +### Design — Color Mode (Dark / Contrast) + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `design.color.enable-dark-mode` | bool | `false` | Enable dark-mode rendering | +| `design.color.color-mode-type` | enum | `media-query` | `data` (toggle via `data-bs-theme`) or `media-query` (`prefers-color-scheme`) | +| `design.color.force-dark-mode` | bool | `false` | Always render dark | +| `design.color.enable-contrast-mode` | bool | `false` | Enable high-contrast variant | +| `design.color.contrast-mode-type` | enum | `media-query` | `data` or `media-query` | +| `design.color.*-dark` | string | `''` | Dark variants: `body-color-dark`, `header-bg-dark`, `footer-bg-dark`, `mobile-menu-bg-dark`, `page-bg-dark`, `navbar-dark`, `navbar-dark-toggler-border-color` | + +### Design — Fonts + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `design.font.font-family-sans-serif` | string | `''` | Sans-serif stack | +| `design.font.font-family-base` | string | `''` | Base stack | +| `design.font.headings-font-family` | string | `''` | Headings stack | +| `design.font.font-size-base` | string | `1rem` | Base font size | +| `design.font.display1-font-size` … `display6-font-size` | string | `5rem` … `2.5rem` | Display sizes | +| `design.font.h1-font-size` … `h6-font-size` | string | `2.0rem` … `1rem` | Heading sizes | + +> **When to use these vs. SCSS:** if the customer should change colors at runtime via the +> Settings UI → use `design.color.*` (rendered as CSS custom properties). If the values +> are baked-in branding → SCSS `!default` overrides (see `t3bootstrap-overrides`). + +### Icons / Assets + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `icons.uploads.prefix` | string | `t3b-icon-file-` | Icon-set prefix for upload lists | +| `icons.uploads.font-size` | string | `1.2rem` | Icon size | +| `assets.jquerycore` | string | `EXT:template/.../jquery-3.7.1.min.js` | jQuery path | +| `assets.jsBootstrap` | string | `EXT:template/.../bootstrap.min.js` | Bootstrap JS path | +| `assets.jsModernizr` | string | `''` | Modernizr script | + +### Accessibility / Expert / Other + +| Key | Type | Default | Purpose | +| --- | --- | --- | --- | +| `aria.appendNewTabExplanationToAriaLabel` | bool | `true` | Add "(opens in new tab)" to aria-label of `_blank` links | +| `adminPanelOn` | bool | `true` | Show TYPO3 admin panel (also needs FE-user-group config) | +| `liveMode` | bool | `false` | Combine + compress CSS/JS | +| `loginPid` | int | `0` | UID of the felogin page | + +## Settings From `t3bootstrap/core` (T3BCore set) + +`vendor/t3bootstrap/core/Configuration/Sets/T3BCore/settings.definitions.yaml`. Categories +prefixed `t3bcore.*`. Keys are mostly under the legacy `plugin.tx_t3bcore.settings.*` path +(both YAML and TypoScript-constant access work). + +### Bootstrap Tokens + +| Key | Type | Default | +| --- | --- | --- | +| `plugin.tx_t3bcore.settings.font-size-root` | int | `16` | +| `plugin.tx_t3bcore.settings.breakpoints.xs` … `xxl` | int | `0` / `576` / `768` / `992` / `1200` / `1400` | +| `plugin.tx_t3bcore.settings.breakpointsMax.xs` … `xxl` | number | `575.98` / `767.98` / `991.98` / `1199.98` / `1399.98` / `0` | +| `plugin.tx_t3bcore.settings.containerWidths.sm` … `xxl` | int | `540` / `720` / `960` / `1140` / `1340` | + +### Grid + +| Key | Type | Default | +| --- | --- | --- | +| `plugin.tx_t3bcore.settings.gridColumns` | int | `12` | +| `plugin.tx_t3bcore.settings.defaultGridLayout` | string | `100g:100t` | + +### Spacing System + +7-step rem scale exposed as `--t3b-space-` CSS custom properties and `t3b-pt-`, +`t3b-pb-` utility classes. Each step is editable: + +| Key | Type | Default rem | +| --- | --- | --- | +| `t3bcore.spacing.step.none.rem` | number | `0` | +| `t3bcore.spacing.step.xs.rem` | number | `0.25` | +| `t3bcore.spacing.step.s.rem` | number | `0.5` | +| `t3bcore.spacing.step.m.rem` | number | `1` | +| `t3bcore.spacing.step.l.rem` | number | `1.5` | +| `t3bcore.spacing.step.xl.rem` | number | `3` | +| `t3bcore.spacing.step.xxl.rem` | number | `6` | + +> Defaults mirror Bootstrap's `$spacers` plus a sixth step (6rem). + +### Icons + +| Key | Type | Default | Enum | +| --- | --- | --- | --- | +| `plugin.tx_t3bcore.settings.icon.rendering` | string | `svg` | `svg` / `iconfont` | +| `plugin.tx_t3bcore.settings.icon.defaultSize` | string | `md` | `sm` / `md` / `lg` | +| `plugin.tx_t3bcore.settings.icon.defaultColor` | string | `text` | (free string) | + +### Images + +| Key | Type | Default | Enum | +| --- | --- | --- | --- | +| `plugin.tx_t3bcore.settings.imageFullWidth` | int | `2200` | — | +| `plugin.tx_t3bcore.settings.cropVariantFullWidth` | string | `full` | — | +| `plugin.tx_t3bcore.settings.fullwidthClass` | string | `img-fullwidth` | — | +| `plugin.tx_t3bcore.settings.preferredImageFormat` | string | `''` | `''` / `webp` / `avif` | + +### Buttons + +| Key | Type | Default | +| --- | --- | --- | +| `plugin.tx_t3bcore.settings.button.classes` | string | `primary,success,warning,danger,info,secondary,light,dark` | + +### Privacy + +| Key | Type | Default | +| --- | --- | --- | +| `plugin.tx_t3bcore.settings.privacyPolicies.optinVideo` | bool | `false` | +| `plugin.tx_t3bcore.settings.privacyPolicies.google.defaultLang` | string | `https://policies.google.com/privacy` | +| `plugin.tx_t3bcore.settings.privacyPolicies.vimeo.defaultLang` | string | `https://vimeo.com/privacy` | + +## Special Custom Setting Types + +T3Bootstrap ships **non-standard setting types** for repeating structures. The backend +Settings editor renders them as nested list editors. + +| Type | Used by | Item shape | +| --- | --- | --- | +| `ctabaritemlist` | `callToAction.items` | `id`, `icon`, `color`, `sorting`, `modal`, `entries[]` | +| `ctabuttonlist` | `callToAction.headerButtons`, `callToAction.footerButtons` | (button list) | +| `calltoactionlist` | `callToAction.socialLinks` | `id`, `icon`, `title`, `color`, `sorting`, `links[]` | + +Pre-defined social platforms in `callToAction.socialLinks`: `facebook`, `youtube`, +`instagram`, `pinterest`, `xing`, `linkedin`, `git` (GitHub), `mastodon`, `twitter`, `x`, +`bluesky`, `tiktok`, `kununu`. Each has an `id`, prebuilt `icon` (e.g. `t3b-icon-facebook-f`), +brand `color`, and an empty `links[]` array that the editor fills with language-specific URLs. + +### Editing in `settings.yaml` + +```yaml +callToAction: + socialLinks: + - id: facebook + icon: t3b-icon-facebook-f + title: Facebook + color: '#1877f2' + sorting: 2 + links: + - languageId: 0 + link: 'https://facebook.com/customer-de' + - languageId: 1 + link: 'https://facebook.com/customer-en' + - id: linkedin + icon: t3b-icon-linkedin + title: LinkedIn + color: '#0a66c2' + sorting: 7 + links: + - languageId: 0 + link: 'https://linkedin.com/company/customer' +``` + +To **add a custom platform** not in the default list, append a fresh item with your own +`id` and matching icon — the rendering ViewHelper iterates the list as-is. + +## Settings From Add-On Sets + +### `t3bootstrap/blog` (`t3bootstrap/t3bootstrap-blog` extension) + +| Key | Type | Default | Enum | +| --- | --- | --- | --- | +| `t3bootstrap-blog.listDesign` | string | `default` | `default` / `card` | + +### `wapplersystems/filecollection-gallery` + +Categories: `filecollectionGallery.templates` / `.mobile` / `.desktop` / `.lightbox`. +Includes `filecollectiongallery.view.templateRootPath` and per-breakpoint gallery options. +Browse `vendor/wapplersystems/filecollection_gallery/Configuration/Sets/FileCollectionGallery/settings.definitions.yaml` for the full list. + +### `t3bootstrap/template` legacy `styles.content.textmedia` + +Not in `settings.definitions.yaml`; lives in the upstream `settings.yaml` of the Template set: + +```yaml +styles: + content: + textmedia: + linkWrap: + lightboxEnabled: true + width: 1200m + height: 900m +``` + +Override to disable the lightbox, or to change the click-to-zoom dimensions. + +### Other Add-Ons Without Typed Definitions + +Many add-on sets still rely on legacy `constants.typoscript`. Common ones: + +- News (`t3bootstrap/t3bootstrap-news`): `plugin.tx_news.settings.*` from EXT:news with t3bootstrap-specific list/detail layouts via the Site Set selected. +- Form (`t3bootstrap/t3bootstrap-form`): `plugin.tx_form.*` standard EXT:form keys. +- Address (`t3bootstrap/t3bootstrap-address`): list/detail PIDs. + +For these, override via TypoScript constants in the customer extension (see +`t3bootstrap-overrides` Layer 1). + +## Cookbook — Common Tasks + +Each task lists the **YAML snippet** to drop into the customer's `config/sites//settings.yaml`. + +### 1. Change brand colors (runtime themable) + +```yaml +design: + color: + primary: '#c81d25' + secondary: '#2b6cb0' + body-color: '#1a202c' + headings-color: '#1a202c' +``` + +These become CSS custom properties; no recompile needed. + +### 2. Switch header layout + make non-sticky + +```yaml +header: + layout: 2 # logo above nav + isSticky: false + searchbox: true + slogan: 'Beispiel-Slogan in HTML' +``` + +### 3. Off-canvas mobile menu with searchbox + language switcher + +```yaml +navigation: + mobile: + menuType: offcanvas + showSearchbox: true + showLanguage: true + expandSubmenus: false +``` + +### 4. Mega-menu + +```yaml +navigation: + main: + menuType: megamenu + megaMenuPid: 42 # the page that holds the megamenu structure +``` + +### 5. Language switcher always visible in main nav + +```yaml +navigation: + language: + enabled: true + showAlwaysInMainNavigation: true + showInMetaNavigation: false + layout: Row # not dropdown + itemLayout: FlagAndLabel + hideCurrent: false +``` + +### 6. Footer content from a central sysfolder + custom credits + +```yaml +footer: + contentPageId: 99 # sysfolder UID with footer CEs + copyright: '© 2026 Customer GmbH' + creditsEnabled: false # hide the "Created with …" line +``` + +### 7. Dark mode via data attribute (manual toggle) + +```yaml +design: + color: + enable-dark-mode: true + color-mode-type: data # not media-query + body-color-dark: '#e4e4e7' + page-bg-dark: '#0f172a' + header-bg-dark: '#020617' + footer-bg-dark: '#020617' + mobile-menu-bg-dark: '#020617' +``` + +A toggle button must set `data-bs-theme="dark"` on ``. + +### 8. Custom Bootstrap breakpoints (mobile-first scale) + +```yaml +plugin: + tx_t3bcore: + settings: + breakpoints: + xs: 0 + sm: 480 # tighter mobile threshold + md: 720 + lg: 980 + xl: 1280 + xxl: 1480 + breakpointsMax: + xs: 479.98 + sm: 719.98 + md: 979.98 + lg: 1279.98 + xl: 1479.98 + xxl: 0 + containerWidths: + sm: 460 + md: 700 + lg: 940 + xl: 1240 + xxl: 1420 +``` + +### 9. Custom spacing scale (bigger overall) + +```yaml +t3bcore: + spacing: + step: + xs: { rem: 0.5 } + s: { rem: 1 } + m: { rem: 2 } + l: { rem: 3 } + xl: { rem: 5 } + xxl: { rem: 8 } +``` + +### 10. Switch all images to WebP + +```yaml +plugin: + tx_t3bcore: + settings: + preferredImageFormat: webp +``` + +### 11. Enable indexed-search + +```yaml +search: + searchPageId: 7 # the page hosting indexed_search Pi1 + indexedSearch: + indexingOn: true + indexExternalsOn: false + indexMetaTagsOn: true +header: + searchbox: true +``` + +### 12. PWA / web manifest + theme color + +```yaml +meta: + webmanifest: '/site.webmanifest' + themeColor: '#005262' + appleTouchIcon: 'EXT:site_customer/Resources/Public/Icons/apple-touch-icon-180.png' + androidIcon192: 'EXT:site_customer/Resources/Public/Icons/android-chrome-192.png' + androidIcon512: 'EXT:site_customer/Resources/Public/Icons/android-chrome-512.png' + maskIcon: 'EXT:site_customer/Resources/Public/Icons/safari-pinned-tab.svg' + maskIconColor: '#005262' +``` + +> Pair with the `typo3-skills:typo3-favicon-manifest` skill for the route-enhancer side. + +### 13. Felogin + +```yaml +loginPid: 41 +``` + +### 14. Hide the t3bootstrap header comment + +```yaml +headercomment: '' +``` + +### 15. Floating social CTA-bar (left side, all breakpoints) + +```yaml +body: + callToAction: + enabled: true + position: left + class: 'd-flex' # always visible + +callToAction: + socialLinks: + - id: linkedin + icon: t3b-icon-linkedin + title: LinkedIn + color: '#0a66c2' + sorting: 1 + links: + - languageId: 0 + link: 'https://linkedin.com/company/customer' + - id: github + icon: t3b-icon-github-alt + title: GitHub + color: '#333' + sorting: 2 + links: + - languageId: 0 + link: 'https://github.com/customer' +``` + +### 16. Header CTA buttons (multi-language) + +```yaml +callToAction: + headerButtons: + - id: book-demo + label: 'Demo buchen' + class: 'btn btn-primary' + links: + - languageId: 0 + link: 't3://page?uid=110' + label: 'Demo buchen' + - languageId: 1 + link: 't3://page?uid=110&L=1' + label: 'Book a demo' +``` + +### 17. Customer-specific defaults shipped with site package + +In `local_packages//site_/Configuration/Sets/Site/settings.yaml`: + +```yaml +design: + color: + primary: '#c81d25' + secondary: '#2b6cb0' +header: + layout: 4 + isSticky: true +navigation: + main: + menuType: smartmenus + levels: 2 +footer: + creditsEnabled: false +``` + +These become the **default** when the customer set is added to the site config; the +backend Settings editor still lets the editor override per-site. + +## YAML Structure Tips + +### Dotted vs. Nested + +Both work and produce the same effective setting: + +```yaml +# Nested (recommended for readability) +header: + logo: 'EXT:site_customer/Resources/Public/Images/logo.svg' + isSticky: true + layout: 4 +``` + +```yaml +# Dotted (compact for single overrides) +header.logo: 'EXT:site_customer/Resources/Public/Images/logo.svg' +header.isSticky: true +header.layout: 4 +``` + +> The TypoScript-constant access (`{$header.logo}`) works regardless. + +### Quoting Pitfall + +A bool default of `false` set in YAML as the string `'false'` becomes truthy. Always +write booleans **unquoted**: + +```yaml +# ✅ correct +header.isSticky: false + +# ❌ wrong — string 'false' evaluates to truthy when consumed as bool +header.isSticky: 'false' +``` + +### Path Already Defined as Both Setting and Constant + +When the same path is set in `settings.yaml` AND in a `constants.typoscript`, **the +settings YAML wins** in v14. Don't define a value in both places. + +## Anti-Patterns + +| Anti-pattern | Why it's bad | Correct approach | +| --- | --- | --- | +| Editing `vendor/t3bootstrap/template/.../settings.definitions.yaml` | Wiped by composer update; also doesn't override anything (it's the definition, not the value) | Override the **value** in `config/sites//settings.yaml` | +| Putting brand colors in SCSS variables when editor needs to change them | Requires SCSS rebuild; editor can't tweak in backend | Use `design.color.*` settings (CSS custom properties) | +| Setting `searchbox: true` without `search.searchPageId` | Searchbox renders, every submit 404s | Configure `search.searchPageId` together | +| Adding a customer-specific social platform via hardcoded Fluid | Loses the multi-language link editor | Add an item to `callToAction.socialLinks` with a unique `id` + icon | +| Forking the whole `settings.definitions.yaml` "to add one field" | Maintenance burden | Add your own definition in the customer extension's `Configuration/Sets/Site/settings.definitions.yaml` — it merges with upstream | +| Mixing `header.logo = ...` in a customer constants.typoscript AND `settings.yaml` | Confusing — YAML wins, the TS line looks active but isn't | Pick one (YAML preferred) | +| Setting both `enable-dark-mode: true` and `force-dark-mode: true` without reason | Force overrides toggle UI, editor can't switch back | Only `force-dark-mode` for design previews; otherwise just `enable-dark-mode` | +| Setting `navigation.main.menuType` per language | Type is structural; switching it breaks markup | One menu type site-wide; vary only visual properties | + +## Where Things Live (Quick Reference) + +```text +# Master definitions +vendor/t3bootstrap/template/Configuration/Sets/Template/settings.definitions.yaml +vendor/t3bootstrap/core/Configuration/Sets/T3BCore/settings.definitions.yaml +vendor/t3bootstrap/t3bootstrap-blog/Configuration/Sets/T3BootstrapBlog/settings.definitions.yaml +vendor/wapplersystems/filecollection_gallery/Configuration/Sets/FileCollectionGallery/settings.definitions.yaml + +# Upstream defaults +vendor/t3bootstrap/template/Configuration/Sets/Template/settings.yaml # textmedia lightbox +vendor//Configuration/Sets//settings.yaml + +# Project overrides +config/sites//settings.yaml # what the backend writes + +# Customer extension shipping defaults +local_packages//site_/Configuration/Sets/Site/settings.yaml +``` + +## Verification Checklist + +After changing settings: + +1. **No cache flush needed for typed settings** — they're read live; but TypoScript-rendered values (most uses) still rely on the TypoScript cache. Safer: `ddev exec vendor/bin/typo3 cache:flush`. +2. Re-load the frontend and inspect: e.g. for color changes look at the rendered CSS for `--bs-primary` / `--t3b-color-primary`. +3. **claude-diagnostics**: + - `vendor/bin/typo3 ts:constants --path=header.logo` — confirm the effective value. + - `vendor/bin/typo3 site:settings --site=` — full dump. +4. For settings that affect generated CSS (breakpoints, spacing, colors when SCSS-driven): trigger the customer's SCSS rebuild (`ws_scss` watcher, or `npm run build`). +5. For settings that affect JS (mobile menu type, AOS): hard reload the frontend; the JS migrator decides at page load. + +For overrides that aren't settable (template structure, partials), switch to the +**`t3bootstrap-overrides`** skill. For the bootstrap setup, see **`t3bootstrap-site-package`**. \ No newline at end of file diff --git a/.agents/skills/t3bootstrap-site-settings/agents/openai.yaml b/.agents/skills/t3bootstrap-site-settings/agents/openai.yaml new file mode 100644 index 0000000..0c26bda --- /dev/null +++ b/.agents/skills/t3bootstrap-site-settings/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "T3Bootstrap Site Settings" + short_description: "Configure T3Bootstrap via typed Site Settings" + default_prompt: "Use $t3bootstrap-site-settings to configure a T3Bootstrap-based TYPO3 v14 project via Site Settings (`config/sites//settings.yaml` or the backend Settings editor) — the catalog covers ~200+ typed keys for header, navigation (main/sub/mobile/language/footer/meta/breadcrumb), design colors, design fonts, dark/contrast mode, body/footer, meta/favicons/manifest, search, breakpoints, container widths, spacing steps, icons, images, buttons, privacy, and the CTA-bar with social-link list editor." \ No newline at end of file diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 72fc154..b912a06 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,8 +1,8 @@ { "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "t3bootstrap-skills", - "version": "0.1.0", - "description": "Agent Skills für das T3Bootstrap-Ökosystem (TYPO3 v14): Site-Package-Setup auf den t3bootstrap/*- und wapplersystems/*-Extensions, minimal-invasive Template- und CSS-Overrides, Content-Element-Auswahl und Inhalts-Migration auf die b13/container-basierten t3bs_*-CEs (inkl. Flux-bs5 → Container-bs5 Migration). Ergänzt das typo3-skills-Plugin um T3Bootstrap-spezifische Workflows.", + "version": "0.2.0", + "description": "Agent Skills für das T3Bootstrap-Ökosystem (TYPO3 v14): Site-Package-Setup auf den t3bootstrap/*- und wapplersystems/*-Extensions, Site-Settings-Katalog (~200+ typed settings für Header, Navigation, Design, Farben, Fonts, Breakpoints, Spacing, Search, CTA-Bar etc.), minimal-invasive Template- und CSS-Overrides, Content-Element-Auswahl und Inhalts-Migration auf die b13/container-basierten t3bs_*-CEs (inkl. Flux-bs5 → Container-bs5 Migration). Ergänzt das typo3-skills-Plugin um T3Bootstrap-spezifische Workflows.", "author": { "name": "WapplerSystems", "url": "https://wappler.systems" diff --git a/README.md b/README.md index 4fc9c2f..3676ffe 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ packages and remains upgrade-friendly. | Skill | Purpose | | --- | --- | | [t3bootstrap-site-package](./.agents/skills/t3bootstrap-site-package/SKILL.md) | Set up a TYPO3 v14 project on the T3Bootstrap stack: `composer.json` repositories, the right `t3bootstrap/*` + `wapplersystems/*` packages, site sets in `config/sites//config.yaml`, when (and when not) to add a local site package, language configuration, route enhancers. | +| [t3bootstrap-site-settings](./.agents/skills/t3bootstrap-site-settings/SKILL.md) | Catalog of the ~200+ typed Site Settings exposed by `t3bootstrap/template` and `t3bootstrap/core` — header, navigation (main/sub/mobile/language/footer/meta/breadcrumb), design colors and fonts, dark/contrast mode, body/footer, meta/favicons, search, breakpoints, container widths, spacing, icons, buttons, privacy, plus the custom `ctabaritemlist` / `calltoactionlist` types for social-link editing. | | [t3bootstrap-overrides](./.agents/skills/t3bootstrap-overrides/SKILL.md) | Minimal-invasive customization: Fluid template overrides via `templateRootPaths.10` / `partialRootPaths.10` / `layoutRootPaths.10`, SCSS variable overrides with `!default`, TypoScript constants, when to override what — without forking `t3bootstrap/template`. | | [t3bootstrap-content-elements](./.agents/skills/t3bootstrap-content-elements/SKILL.md) | Catalog of the 23 `t3bs_*` content elements from `t3bootstrap/container-bs5-templates`, decision matrix for content migration (static HTML, WordPress, Joomla, older TYPO3, Flux-bs5), and the `t3bsContainerBs5MigrateFluxBs5` upgrade wizard. |