npx claudepluginhub dirnbauer/webconsulting-skillsThis skill uses the workspace's default tool permissions.
> Source: https://github.com/dirnbauer/webconsulting-skills
Guides creating Content Elements, Record Types, Page Types, and File Types using TYPO3 Content Blocks extension—the single source of truth for YAML-based content modeling in TYPO3 14.x.
Recommends and installs shadcn/ui components plus 1,338 premium ShadcnBlocks and 1,189 free components for React/Next.js + Tailwind frontends like landing pages, dashboards, heroes, and pricing sections.
Manages shadcn/ui components and projects: adding, searching, fixing, debugging, styling, and composing UI. Provides project context, docs, and examples for shadcn init or components.json files.
Share bugs, ideas, or general feedback.
Use this skill to build TYPO3 Content Blocks content elements that behave like a coherent shadcn/ui system: preset-driven tokens, shared Fluid atoms/molecules, complete field coverage, useful backend previews, semantic icons, and seed data that fills every editor field.
This skill assumes Content Blocks are the source of truth for schema and TYPO3 owns rendering. shadcn/ui is the source for theme tokens, component class contracts, data attributes, states, spacing, borders, radius, and typography.
The styling rule is strict: content elements should not hardcode colors or theme-specific visual values. Raw oklch(), hsl(), rgb(), hex colors, and fixed light/dark assumptions belong in the committed shadcn theme token source only. Templates, element CSS, backend preview CSS, generated icons, and chart scripts should consume semantic tokens or Tailwind/shadcn utility classes.
Establish the preset source.
b4hb38Fyj.body[data-shadcn-preset="b4hb38Fyj"]; do not add a runtime preset downloader or binary switcher.:root as the light-mode base and .dark as the dark-mode override, matching shadcn. Do not write content elements that only look correct in one mode.references/shadcn-preset-workflow.md before changing theme tokens or primitive class strings.Audit before editing.
php <skill>/scripts/audit-content-elements.php <repo-root> when working on a repo with ContentBlocks/ContentElements.f:split(, pipe-delimited links such as Label|https://..., legacy list fields such as features_list, specs_text, row_data, comma-delimited tier_values, and monolithic shadcn2fluid_* fixture maps.references/content-element-contract.md, especially for date/time formatting, typolink attributes, resource paths, and string-only ViewHelpers.Fix the shared component layer first.
Resources/Private/Components atoms/molecules from generated shadcn class contracts before editing hundreds of individual templates.bg-background, text-foreground, bg-card, border-border, ring-ring, text-muted-foreground, bg-primary, and text-primary-foreground.references/styling-token-contract.md before adding or changing element CSS, SVG icon colors, chart colors, shadows, overlays, or backend preview styling.Audit each content element against its contract.
references/content-element-contract.md.config.yaml, templates/frontend.html, language/labels.xlf, assets/icon.svg, CSS/JS assets, backend preview, and seed coverage.config.yaml:title as an editor-facing product name. Prefer names like Text & Media, Image Call to Action, and Logo Cloud Hero over raw slugs such as textmedia, CTA With Image, or Hero Logo Cloud.typo3-translations skill for XLIFF format choices, English/German localization, ICU MessageFormat strings, LLL: references, and localized wizard group labels.config.yaml.Style / variant fields as contracts, not decorative metadata. Keep one only when the value is passed to an existing shadcn-backed Fluid component feature (for example Button/Badge/Alert variants or TabsList default/line) or when the template has a real layout/behavior branch. Do not keep variant fields that only append unused BEM modifier classes.config.yaml, frontend templates, backend previews, and fixtures.assets/frontend.css, use an empty/comment-only marker file when the shared component layer handles all styling. Do not re-add f:asset.css includes or style rules merely to satisfy the file-presence contract.Collection fields for second-level repeatables when the installed Content Blocks version supports nested Collections; keep seed scripts recursive so child rows are created after their parent IRRE rows.Collection field an explicit table: key. Without it, Content Blocks derives the table from the identifier alone, so unrelated elements that pick the same name (rows, posts, column_items, cells, items, links...) silently share one physical table — schema migrations break, foreign_table_parent_uid drifts to the wrong type, and renames lose data. Names like <contentblock-slug>_<identifier> are safe, for example blog_teasers_posts or feature_matrix_rows. See references/content-element-contract.md "Collection Table Naming".Link fields for editor-managed URLs. Keep visible link text in a separate text field and never encode Label|https://... pairs in textareas.Add backend previews for the page/layout module.
references/backend-preview-pattern.md.templates/backend-preview.fluid.html using Content Blocks Preview layout with Content and optionally Footer.<f:section name="Header"></f:section> empty — never render a duplicate headline above the formatted card. The card itself shows the title inside d-ce-preview__title. Removing the section instead of emptying it triggers TYPO3's InvalidSectionException fallback to the standard renderer, which re-adds the duplicate.d-ce-preview__meta, surface the editor-facing element name, the Content Block identifier, the record uid, and the page pid as small pills. Use <f:translate key="LLL:EXT:desiderio/Resources/Private/Language/labels.xlf:preview.uid"/> and :preview.page — never hardcode the labels.Create or refresh icons.
references/icon-pattern.md.assets/icon.svg.currentColor primary, var(--icon-color-accent,currentColor) accent, readable in light and dark.gpt-image-*, first verify the currently available OpenAI image model and API credentials. Use image generation for metaphor boards or visual direction; redraw the final asset as clean, editable SVG because TYPO3 backend icons need tiny, token-colored vectors.Update seed scripts.
{"label": "Docs", "link": "https://example.com/docs"} or link_1_label plus link_1. Do not generate pipe-delimited link strings.Select values against the current config.yaml items before insertion. Stale fixture values from removed style variants should fall back to the configured default instead of seeding inert editor choices.ContentBlocks/ContentElements/<element>/fixture.json file. Do not create or restore monolithic shadcn2fluid_* fixture mappings.Verify and commit in reviewable slices.
This is the single most damaging mistake when authoring Content Blocks. Read this before creating any type: Collection field.
Every type: Collection field generates a separate physical database table. Without an explicit table: key, Content Blocks falls back to using the bare identifier as the table name. That breaks production in three escalating ways:
rows, groups, order, range, system, values, user are MySQL/MariaDB reserved words. Doctrine quotes at runtime so the table works inside TYPO3, but mysqldump, mysqlcheck, ad-hoc CLI queries, schema-diff tools, and IDE introspection all stumble on the unquoted name.posts, column_items, rows, cells, items, links, features, tabs, members, slides, stats, tiers, partners, clients, reviews, routes, metrics, specs, jobs, awards...), Content Blocks merges their schemas into one shared table. The shared table becomes the union of every consuming element's columns, schema migrations get confused, and renaming one block later requires a parent-aware data migration to split records back apart.foreign_table_parent_uid type drift. Older Content Blocks versions created the parent reference column as varchar(255) DEFAULT '' NOT NULL. Newer TCA-driven schema migration wants int unsigned DEFAULT 0 NOT NULL. The migration fails with Truncated incorrect INTEGER value: '' because existing rows hold empty-string values that strict-mode MySQL refuses to coerce. Recovery requires UPDATE <table> SET foreign_table_parent_uid = 0 WHERE foreign_table_parent_uid = '' before the ALTER. Adding table: from the start avoids the legacy column path entirely on fresh tables.type: Collection field without table:.rows, posts, column_items, cells, items, links, features, tabs, members, slides, stats, tiers, groups, users, range, order, system, values as a table: value — they collide with other extensions or with reserved SQL keywords.table: after editor data exists without a parent-aware data migration: dropping a shared table loses every block's content, and renaming without migration orphans the rows.type: Collection field an explicit table: directive in the YAML.<contentblock-slug-as-snake_case>_<collection-identifier>, for example blog_teasers_posts, feature_matrix_rows, footer_mega_column_items, pricing_plan_features, data_table_cells.pricing_plan_features for a features Collection nested inside plans).table: to every Collection in the same pass — schema migrations regress as soon as one block falls through.# Every Collection field that lacks an explicit table: directive (should print nothing).
rg -nP '^\s*type: Collection\s*$' --no-heading -A1 ContentBlocks/ContentElements \
| rg -B1 -v 'table:'
# Bare table names that match MySQL/MariaDB reserved words.
rg -n '^\s+table:\s+(rows|groups|range|order|system|values|user|cross|dense_rank|window)\s*$' \
ContentBlocks/ContentElements
# Bare unprefixed names — risky for cross-extension collision even if not reserved.
rg -nP '^\s+table:\s+[a-z][a-z0-9_]*\s*$' ContentBlocks/ContentElements \
| rg -v '_[a-z]' # everything kept after this filter has no underscore — review by hand.
The full reasoning, migration playbook for an already-shared table, and additional examples live in references/content-element-contract.md "Collection Table Naming".
shadcn2fluid; allowed mentions are limited to package conflicts, migration notes, and tests/docs that explicitly prevent the old package or fixture map from returning.type: Collection field has an explicit table: key with a <contentblock-slug>_<identifier> value. No bare names, no reserved SQL words. Audit grep in "Critical Rules — Collection Table Naming" should print nothing.references/shadcn-preset-workflow.md: scratch-app preset workflow and token expectations.references/styling-token-contract.md: no-hardcoded-style rules, light/dark behavior, and verification scans.references/content-element-contract.md: field/template/label/seed audit contract.references/backend-preview-pattern.md: Content Blocks backend preview pattern.references/icon-pattern.md: TYPO3 backend icon rules.../typo3-translations/SKILL.md: XLIFF, localization, ICU MessageFormat, and LLL: label rules.scripts/audit-content-elements.php <repo-root>: JSON audit for Content Blocks directories.