typo3-content-blocks

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TYPO3 Content Blocks Development

TYPO3 Content Blocks 开发

Compatibility: TYPO3 v13.x and v14.x (v14 preferred) All code examples in this skill are designed to work on both TYPO3 v13 and v14.
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 your target TYPO3 version (v13 or v14) by checking the official TYPO3 documentation.
兼容性: TYPO3 v13.x 和 v14.x(推荐v14) 本技能中的所有代码示例均适用于TYPO3 v13和v14版本。
TYPO3 API优先原则: 在创建自定义实现之前,始终使用TYPO3的内置API、核心功能和既定约定。不要重复造轮子,TYPO3已提供的功能无需重新开发。在使用API和方法前,请务必通过官方TYPO3文档确认它们在目标版本(v13或v14)中存在且未被弃用。

1. The Single Source of Truth Principle

1. 唯一可信来源原则

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
Content Blocks是TYPO3中创建自定义内容类型的现代化方案。它通过单一YAML配置消除冗余,自动生成:
  • TCA(表配置数组)
  • 数据库架构(SQL)
  • TypoScript渲染配置
  • 后端表单与预览
  • 标签与翻译

Why Content Blocks?

为什么选择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
传统方式Content Blocks方式
多个TCA文件单个
config.yaml
手动编写SQL定义自动生成数据库架构
独立的TypoScript配置自动注册渲染规则
分散的翻译文件单个
labels.xlf
复杂的设置流程简洁的文件夹结构

2. Installation

2. 安装

bash
undefined
bash
undefined

Install via Composer (DDEV recommended)

通过Composer安装(推荐使用DDEV)

ddev composer require friendsoftypo3/content-blocks
ddev composer require friendsoftypo3/content-blocks

After installation, clear caches

安装完成后,清除缓存

ddev typo3 cache:flush
undefined
ddev typo3 cache:flush
undefined

Security Configuration (Classic Mode)

安全配置(经典模式)

For non-composer installations, deny web access to ContentBlocks folder:
apache
undefined
对于非Composer安装的项目,需禁止Web访问ContentBlocks文件夹:
apache
undefined

.htaccess addition

.htaccess中添加以下规则

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

3. Content Types Overview

3. 内容类型概述

Content Blocks supports four content types:
TypeFolderTableUse Case
ContentElements
ContentBlocks/ContentElements/
tt_content
Frontend content (hero, accordion, CTA)
RecordTypes
ContentBlocks/RecordTypes/
Custom/existingStructured records (news, products, team)
PageTypes
ContentBlocks/PageTypes/
pages
Custom page types (blog, landing page)
FileTypes
ContentBlocks/FileTypes/
sys_file_metadata
Extended file metadata (photographer, copyright)
Content Blocks支持四种内容类型:
类型文件夹数据表使用场景
ContentElements
ContentBlocks/ContentElements/
tt_content
前端内容(Hero横幅、折叠面板、CTA按钮等)
RecordTypes
ContentBlocks/RecordTypes/
自定义/现有表结构化记录(新闻、产品、团队成员等)
PageTypes
ContentBlocks/PageTypes/
pages
自定义页面类型(博客、落地页等)
FileTypes
ContentBlocks/FileTypes/
sys_file_metadata
扩展文件元数据(摄影师信息、版权声明等)

4. Folder Structure

4. 文件夹结构

EXT:my_sitepackage/
└── ContentBlocks/
    ├── ContentElements/
    │   └── my-hero/
    │       ├── assets/
    │       │   └── icon.svg
    │       ├── language/
    │       │   └── labels.xlf
    │       ├── templates/
    │       │   ├── backend-preview.html
    │       │   ├── frontend.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.html
    │       └── config.yaml
    └── FileTypes/
        └── image-extended/
            ├── language/
            │   └── labels.xlf
            └── config.yaml
EXT:my_sitepackage/
└── ContentBlocks/
    ├── ContentElements/
    │   └── my-hero/
    │       ├── assets/
    │       │   └── icon.svg
    │       ├── language/
    │       │   └── labels.xlf
    │       ├── templates/
    │       │   ├── backend-preview.html
    │       │   ├── frontend.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.html
    │       └── config.yaml
    └── FileTypes/
        └── image-extended/
            ├── language/
            │   └── labels.xlf
            └── config.yaml

5. Creating Content Elements

5. 创建内容元素

Kickstart Command (Recommended)

快速启动命令(推荐)

bash
undefined
bash
undefined

Interactive mode

交互式模式

ddev typo3 make:content-block
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"
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
undefined
ddev typo3 cache:flush -g system ddev typo3 extension:setup --extension=my_sitepackage
undefined

Minimal Content Element

最简内容元素配置

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/ContentElements/hero-banner/config.yaml

EXT:my_sitepackage/ContentBlocks/ContentElements/hero-banner/config.yaml

name: myvendor/hero-banner fields:
  • identifier: header useExistingField: true
  • identifier: bodytext useExistingField: true
undefined
name: myvendor/hero-banner fields:
  • identifier: header useExistingField: true
  • identifier: bodytext useExistingField: true
undefined

Full Content Element Example

完整内容元素示例

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/ContentElements/hero-banner/config.yaml

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
undefined
name: myvendor/hero-banner group: default description: "带图片和CTA按钮的全宽Hero横幅" prefixFields: true prefixType: full basics:
  • TYPO3/Appearance
  • TYPO3/Links fields:
  • identifier: header useExistingField: true
  • identifier: subheadline type: Text label: 副标题
  • identifier: hero_image type: File minitems: 1 maxitems: 1 allowed: common-image-types
  • identifier: cta_link type: Link label: 调用链接
  • identifier: cta_text type: Text label: 按钮文本
undefined

Frontend Template

前端模板

html
<!-- templates/frontend.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>
html
<!-- templates/frontend.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: '了解更多')}
            </f:link.typolink>
        </f:if>
    </div>
</section>
</html>

Backend Preview Template

后端预览模板

html
<!-- templates/backend-preview.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>
html
<!-- templates/backend-preview.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)

6. 创建记录类型(自定义数据表)

Record Types create custom database tables for structured data like teams, products, events, etc.
记录类型用于为结构化数据(如团队成员、产品、活动等)创建自定义数据库表

Extbase-Compatible Table Naming

兼容Extbase的表命名规则

IMPORTANT: For Extbase compatibility, use the
tx_extensionkey_domain_model_*
naming convention:
yaml
undefined
重要提示: 为了兼容Extbase,请使用
tx_extensionkey_domain_model_*
命名约定:
yaml
undefined

✅ CORRECT - Extbase compatible table name

✅ 正确 - 兼容Extbase的表名

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

```yaml
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

```yaml

❌ WRONG - Short table names don't work with Extbase

❌ 错误 - 短表名无法兼容Extbase

name: myvendor/team-member table: team_member # Won't work with Extbase!
undefined
name: myvendor/team-member table: team_member # 无法与Extbase兼容!
undefined

Minimal Record Type

最简记录类型配置

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/RecordTypes/team-member/config.yaml

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
undefined
name: myvendor/team-member table: tx_mysitepackage_domain_model_teammember labelField: name fields:
  • identifier: name type: Text
undefined

Full Record Type Example

完整记录类型示例

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/RecordTypes/team-member/config.yaml

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 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 items:
      • label: LinkedIn value: linkedin
      • label: Twitter/X value: twitter
      • label: GitHub value: github
    • identifier: url type: Link
undefined
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 security: ignorePageTypeRestriction: true # 允许在普通页面使用 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 items:
      • label: LinkedIn value: linkedin
      • label: Twitter/X value: twitter
      • label: GitHub value: github
    • identifier: url type: Link
undefined

Multi-Type Records (Single Table Inheritance)

多类型记录(单表继承)

Create multiple types for one table:
yaml
undefined
为单个表创建多种类型:
yaml
undefined

EXT:my_sitepackage/ContentBlocks/RecordTypes/person-employee/config.yaml

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: 999 # Default type (loaded first) labelField: name languageAware: false workspaceAware: false fields:
  • identifier: name type: Text
  • identifier: department type: Text

```yaml
name: myvendor/person-employee table: tx_mysitepackage_domain_model_person typeField: person_type typeName: employee priority: 999 # 默认类型(优先加载) labelField: name languageAware: false workspaceAware: false fields:
  • identifier: name type: Text
  • identifier: department type: Text

```yaml

EXT:my_sitepackage/ContentBlocks/RecordTypes/person-contractor/config.yaml

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
undefined
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
undefined

Record Types as Collection Children

作为集合子项的记录类型

Define a record that can be used in IRRE collections:
yaml
undefined
定义可用于IRRE集合的记录:
yaml
undefined

EXT:my_sitepackage/ContentBlocks/RecordTypes/slide/config.yaml

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

```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

```yaml

EXT:my_sitepackage/ContentBlocks/ContentElements/slider/config.yaml

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
undefined
name: myvendor/slider fields:
  • identifier: slides type: Collection foreign_table: tx_mysitepackage_domain_model_slide shareAcrossTables: true shareAcrossFields: true minitems: 1
undefined

7. Creating Page Types (Custom doktypes)

7. 创建页面类型(自定义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.
页面类型扩展
pages
表,添加自定义页面类型——非常适合博客文章、落地页、新闻页或具有特殊属性的其他页面变体。

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
使用场景示例
结构化页面属性包含作者、 teaser图片、发布日期的博客
插件集成读取页面属性的新闻列表、事件日历
差异化页面行为无导航的落地页
SEO专属字段每种页面类型的自定义元字段

Minimal Page Type

最简页面类型配置

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/PageTypes/blog-article/config.yaml

EXT:my_sitepackage/ContentBlocks/PageTypes/blog-article/config.yaml

name: myvendor/blog-article typeName: 1705234567 fields:
  • identifier: author_name type: Text
undefined
name: myvendor/blog-article typeName: 1705234567 fields:
  • identifier: author_name type: Text
undefined

Full Page Type Example

完整页面类型示例

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/PageTypes/blog-article/config.yaml

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)
undefined
name: myvendor/blog-article typeName: 1705234567 # Unix时间戳(唯一标识符) group: default # 选项:default、link、special fields:
  • identifier: author_name type: Text label: 作者 required: true
  • identifier: teaser_text type: Textarea label: 预览文本
  • identifier: hero_image type: File allowed: common-image-types maxitems: 1
  • identifier: publish_date type: DateTime label: 发布日期
  • identifier: reading_time type: Number label: 阅读时长(分钟)
undefined

Page Type Options

页面类型选项

OptionTypeRequiredDescription
typeName
integerUnique doktype number (use Unix timestamp)
group
stringGroup in selector:
default
,
link
,
special
Reserved typeName values: 199, 254 (cannot be used)
选项类型必填描述
typeName
整数唯一的doktype编号(建议使用Unix时间戳)
group
字符串选择器中的分组:
default
link
special
保留的typeName值: 199、254(不可使用)

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
页面类型支持特定状态的图标。将以下图标添加到assets文件夹:
ContentBlocks/PageTypes/blog-article/
├── assets/
│   ├── icon.svg              # 默认图标
│   ├── icon-hide-in-menu.svg # 隐藏在菜单中的状态图标
│   └── icon-root.svg         # 站点根节点状态图标
└── config.yaml

Backend Preview

后端预览

Create a
backend-preview.html
to preview custom page properties:
html
<!-- templates/backend-preview.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>
创建
backend-preview.html
以预览自定义页面属性:
html
<!-- templates/backend-preview.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>作者:</strong> {data.author_name}
        </be:link.editRecord>
        <f:if condition="{data.publish_date}">
            <br/><small>发布日期: <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:
typoscript
undefined
页面类型没有自动前端渲染。需在TypoScript中添加ContentBlocksDataProcessor:
typoscript
undefined

Configuration/TypoScript/setup.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:

```html
<!-- 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>
page = PAGE page { 10 = FLUIDTEMPLATE 10 { templateName = Default templateRootPaths.10 = EXT:my_sitepackage/Resources/Private/Templates/
    dataProcessing {
        # 处理Content Blocks页面数据
        1 = content-blocks
    }
}
}

然后在Fluid模板中访问字段:

```html
<!-- Resources/Private/Templates/Default.html -->
<f:if condition="{data.author_name}">
    <p class="author">作者:{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:
typoscript
undefined
若要在“创建新页面”拖拽区域隐藏页面类型:
typoscript
undefined

Configuration/user.tsconfig

Configuration/user.tsconfig

options { pageTree { doktypesToShowInNewPageDragArea := removeFromList(1705234567) } }
undefined
options { pageTree { doktypesToShowInNewPageDragArea := removeFromList(1705234567) } }
undefined

8. Creating File Types (Extended Metadata)

8. 创建文件类型(扩展元数据)

New in version 1.2
File Types extend the
sys_file_metadata
table with custom fields – perfect for photographer credits, copyright notices, or additional file options.
版本1.2新增功能
文件类型扩展
sys_file_metadata
表,添加自定义字段——非常适合摄影师署名、版权声明或其他文件选项。

Available File Type Names

可用的文件类型名称

typeNameFile Types
image
JPEG, PNG, GIF, WebP, SVG
video
MP4, WebM, OGG
audio
MP3, WAV, OGG
text
TXT, PDF, Markdown
application
ZIP, Office formats
typeName文件类型
image
JPEG、PNG、GIF、WebP、SVG
video
MP4、WebM、OGG
audio
MP3、WAV、OGG
text
TXT、PDF、Markdown
application
ZIP、Office格式

Minimal File Type

最简文件类型配置

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/FileTypes/image-extended/config.yaml

EXT:my_sitepackage/ContentBlocks/FileTypes/image-extended/config.yaml

name: myvendor/image-extended typeName: image fields:
  • identifier: photographer type: Text label: Photographer
undefined
name: myvendor/image-extended typeName: image fields:
  • identifier: photographer type: Text label: 摄影师
undefined

Full File Type Example

完整文件类型示例

yaml
undefined
yaml
undefined

EXT:my_sitepackage/ContentBlocks/FileTypes/image-extended/config.yaml

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
undefined
name: myvendor/image-extended typeName: image prefixFields: false # 保留原始列名 fields:
  • identifier: image_overlay_palette type: Palette label: 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette' fields:

    复用TYPO3核心现有字段

    • identifier: alternative useExistingField: true
    • identifier: description useExistingField: true
    • type: Linebreak
    • identifier: link useExistingField: true
    • identifier: title useExistingField: true
    • type: Linebreak

    自定义字段

    • identifier: photographer type: Text label: 摄影师
    • identifier: copyright type: Text label: 版权声明
    • identifier: source_url type: Link label: 来源URL
    • type: Linebreak
    • identifier: crop useExistingField: true
undefined

File Type Options

文件类型选项

OptionTypeRequiredDescription
typeName
stringOne of:
text
,
image
,
audio
,
video
,
application
prefixFields
booleanDisable prefixing (recommended:
false
)
选项类型必填描述
typeName
字符串可选值:
text
image
audio
video
application
prefixFields
布尔值禁用前缀(推荐设置为
false

Use Cases for File Types

文件类型使用场景

Use CaseFields to Add
Photography agency
photographer
,
copyright
,
license_type
,
expiry_date
Video platform
director
,
duration
,
transcript
,
subtitles
Document management
document_version
,
author
,
confidentiality
E-commerce
product_sku
,
variant_color
,
variant_size
使用场景需添加的字段
摄影机构
photographer
copyright
license_type
expiry_date
视频平台
director
duration
transcript
subtitles
文档管理
document_version
author
confidentiality
电商平台
product_sku
variant_color
variant_size

Accessing File Type Fields

访问文件类型字段

In Fluid templates, access custom metadata through FAL references:
html
<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>
在Fluid模板中,通过FAL引用访问自定义元数据:
html
<f:for each="{data.images}" as="image">
    <figure>
        <f:image image="{image}" alt="{image.alternative}"/>
        <f:if condition="{image.properties.photographer}">
            <figcaption>
                摄影:{image.properties.photographer}
                <f:if condition="{image.properties.copyright}">
                    | © {image.properties.copyright}
                </f:if>
            </figcaption>
        </f:if>
    </figure>
</f:for>

9. Field Types Reference

9. 字段类型参考

Simple Fields

简单字段

TypeDescriptionExample
Text
Single line text
type: Text
Textarea
Multi-line text
type: Textarea
Email
Email address
type: Email
Link
Link/URL
type: Link
Number
Integer/Float
type: Number
DateTime
Date and/or time
type: DateTime
Color
Color picker
type: Color
Checkbox
Boolean checkbox
type: Checkbox
Radio
Radio buttons
type: Radio
Slug
URL slug
type: Slug
Password
Password field
type: Password
类型描述示例
Text
单行文本
type: Text
Textarea
多行文本
type: Textarea
Email
邮箱地址
type: Email
Link
链接/URL
type: Link
Number
整数/浮点数
type: Number
DateTime
日期和/或时间
type: DateTime
Color
颜色选择器
type: Color
Checkbox
布尔复选框
type: Checkbox
Radio
单选按钮
type: Radio
Slug
URL别名
type: Slug
Password
密码字段
type: Password

Relational Fields

关联字段

TypeDescriptionExample
File
File references (FAL)
type: File
Relation
Record relations
type: Relation
Select
Dropdown selection
type: Select
Category
System categories
type: Category
Collection
Inline records (IRRE)
type: Collection
Folder
Folder reference
type: Folder
Language
Language selector
type: Language
类型描述示例
File
文件引用(FAL)
type: File
Relation
记录关联
type: Relation
Select
下拉选择
type: Select
Category
系统分类
type: Category
Collection
内联记录(IRRE)
type: Collection
Folder
文件夹引用
type: Folder
Language
语言选择器
type: Language

Structural Fields

结构字段

TypeDescriptionExample
Tab
Tab separator
type: Tab
Palette
Group fields
type: Palette
Linebreak
Line break in palette
type: Linebreak
FlexForm
FlexForm container
type: FlexForm
Json
JSON field
type: Json
类型描述示例
Tab
标签页分隔符
type: Tab
Palette
字段分组
type: Palette
Linebreak
分组内换行
type: Linebreak
FlexForm
FlexForm容器
type: FlexForm
Json
JSON字段
type: Json

Common Field Options

通用字段选项

yaml
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
yaml
fields:
  - identifier: my_field
    type: Text
    label: 我的字段标签           # 静态标签(或使用labels.xlf)
    description: 帮助文本          # 字段描述
    required: true                  # 设置为必填字段
    default: "默认值"        # 默认值
    placeholder: "输入文本..."    # 占位文本
    prefixField: false              # 为此字段禁用前缀
    useExistingField: true          # 复用现有TCA字段
    displayCond: 'FIELD:other:=:1'  # 条件显示
    onChange: reload                # 字段变更时重新加载表单

File Field Example

文件字段示例

yaml
fields:
  - identifier: gallery_images
    type: File
    allowed: common-image-types
    minitems: 1
    maxitems: 10
    appearance:
      createNewRelationLinkTitle: Add Image
      showAllLocalizationLink: true
    behaviour:
      allowLanguageSynchronization: true
yaml
fields:
  - identifier: gallery_images
    type: File
    allowed: common-image-types
    minitems: 1
    maxitems: 10
    appearance:
      createNewRelationLinkTitle: 添加图片
      showAllLocalizationLink: true
    behaviour:
      allowLanguageSynchronization: true

Select Field Example

选择字段示例

yaml
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
yaml
fields:
  - identifier: layout
    type: Select
    renderType: selectSingle
    default: default
    items:
      - label: 默认布局
        value: default
      - label: 宽布局
        value: wide
      - label: 紧凑布局
        value: compact

Collection Field Example (Inline IRRE)

集合字段示例(内联IRRE)

yaml
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
yaml
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: 默认展开

10. Field Prefixing

10. 字段前缀

Content Blocks automatically prefixes field identifiers to avoid collisions.
Content Blocks会自动为字段标识符添加前缀,避免冲突。

Prefixing Types

前缀类型

yaml
undefined
yaml
undefined

Full prefix (default): myvendor_myblock_fieldname

完整前缀(默认): myvendor_myblock_fieldname

name: myvendor/my-block prefixFields: true prefixType: full
name: myvendor/my-block prefixFields: true prefixType: full

Vendor prefix only: myvendor_fieldname

仅供应商前缀: myvendor_fieldname

name: myvendor/my-block prefixFields: true prefixType: vendor
name: myvendor/my-block prefixFields: true prefixType: vendor

Custom vendor prefix: tx_custom_fieldname

自定义供应商前缀: tx_custom_fieldname

name: myvendor/my-block prefixFields: true prefixType: vendor vendorPrefix: tx_custom
name: myvendor/my-block prefixFields: true prefixType: vendor vendorPrefix: tx_custom

No prefix (use with caution!)

无前缀(谨慎使用!)

name: myvendor/my-block prefixFields: false
undefined
name: myvendor/my-block prefixFields: false
undefined

Disable Prefixing per Field

为单个字段禁用前缀

yaml
fields:
  - identifier: my_custom_field
    type: Text
    prefixField: false  # This field won't be prefixed
yaml
fields:
  - identifier: my_custom_field
    type: Text
    prefixField: false  # 该字段不会添加前缀

11. Templating Features

11. 模板功能

Accessing Data in Fluid

在Fluid中访问数据

html
<!-- 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>
html
<!-- 基础字段访问 -->
{data.header}
{data.my_field}

<!-- 记录元数据 -->
{data.uid}
{data.pid}
{data.languageId}
{data.mainType}      <!-- 数据表名: tt_content -->
{data.recordType}    <!-- CType: myvendor_heroblock -->
{data.fullType}      <!-- tt_content.myvendor_heroblock -->

<!-- 原始数据库值 -->
{data.rawRecord.some_field}

<!-- 系统属性 -->
{data.systemProperties.createdAt}
{data.systemProperties.lastUpdatedAt}
{data.systemProperties.sorting}
{data.systemProperties.disabled}

<!-- 语言信息 -->
{data.languageInfo.translationParent}
{data.languageInfo.translationSource}

<!-- 关联数据自动解析! -->
<f:for each="{data.gallery_images}" as="image">
    <f:image image="{image}" width="400"/>
</f:for>

<!-- 嵌套集合 -->
<f:for each="{data.accordion_items}" as="item">
    <h3>{item.title}</h3>
    <f:format.html>{item.content}</f:format.html>
</f:for>

Asset ViewHelpers

资源视图助手

html
<!-- 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"/>
html
<!-- 从assets文件夹引入CSS -->
<f:asset.css identifier="my-block-css" href="{cb:assetPath()}/frontend.css"/>

<!-- 从assets文件夹引入JS -->
<f:asset.script identifier="my-block-js" src="{cb:assetPath()}/frontend.js"/>

<!-- 跨模块资源引用 -->
<f:asset.css identifier="shared-css" href="{cb:assetPath(name: 'vendor/other-block')}/shared.css"/>

Translation ViewHelper

翻译视图助手

html
<!-- 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"/>
html
<!-- 访问labels.xlf中的翻译 -->
<f:translate key="{cb:languagePath()}:my_label"/>

<!-- 跨模块翻译引用 -->
<f:translate key="{cb:languagePath(name: 'vendor/other-block')}:shared_label"/>

12. Extending Existing Tables

12. 扩展现有数据表

Add custom types to existing tables (like
tx_news
):
yaml
undefined
为现有表(如
tx_news
)添加自定义类型:
yaml
undefined

EXT:my_sitepackage/ContentBlocks/RecordTypes/custom-news/config.yaml

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
undefined
name: myvendor/custom-news table: tx_news_domain_model_news typeName: custom_news fields:
  • identifier: title useExistingField: true
  • identifier: custom_field type: Text
undefined

13. Workflow with DDEV

13. 与DDEV配合的工作流

Standard Development Workflow

标准开发工作流

bash
undefined
bash
undefined

1. Create new Content Block

1. 创建新的Content Block

ddev typo3 make:content-block
ddev typo3 make:content-block

2. Clear system caches

2. 清除系统缓存

ddev typo3 cache:flush -g system
ddev typo3 cache:flush -g system

3. Update database schema

3. 更新数据库架构

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

Alternative: Use Database Analyzer in TYPO3 Backend

替代方案:使用TYPO3后端的数据库分析器

Admin Tools > Maintenance > Analyze Database Structure

管理工具 > 维护 > 分析数据库结构

undefined
undefined

Using webprofil/make Extension

使用webprofil/make扩展

If
webprofil/make
is installed:
bash
undefined
若已安装
webprofil/make
bash
undefined

Create Content Block with webprofil/make

使用webprofil/make创建Content Block

ddev make:content_blocks
ddev make:content_blocks

Clear caches and update database

清除缓存并更新数据库

ddev typo3 cache:flush ddev typo3 database:updateschema
undefined
ddev typo3 cache:flush ddev typo3 database:updateschema
undefined

Integration with Extbase

与Extbase集成

After creating Record Types with proper table names, generate Extbase models:
bash
undefined
创建符合表名规则的记录类型后,生成Extbase模型:
bash
undefined

If typo3:make:model is available

若typo3:make:model可用

ddev typo3 make:model --extension=my_sitepackage
ddev typo3 make:model --extension=my_sitepackage

Generate repository

生成仓库类

ddev typo3 make:repository --extension=my_sitepackage
undefined
ddev typo3 make:repository --extension=my_sitepackage
undefined

14. Defaults Configuration

14. 默认配置

Create a
content-blocks.yaml
in project root for default settings:
yaml
undefined
在项目根目录创建
content-blocks.yaml
设置默认配置:
yaml
undefined

content-blocks.yaml

content-blocks.yaml

vendor: myvendor extension: my_sitepackage content-type: content-element skeleton-path: content-blocks-skeleton
config: content-element: basics: - TYPO3/Appearance - TYPO3/Links group: common prefixFields: true prefixType: full
record-type: prefixFields: true prefixType: vendor vendorPrefix: tx_mysitepackage
undefined
vendor: myvendor extension: my_sitepackage content-type: content-element skeleton-path: content-blocks-skeleton
config: content-element: basics: - TYPO3/Appearance - TYPO3/Links group: common prefixFields: true prefixType: full
record-type: prefixFields: true prefixType: vendor vendorPrefix: tx_mysitepackage
undefined

15. Best Practices

15. 最佳实践

DO ✅

推荐做法 ✅

  1. Use Extbase-compatible table names for Record Types:
    yaml
    table: tx_myextension_domain_model_myrecord
  2. Reuse existing fields when possible:
    yaml
    - identifier: header
      useExistingField: true
  3. Group related fields with Tabs and Palettes:
    yaml
    - identifier: settings_tab
      type: Tab
      label: Settings
  4. Use meaningful identifiers (snake_case):
    yaml
    - identifier: hero_background_image
  5. Clear caches after changes:
    bash
    ddev typo3 cache:flush -g system
    ddev typo3 extension:setup --extension=my_sitepackage
  6. Use labels.xlf for all user-facing labels
  1. 为记录类型使用兼容Extbase的表名:
    yaml
    table: tx_myextension_domain_model_myrecord
  2. 尽可能复用现有字段:
    yaml
    - identifier: header
      useExistingField: true
  3. 使用标签页和分组来组织相关字段:
    yaml
    - identifier: settings_tab
      type: Tab
      label: 设置
  4. 使用有意义的标识符(蛇形命名法snake_case):
    yaml
    - identifier: hero_background_image
  5. 修改后清除缓存:
    bash
    ddev typo3 cache:flush -g system
    ddev typo3 extension:setup --extension=my_sitepackage
  6. 使用labels.xlf管理所有用户可见的标签

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:
    yaml
    # ❌ Wrong
    table: team_member
    
    # ✅ Correct
    table: tx_mysitepackage_domain_model_teammember
  4. Don't use dashes in identifiers:
    yaml
    # ❌ Wrong
    identifier: hero-image
    
    # ✅ Correct
    identifier: hero_image
  5. Don't forget shareAcross options when using foreign_table in multiple places
  1. 不要使用原生SQL - Content Blocks会自动生成数据库架构
  2. 不要重复编写TCA - Config.yaml是唯一可信来源
  3. 不要为Extbase集成使用短表名:
    yaml
    # ❌ 错误
    table: team_member
    
    # ✅ 正确
    table: tx_mysitepackage_domain_model_teammember
  4. 不要在标识符中使用短横线:
    yaml
    # ❌ 错误
    identifier: hero-image
    
    # ✅ 正确
    identifier: hero_image
  5. 在多个地方使用foreign_table时,不要忘记设置shareAcross选项

16. Troubleshooting

16. 故障排除

Content Block Not Appearing

Content Block未显示

bash
undefined
bash
undefined

Clear all caches

清除所有缓存

ddev typo3 cache:flush
ddev typo3 cache:flush

Rebuild class loading

重建类加载

ddev composer dump-autoload
ddev composer dump-autoload

Check extension setup

检查扩展设置

ddev typo3 extension:setup --extension=my_sitepackage
undefined
ddev typo3 extension:setup --extension=my_sitepackage
undefined

Database Errors

数据库错误

bash
undefined
bash
undefined

Update database schema

更新数据库架构

ddev typo3 database:updateschema
ddev typo3 database:updateschema

Or use Compare Tool

或使用对比工具

Admin Tools > Maintenance > Analyze Database Structure

管理工具 > 维护 > 分析数据库结构

undefined
undefined

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
  • 检查字段标识符是否唯一(使用前缀)
  • 验证字段类型是否正确
  • 检查config.yaml中的拼写错误
  • 确保labels.xlf中有匹配的键

17. Version Constraints

17. 版本约束

php
// ext_emconf.php
$EM_CONF[$_EXTKEY] = [
    'title' => 'My Extension',
    'version' => '1.0.0',
    'state' => 'stable',
    'constraints' => [
        'depends' => [
            'typo3' => '13.0.0-14.99.99',
            'content_blocks' => '2.0.0-2.99.99',
        ],
    ],
];

php
// ext_emconf.php
$EM_CONF[$_EXTKEY] = [
    'title' => '我的扩展',
    'version' => '1.0.0',
    'state' => 'stable',
    'constraints' => [
        'depends' => [
            'typo3' => '13.0.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:
  • typo3-content-blocks-migration - Bidirectional migration guide with:
    • TCA → Content Blocks field mapping
    • Content Blocks → TCA reverse mapping
    • Data migration scripts
    • Step-by-step examples
    • Checklists for both directions

如需在传统TYPO3扩展与Content Blocks之间迁移,请查看专门的迁移技能:
  • typo3-content-blocks-migration - 双向迁移指南,包含:
    • TCA → Content Blocks字段映射
    • Content Blocks → TCA反向映射
    • 数据迁移脚本
    • 分步示例
    • 双向迁移检查清单

18. Package Management for v14 Compatibility

18. v14兼容性的包管理

If extensions don't support TYPO3 v14 yet, fork and update:
bash
undefined
若扩展尚不支持TYPO3 v14,请fork并更新:
bash
undefined

Add private fork as VCS repository in composer.json

在composer.json中添加私有fork作为VCS仓库

Then update extension for v14 using typo3-rector and typo3-update skills

然后使用typo3-rector和typo3-update技能将扩展更新为v14兼容版本


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)

---

webconsulting技术栈所需的私有fork:
- `webprofil/wp-t3monitoring-client` (^13 → ^14)
- `webprofil/deployer` (^13 → ^14)
- `webprofil/crawler` (^1.0 → 兼容v14)
- `webprofil/make` (^1.1 → 兼容v14)

---

References

参考资料

Credits & Attribution

致谢与归属

This skill incorporates information from the official Content Blocks documentation maintained by the TYPO3 Content Types Team and Friends of TYPO3.
Adapted by webconsulting.at for this skill collection
本技能整合了由TYPO3内容类型团队Friends of TYPO3维护的官方Content Blocks文档中的信息。
由webconsulting.at改编至本技能集合