Token导航 LogoToken导航

Agent Skill · 前端设计

typo3-content-blocks(typo3 内容块)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

typo3-content-blocks 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 2,666。

总安装 2,007周安装 82GitHub Stars 26下载 649核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:typo3-content-blocks(typo3 内容块)
来源仓库:https://github.com/dirnbauer/webconsulting-skills
仓库路径:skills/typo3-content-blocks
安装命令:
npx skills add https://github.com/dirnbauer/webconsulting-skills --skill typo3-content-blocks
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/dirnbauer/webconsulting-skills --skill typo3-content-blocks

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

辅助前端页面与组件的开发维护,支持内容区块结构生成。可用于审查 React、Vue、CSS 等相关代码实现。需结合项目现有设计系统和构建方式使用。涉及页面改动时应配合本地预览确认视觉效果。typo3-content-blocks 属于前端设计类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/typo3-content-blocks

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/dirnbauer/webconsulting-skills --skill typo3-c…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

typo3-content-blocks 怎么安装?

在终端执行 npx skills add https://github.com/dirnbauer/webconsulting-skills --skill typo3-content-blo…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

typo3-content-blocks 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

typo3-content-blocks 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

typo3-content-blocks 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

typo3-content-blocks 用的人多吗?

公开数据是累计安装 2,007 次,近一周安装 82 次,下载 649 次,GitHub 26 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

typo3-content-blocks 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
typo3-content-blocks

typo3 内容块 · 本页

2,00726需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

TYPO3 Content Blocks Development

Compatibility: This skill targets TYPO3 v14.x with Content Blocks 2.x. Always match the Packagist friendsoftypo3/content-blocks constraint to your Core version. For Content Blocks 1.x on TYPO3 v13, upstream requires TYPO3 ≥ 13.4 (typo3/cms-core: ^13.4) — confirm on Packagist. Examples use TYPO3 v14 APIs and CB 2.x; adjust composer.json if upstream constraints differ.
TYPO3 API First: Always use TYPO3's built-in APIs, core features, and established conventions before creating custom implementations. Do not reinvent what TYPO3 already provides. Always verify that the APIs and methods you use exist and are not deprecated in TYPO3 v14 by checking the official TYPO3 documentation.
Migration Coverage: Content Blocks migration and cross-skill handoff guidance are documented directly in this skill and its local add-ons.

1. The Single Source of Truth Principle

Content Blocks is the modern approach to creating custom content types in TYPO3. It eliminates redundancy by providing a single YAML configuration that generates:

  • TCA (Table Configuration Array)
  • Database schema (SQL)
  • TypoScript rendering
  • Backend forms and previews
  • Labels and translations

Why Content Blocks?

Traditional ApproachContent Blocks Approach
Multiple TCA filesOne config.yaml
Manual SQL definitionsAuto-generated schema
Separate TypoScriptAuto-registered rendering
Scattered translationsSingle labels.xlf
Complex setupSimple folder structure

2. Installation

# Install via Composer (DDEV recommended)
ddev composer require friendsoftypo3/content-blocks

# After installation, clear caches
ddev typo3 cache:flush
Version constraint: Content Blocks 1.x requires TYPO3 ≥ 13.4 (typo3/cms-core: ^13.4 in the package). TYPO3 13.1–13.3 do not satisfy that Composer constraint.

Security Configuration (Classic Mode)

For non-composer installations, deny web access to ContentBlocks folder:

# .htaccess addition
RewriteRule (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|ContentBlocks|Resources/Private|Tests?|Documentation|docs?)/ - [F]

3. Content Types Overview

Content Blocks supports four content types:

TypeFolderTableUse Case
ContentElementsContentBlocks/ContentElements/tt_contentFrontend content (hero, accordion, CTA)
RecordTypesContentBlocks/RecordTypes/Custom/existingStructured records (news, products, team)
PageTypesContentBlocks/PageTypes/pagesCustom page types (blog, landing page)
FileTypesContentBlocks/FileTypes/sys_file_referenceExtended file references (photographer, copyright)

4. Folder Structure

EXT:my_sitepackage/
└── ContentBlocks/
    ├── ContentElements/
    │   └── my-hero/
    │       ├── assets/
    │       │   └── icon.svg
    │       ├── language/
    │       │   └── labels.xlf
    │       ├── templates/
    │       │   ├── backend-preview.fluid.html
    │       │   ├── frontend.fluid.html
    │       │   └── partials/
    │       └── config.yaml
    ├── RecordTypes/
    │   └── my-record/
    │       ├── assets/
    │       │   └── icon.svg
    │       ├── language/
    │       │   └── labels.xlf
    │       └── config.yaml
    ├── PageTypes/
    │   └── blog-article/
    │       ├── assets/
    │       │   ├── icon.svg
    │       │   ├── icon-hide-in-menu.svg
    │       │   └── icon-root.svg
    │       ├── language/
    │       │   └── labels.xlf
    │       ├── templates/
    │       │   └── backend-preview.fluid.html
    │       └── config.yaml
    └── FileTypes/
        └── image-extended/
            ├── language/
            │   └── labels.xlf
            └── config.yaml

5. Creating Content Elements

Kickstart Command (Recommended)

# Interactive mode
ddev typo3 make:content-block

# One-liner
ddev typo3 make:content-block \
  --content-type="content-element" \
  --vendor="myvendor" \
  --name="hero-banner" \
  --title="Hero Banner" \
  --extension="my_sitepackage"

# After creation, update database
ddev typo3 cache:flush -g system
ddev typo3 extension:setup --extension=my_sitepackage

Predefined Basics (content elements)

List under basics: to pull in Core field groups: TYPO3/Header, TYPO3/Appearance, TYPO3/Links, TYPO3/Categories. See the Content Blocks basics reference.

Minimal Content Element

# EXT:my_sitepackage/ContentBlocks/ContentElements/hero-banner/config.yaml
name: myvendor/hero-banner
fields:
  - identifier: header
    useExistingField: true
  - identifier: bodytext
    useExistingField: true

Full Content Element Example

# EXT:my_sitepackage/ContentBlocks/ContentElements/hero-banner/config.yaml
name: myvendor/hero-banner
group: default
description: "A full-width hero banner with image and CTA"
prefixFields: true
prefixType: full
basics:
  - TYPO3/Appearance
  - TYPO3/Links
fields:
  - identifier: header
    useExistingField: true
  - identifier: subheadline
    type: Text
    label: Subheadline
  - identifier: hero_image
    type: File
    minitems: 1
    maxitems: 1
    allowed: common-image-types
  - identifier: cta_link
    type: Link
    label: Call to Action Link
  - identifier: cta_text
    type: Text
    label: Button Text

Frontend Template

<!-- templates/frontend.fluid.html -->
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
      xmlns:cb="http://typo3.org/ns/TYPO3/CMS/ContentBlocks/ViewHelpers"
      data-namespace-typo3-fluid="true">

<f:asset.css identifier="hero-banner-css" href="{cb:assetPath()}/frontend.css"/>

<section class="hero-banner">
    <f:if condition="{data.hero_image}">
        <f:for each="{data.hero_image}" as="image">
            <f:image image="{image}" alt="{data.header}" class="hero-image"/>
        </f:for>
    </f:if>

    <div class="hero-content">
        <h1>{data.header}</h1>
        <f:if condition="{data.subheadline}">
            <p class="subheadline">{data.subheadline}</p>
        </f:if>

        <f:if condition="{data.cta_link}">
            <f:link.typolink parameter="{data.cta_link}" class="btn btn-primary">
                {data.cta_text -> f:or(default: 'Learn more')}
            </f:link.typolink>
        </f:if>
    </div>
</section>
</html>

Backend Preview Template

<!-- templates/backend-preview.fluid.html -->
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
      xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
      data-namespace-typo3-fluid="true">

<div class="content-block-preview">
    <strong>{data.header}</strong>
    <f:if condition="{data.subheadline}">
        <br/><em>{data.subheadline}</em>
    </f:if>
    <f:if condition="{data.hero_image}">
        <f:for each="{data.hero_image}" as="image">
            <be:thumbnail image="{image}" width="100" height="100"/>
        </f:for>
    </f:if>
</div>
</html>

6. Creating Record Types (Custom Tables)

Record Types create custom database tables for structured data like teams, products, events, etc.

Extbase-Compatible Table Naming

IMPORTANT: For Extbase compatibility, use the tx_extensionkey_domain_model_* naming convention:

# ✅ CORRECT - Extbase compatible table name
name: myvendor/team-member
table: tx_mysitepackage_domain_model_teammember
labelField: name
fields:
  - identifier: name
    type: Text
  - identifier: position
    type: Text
  - identifier: email
    type: Email
  - identifier: photo
    type: File
    allowed: common-image-types
    maxitems: 1
# ❌ WRONG - Short table names don't work with Extbase
name: myvendor/team-member
table: team_member  # Won't work with Extbase!

Minimal Record Type

# EXT:my_sitepackage/ContentBlocks/RecordTypes/team-member/config.yaml
name: myvendor/team-member
table: tx_mysitepackage_domain_model_teammember
labelField: name
fields:
  - identifier: name
    type: Text

Full Record Type Example

# EXT:my_sitepackage/ContentBlocks/RecordTypes/team-member/config.yaml
name: myvendor/team-member
table: tx_mysitepackage_domain_model_teammember
labelField: name
fallbackLabelFields:
  - email
languageAware: true
workspaceAware: true
sortable: true
softDelete: true
trackCreationDate: true
trackUpdateDate: true
internalDescription: true
restriction:
  disabled: true
  startTime: true
  endTime: true
  userGroup: true  # fe_group visibility fields when applicable
security:
  ignorePageTypeRestriction: true  # Allow on normal pages
fields:
  - identifier: name
    type: Text
    required: true
  - identifier: position
    type: Text
  - identifier: email
    type: Email
  - identifier: phone
    type: Text
  - identifier: bio
    type: Textarea
    enableRichtext: true
  - identifier: photo
    type: File
    allowed: common-image-types
    maxitems: 1
  - identifier: social_links
    type: Collection
    labelField: platform
    fields:
      - identifier: platform
        type: Select
        renderType: selectSingle
        items:
          - label: LinkedIn
            value: linkedin
          - label: Twitter/X
            value: twitter
          - label: GitHub
            value: github
      - identifier: url
        type: Link

Record Type options (reference)

Content Blocks exposes many optional root keys on record types — always confirm names against the current Record Types YAML reference. Commonly used flags include:

OptionRole
editLockingEditor locking behaviour
sortField / sortableManual sorting (sorting column)
rootLevelTypeAllow records at PID 0
readOnlyRead-only in FormEngine
adminOnlyVisible to admins only
hideAtCopy / appendLabelAtCopyCopy behaviour
groupBackend selector grouping

Multi-Type Records (Single Table Inheritance)

Create multiple types for one table:

# EXT:my_sitepackage/ContentBlocks/RecordTypes/person-employee/config.yaml
name: myvendor/person-employee
table: tx_mysitepackage_domain_model_person
typeField: person_type
typeName: employee
priority: 0  # Integer ordering; higher values load first (higher priority)
labelField: name
languageAware: false
workspaceAware: false
fields:
  - identifier: name
    type: Text
  - identifier: department
    type: Text
# EXT:my_sitepackage/ContentBlocks/RecordTypes/person-contractor/config.yaml
name: myvendor/person-contractor
table: tx_mysitepackage_domain_model_person
typeName: contractor
fields:
  - identifier: name
    type: Text
  - identifier: company
    type: Text
  - identifier: contract_end
    type: DateTime

Record Types as Collection Children

Define a record that can be used in IRRE collections:

# EXT:my_sitepackage/ContentBlocks/RecordTypes/slide/config.yaml
name: myvendor/slide
table: tx_mysitepackage_domain_model_slide
labelField: title
fields:
  - identifier: title
    type: Text
  - identifier: image
    type: File
    maxitems: 1
  - identifier: link
    type: Link
# EXT:my_sitepackage/ContentBlocks/ContentElements/slider/config.yaml
name: myvendor/slider
fields:
  - identifier: slides
    type: Collection
    foreign_table: tx_mysitepackage_domain_model_slide
    shareAcrossTables: true
    shareAcrossFields: true
    minitems: 1

7. Creating Page Types (Custom doktypes)

Page Types extend the pages table with custom page types – ideal for blog articles, landing pages, news pages, or other page variants with special properties.

When to Use Page Types

Use CaseExample
Structured page propertiesBlog with author, teaser image, publish date
Plugin integrationNews lists, event calendars reading page properties
Different page behaviorLanding pages without navigation
SEO-specific fieldsCustom meta fields per page type

Minimal Page Type

# EXT:my_sitepackage/ContentBlocks/PageTypes/blog-article/config.yaml
name: myvendor/blog-article
typeName: 1705234567
fields:
  - identifier: author_name
    type: Text

Full Page Type Example

# EXT:my_sitepackage/ContentBlocks/PageTypes/blog-article/config.yaml
name: myvendor/blog-article
typeName: 1705234567   # Unix timestamp (unique identifier)
group: default         # Options: default, link, special
fields:
  - identifier: author_name
    type: Text
    label: Author
    required: true
  - identifier: teaser_text
    type: Textarea
    label: Teaser
  - identifier: hero_image
    type: File
    allowed: common-image-types
    maxitems: 1
  - identifier: publish_date
    type: DateTime
    label: Publish Date
  - identifier: reading_time
    type: Number
    label: Reading Time (minutes)

Page Type Options

OptionTypeRequiredDescription
typeNameinteger✓Unique doktype number (use Unix timestamp)
groupstringGroup in selector: default, link, special
allowedRecordTypesarrayRecord types allowed on this doktype (default includes pages, sys_category, sys_file_reference, sys_file_collection; * wildcard possible — see official Page Types API)

Reserved typeName values: 199, 254 (cannot be used)

Icons for Page States

Page Types support state-specific icons. Add these to your assets folder:

ContentBlocks/PageTypes/blog-article/
├── assets/
│   ├── icon.svg              # Default icon
│   ├── icon-hide-in-menu.svg # Hidden in menu state
│   └── icon-root.svg         # Site root state
└── config.yaml

Backend Preview

Create a backend-preview.fluid.html to preview custom page properties:

<!-- templates/backend-preview.fluid.html -->
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
      xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
      data-namespace-typo3-fluid="true">

<div class="card card-size-medium">
    <div class="card-body">
        <be:link.editRecord uid="{data.uid}" table="{data.mainType}" fields="author_name">
            <strong>Author:</strong> {data.author_name}
        </be:link.editRecord>
        <f:if condition="{data.publish_date}">
            <br/><small>Published: <f:format.date format="d.m.Y">{data.publish_date}</f:format.date></small>
        </f:if>
    </div>
</div>
</html>

Frontend Integration

Page Types have no automatic frontend rendering. Add the ContentBlocksDataProcessor to your TypoScript:

# Configuration/TypoScript/setup.typoscript
page = PAGE
page {
    10 = FLUIDTEMPLATE
    10 {
        templateName = Default
        templateRootPaths.10 = EXT:my_sitepackage/Resources/Private/Templates/

        dataProcessing {
            # Process Content Blocks page data
            1 = content-blocks
        }
    }
}

Then access fields in your Fluid template:

<!-- Resources/Private/Templates/Default.html -->
<f:if condition="{data.author_name}">
    <p class="author">By {data.author_name}</p>
</f:if>

<f:if condition="{data.hero_image}">
    <f:for each="{data.hero_image}" as="image">
        <f:image image="{image}" class="hero-image"/>
    </f:for>
</f:if>

Remove from Page Tree Drag Area

To hide your page type from the "Create new page" drag area:

# Configuration/user.tsconfig
options {
    pageTree {
        doktypesToShowInNewPageDragArea := removeFromList(1705234567)
    }
}

8. Creating File Types (Extended Metadata)

New in version 1.2

File Types extend the sys_file_reference table with custom fields – perfect for photographer credits, copyright notices, or additional reference-level options.

Available File Type Names

typeNameFile Types
imageJPEG, PNG, GIF, WebP, SVG
videoMP4, WebM, OGG
audioMP3, WAV, OGG
textTXT, PDF, Markdown
applicationZIP, Office formats

Minimal File Type

# EXT:my_sitepackage/ContentBlocks/FileTypes/image-extended/config.yaml
name: myvendor/image-extended
typeName: image
fields:
  - identifier: photographer
    type: Text
    label: Photographer

Full File Type Example

# EXT:my_sitepackage/ContentBlocks/FileTypes/image-extended/config.yaml
name: myvendor/image-extended
typeName: image
prefixFields: false  # Keep original column names
fields:
  - identifier: image_overlay_palette
    type: Palette
    label: 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette'
    fields:
      # Reuse existing TYPO3 core fields
      - identifier: alternative
        useExistingField: true
      - identifier: description
        useExistingField: true
      - type: Linebreak
      - identifier: link
        useExistingField: true
      - identifier: title
        useExistingField: true
      - type: Linebreak
      # Custom fields
      - identifier: photographer
        type: Text
        label: Photographer
      - identifier: copyright
        type: Text
        label: Copyright Notice
      - identifier: source_url
        type: Link
        label: Source URL
      - type: Linebreak
      - identifier: crop
        useExistingField: true

File Type Options

OptionTypeRequiredDescription
typeNamestring✓One of: text, image, audio, video, application
prefixFieldsbooleanWhether to prefix field identifiers with the Content Block name (often false for File Types to keep shared field names)

Use Cases for File Types

Use CaseFields to Add
Photography agencyphotographer, copyright, license_type, expiry_date
Video platformdirector, duration, transcript, subtitles
Document managementdocument_version, author, confidentiality
E-commerceproduct_sku, variant_color, variant_size

Accessing File Type Fields

In Fluid templates, access custom metadata through FAL references:

<f:for each="{data.images}" as="image">
    <figure>
        <f:image image="{image}" alt="{image.alternative}"/>
        <f:if condition="{image.properties.photographer}">
            <figcaption>
                Photo: {image.properties.photographer}
                <f:if condition="{image.properties.copyright}">
                    | © {image.properties.copyright}
                </f:if>
            </figcaption>
        </f:if>
    </figure>
</f:for>

9. Field Types Reference

Simple Fields

TypeDescriptionExample
TextSingle line texttype: Text
TextareaMulti-line texttype: Textarea
EmailEmail addresstype: Email
LinkLink/URLtype: Link
NumberInteger/Floattype: Number (+ format: integer or format: decimal as needed; legacy YAML sometimes used a non-existent Integer type — use Number)
DateTimeDate and/or timetype: DateTime
ColorColor pickertype: Color
CheckboxBoolean checkboxtype: Checkbox
RadioRadio buttonstype: Radio
SlugURL slugtype: Slug
PasswordPassword fieldtype: Password
BasicShared “basic” field helpertype: Basic
CountryCountry selection (aligns with TCA country where supported)type: Country
PassVirtual field, not visible in the backend; used for storing data handled by extension logictype: Pass
SelectNumberSelect with numeric valuestype: SelectNumber
UuidUUID stringtype: Uuid

Relational Fields

TypeDescriptionExample
FileFile references (FAL)type: File
RelationRecord relationstype: Relation
SelectDropdown selectiontype: Select
CategorySystem categoriestype: Category
CollectionInline records (IRRE)type: Collection
FolderFolder referencetype: Folder
LanguageLanguage selectortype: Language

Structural Fields

TypeDescriptionExample
TabTab separatortype: Tab
PaletteGroup fieldstype: Palette
LinebreakLine break in palettetype: Linebreak
FlexFormFlexForm containertype: FlexForm
JsonJSON fieldtype: Json

Common Field Options

fields:
  - identifier: my_field
    type: Text
    label: My Field Label           # Static label (or use labels.xlf)
    description: Help text          # Field description
    required: true                  # Make field required
    default: "Default value"        # Default value
    placeholder: "Enter text..."    # Placeholder text
    prefixField: false              # Disable prefixing for this field
    useExistingField: true          # Reuse existing TCA field
    displayCond: 'FIELD:other:=:1'  # Conditional display
    onChange: reload                # Reload form on change

File Field Example

TCA-only options: Keys like appearance / behaviour belong in generated TCA, not always in Content Blocks YAML. If the schema rejects them, add a TCA override for that field after generation (see Content Blocks docs on extending TCA).
fields:
  - identifier: gallery_images
    type: File
    allowed: common-image-types
    minitems: 1
    maxitems: 10

Select Field Example

fields:
  - identifier: layout
    type: Select
    renderType: selectSingle
    default: default
    items:
      - label: Default Layout
        value: default
      - label: Wide Layout
        value: wide
      - label: Compact Layout
        value: compact

Collection Field Example (Inline IRRE)

Important: Collections cannot be nested — a Collection field must NOT contain another Collection as a sub-field. See "Common Pitfalls" section for details.

fields:
  - identifier: accordion_items
    type: Collection
    labelField: title
    minitems: 1
    maxitems: 20
    appearance:
      collapseAll: true
      levelLinksPosition: both
    fields:
      - identifier: title
        type: Text
        required: true
      - identifier: content
        type: Textarea
        enableRichtext: true
      - identifier: is_open
        type: Checkbox
        label: Initially Open

10. Field Prefixing

Content Blocks automatically prefixes field identifiers to avoid collisions.

Prefixing Types

# Full prefix (default): myvendor_myblock_fieldname
name: myvendor/my-block
prefixFields: true
prefixType: full

# Vendor prefix only: myvendor_fieldname
name: myvendor/my-block
prefixFields: true
prefixType: vendor

# Custom vendor prefix: tx_custom_fieldname
name: myvendor/my-block
prefixFields: true
prefixType: vendor
vendorPrefix: tx_custom

# No prefix (use with caution!)
name: myvendor/my-block
prefixFields: false

Disable Prefixing per Field

fields:
  - identifier: my_custom_field
    type: Text
    prefixField: false  # This field won't be prefixed

11. Templating Features

Accessing Data in Fluid

<!-- Basic field access -->
{data.header}
{data.my_field}

<!-- Record metadata -->
{data.uid}
{data.pid}
{data.languageId}
{data.mainType}      <!-- Table name: tt_content -->
{data.recordType}    <!-- CType: myvendor_heroblock -->
{data.fullType}      <!-- tt_content.myvendor_heroblock -->

<!-- Raw database values -->
{data.rawRecord.some_field}

<!-- System properties -->
{data.systemProperties.createdAt}
{data.systemProperties.lastUpdatedAt}
{data.systemProperties.sorting}
{data.systemProperties.disabled}

<!-- Language info -->
{data.languageInfo.translationParent}
{data.languageInfo.translationSource}

<!-- Relations are auto-resolved! -->
<f:for each="{data.gallery_images}" as="image">
    <f:image image="{image}" width="400"/>
</f:for>

<!-- Nested collections -->
<f:for each="{data.accordion_items}" as="item">
    <h3>{item.title}</h3>
    <f:format.html>{item.content}</f:format.html>
</f:for>

Asset ViewHelpers

<!-- Include CSS from assets folder -->
<f:asset.css identifier="my-block-css" href="{cb:assetPath()}/frontend.css"/>

<!-- Include JS from assets folder -->
<f:asset.script identifier="my-block-js" src="{cb:assetPath()}/frontend.js"/>

<!-- Cross-block asset reference -->
<f:asset.css identifier="shared-css" href="{cb:assetPath(name: 'vendor/other-block')}/shared.css"/>

Translation ViewHelper

<!-- Access labels.xlf translations -->
<f:translate key="{cb:languagePath()}:my_label"/>

<!-- Cross-block translation -->
<f:translate key="{cb:languagePath(name: 'vendor/other-block')}:shared_label"/>

12. Extending Existing Tables

Add custom types to existing tables (like tx_news):

# EXT:my_sitepackage/ContentBlocks/RecordTypes/custom-news/config.yaml
name: myvendor/custom-news
table: tx_news_domain_model_news
typeName: custom_news
fields:
  - identifier: title
    useExistingField: true
  - identifier: custom_field
    type: Text

13. Workflow with DDEV

Standard Development Workflow

# 1. Create new Content Block
ddev typo3 make:content-block

# 2. Clear system caches
ddev typo3 cache:flush -g system

# 3. Update database schema
ddev typo3 extension:setup --extension=my_sitepackage

# Alternative: Use Database Analyzer in TYPO3 Backend
# Admin Tools > Maintenance > Analyze Database Structure

Using webprofil/make Extension

If webprofil/make is installed:

# Create Content Block with webprofil/make
ddev make:content_blocks

# Clear caches and update database (prefer Core CLI)
ddev typo3 cache:flush
ddev typo3 extension:setup --extension=my_sitepackage
# `database:updateschema` exists only with helhum/typo3-console — do not assume it in plain Core projects

Integration with Extbase

After creating Record Types with proper table names, generate Extbase models:

# If typo3:make:model is available
ddev typo3 make:model --extension=my_sitepackage

# Generate repository
ddev typo3 make:repository --extension=my_sitepackage

14. Defaults Configuration

Create a content-blocks.yaml in project root for default settings:

# content-blocks.yaml
vendor: myvendor
extension: my_sitepackage
content-type: content-element
skeleton-path: content-blocks-skeleton

config:
  content-element:
    basics:
      - TYPO3/Header
      - TYPO3/Appearance
      - TYPO3/Links
      - TYPO3/Categories
    group: default
    prefixFields: true
    prefixType: full

  record-type:
    prefixFields: true
    prefixType: vendor
    vendorPrefix: tx_mysitepackage

15. Best Practices

DO ✅

  1. Use Extbase-compatible table names for Record Types: table: tx_myextension_domain_model_myrecord
  2. Reuse existing fields when possible: - identifier: header useExistingField: true
  3. Group related fields with Tabs and Palettes: - identifier: settings_tab type: Tab label: Settings
  4. Use meaningful identifiers (snake_case): - identifier: hero_background_image
  5. Clear caches after changes: ddev typo3 cache:flush -g system ddev typo3 extension:setup --extension=my_sitepackage
  6. Use labels.xlf for all user-facing labels

DON'T ❌

  1. Don't use raw SQL - Content Blocks generates schema automatically
  2. Don't duplicate TCA - Config.yaml is the single source of truth
  3. Don't use short table names for Extbase integration: # ❌ Wrong table: team_member # ✅ Correct table: tx_mysitepackage_domain_model_teammember
  4. Don't use dashes in identifiers: # ❌ Wrong identifier: hero-image # ✅ Correct identifier: hero_image
  5. Don't forget shareAcross options when using foreign_table in multiple places

16. Troubleshooting

Content Block Not Appearing

# Clear all caches
ddev typo3 cache:flush

# Rebuild class loading
ddev composer dump-autoload

# Check extension setup
ddev typo3 extension:setup --extension=my_sitepackage

Database Errors

# Update database schema (Core)
ddev typo3 extension:setup --extension=my_sitepackage
# With typo3-console only: ddev typo3 database:updateschema

# Or use Compare Tool
# Admin Tools > Maintenance > Analyze Database Structure

Field Not Saving

  • Check field identifier is unique (use prefixing)
  • Verify field type is correct
  • Check for typos in config.yaml
  • Ensure labels.xlf has matching keys

17. Version constraints

Use TYPO3 v14.1+ with Content Blocks 2.x (friendsoftypo3/content-blocks currently requires typo3/cms-core: ^14.1 — confirm on Packagist).

// ext_emconf.php — TYPO3 v14.1+ + Content Blocks 2.x
'depends' => [
    'typo3' => '14.1.0-14.99.99',
    'content_blocks' => '2.0.0-2.99.99',
],

Related Skills

For migration between classic TYPO3 extensions and Content Blocks, see the dedicated migration skill:

- TCA → Content Blocks field mapping - Content Blocks → TCA reverse mapping - Data migration scripts - Step-by-step examples - Checklists for both directions


18. Package Management for v14 Compatibility

If extensions don't support TYPO3 v14 yet, fork and update:

# Add private fork as VCS repository in composer.json
# Then update extension for v14 using typo3-rector and typo3-update skills

Required private forks for webconsulting stack:

  • webprofil/wp-t3monitoring-client (^13 → ^14)
  • webprofil/deployer (^13 → ^14)
  • webprofil/crawler (^1.0 → compatible with v14)
  • webprofil/make (^1.1 → compatible with v14)

References

v14-Only Changes

The following changes affect Content Blocks development on TYPO3 v14 only.

New TCA Type country [v14 only]

TYPO3 v14 introduces a native country TCA type (#99911). Content Blocks can use this for country selection fields. Check Content Blocks YAML documentation for support of this field type.

TCA itemsProcessors [v14 only]

New itemsProcessors option (#107889) enables dynamic item generation for select fields. Content Blocks may expose this via YAML configuration for advanced select field customization.

Type-Specific TCA Properties [v14 only]

  • Type-specific ctrl properties (#108027) — title, label, and other ctrl properties can now be overridden per record type in the types section.
  • Type-specific TCA defaults (#107281) — default values can differ per record type.

Fluid 5.0 Strict Types [v14 only]

Content Block Fluid templates must comply with Fluid 5.0 strict typing:

  • ViewHelper arguments are strictly typed. Ensure correct types (int vs string).
  • No underscore-prefixed variable names (_myVar).
  • CDATA sections are preserved (not stripped).

Content Element Restrictions per Column [v14.1+ only]

TYPO3 v14.1 integrates content_defender functionality into Core. Backend layouts can now restrict which Content Elements (including Content Blocks) are allowed per colPos without third-party extensions.


Common Pitfalls & Hard-Won Lessons

These rules come from real debugging sessions. Violating them causes errors that are difficult to trace.

1. No Nested Collections (CRITICAL)

Content Blocks does NOT support a Collection inside another Collection. This causes a fatal Undefined array key "typeName" error in ProcessingInput.php during TYPO3 bootstrap — preventing composer install, cache:flush, and all CLI commands.

# BROKEN — nested Collection crashes content-blocks
fields:
  - identifier: groups
    type: Collection
    fields:
      - identifier: title
        type: Text
      - identifier: items        # <-- Collection inside Collection = FATAL
        type: Collection
        fields:
          - identifier: label
            type: Text
          - identifier: link
            type: Link

# FIXED — flatten the inner Collection to a Textarea
fields:
  - identifier: groups
    type: Collection
    fields:
      - identifier: title
        type: Text
      - identifier: items         # <-- Textarea with one entry per line
        type: Textarea
        label: Items (one per line)
        rows: 5

The error message (Undefined array key "typeName" on table pages, type record-type) is misleading — it does not point to the actual nested Collection that causes it. If you see this error, grep for nested Collections: type: Collection inside another type: Collection.

2. Dashes in typeName Values

When Content Blocks auto-generates typeName from the name field, it strips all dashes. If you set typeName explicitly, it must follow the same convention — no dashes.

# WRONG — dash in typeName causes CType mismatch
name: myvendor/my-block
typeName: myvendor_my-block

# CORRECT — no dashes, matches auto-generation
name: myvendor/my-block
typeName: myvendor_myblock

The auto-generation logic (UniqueIdentifierCreator::removeDashes) converts myvendor/my-block to myvendor_myblock. If your explicit typeName uses dashes, it won't match existing database records created by auto-generation.

3. Reserved Field Identifier: description

The identifier description is a top-level config.yaml key (the content block's description shown in the backend). Using it as a field identifier creates a type conflict — the config key is a string, but a Textarea field resolves to a different type.

# WRONG — conflicts with the config.yaml root key
description: My content block description
fields:
  - identifier: description      # <-- conflicts with root "description"
    type: Textarea

# CORRECT — use a distinct identifier
description: My content block description
fields:
  - identifier: description_text  # <-- no conflict
    type: Textarea

4. Template Field References Must Match config.yaml Identifiers

Every {data.fieldname} in frontend.html must exactly match an identifier in config.yaml. There is no runtime error — the field simply renders empty, making this a silent bug.

# config.yaml defines:
- identifier: features_list
  type: Textarea
<!-- WRONG — silent failure, renders empty -->
{data.features -> f:split(separator: '\n')}

<!-- CORRECT — matches the identifier -->
{data.features_list -> f:split(separator: '\n')}

When renaming field identifiers (e.g., to resolve conflicts), always search templates for the old name.

5. Collection Identifier Naming — Avoid Table Name Collisions

Never name a Collection field with an identifier that matches an existing TYPO3 database table (e.g., pages, tt_content, sys_file). Content Blocks generates table names from Collection identifiers, and a collision with a core table causes unpredictable errors.

# DANGEROUS — "pages" collides with TYPO3 core table
- identifier: pages
  type: Collection

# SAFE — use a descriptive, unique identifier
- identifier: page_items
  type: Collection

Credits & Attribution

This skill incorporates information from the official Content Blocks documentation maintained by the TYPO3 Content Types Team and Friends of TYPO3.

Original documentation: https://docs.typo3.org/p/friendsoftypo3/content-blocks/

Adapted by webconsulting.at for this skill collection

Source: https://github.com/dirnbauer/webconsulting-skills

平台分布

Claude Code

29.64%
按下载量换算192

Cursor

25.2%
按下载量换算164

Gemini CLI

16.16%
按下载量换算105

windsurf

13.62%
按下载量换算88

OpenCode

7.51%
按下载量换算49

Antigravity

3.29%
按下载量换算21

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills