typo3-content-blocks

安装量: 59
排名: #12707

安装

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

TYPO3 Content Blocks Development

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.

  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 Approach Content Blocks Approach Multiple TCA files One config.yaml Manual SQL definitions Auto-generated schema Separate TypoScript Auto-registered rendering Scattered translations Single labels.xlf Complex setup Simple folder structure 2. Installation

Install via Composer (DDEV recommended)

ddev composer require friendsoftypo3/content-blocks

After installation, clear caches

ddev typo3 cache:flush

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]

  1. Content Types Overview

Content Blocks supports four content types:

Type Folder Table Use Case ContentElements ContentBlocks/ContentElements/ tt_content Frontend content (hero, accordion, CTA) RecordTypes ContentBlocks/RecordTypes/ Custom/existing Structured 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) 4. Folder Structure 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

  1. 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

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

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

{data.header}

{data.subheadline}

{data.cta_text -> f:or(default: 'Learn more')}
</html>

Backend Preview Template

<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">
{data.header}
{data.subheadline}
</html>
  1. 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 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

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: 999 # Default type (loaded first) 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

  1. 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 Case Example Structured page properties Blog with author, teaser image, publish date Plugin integration News lists, event calendars reading page properties Different page behavior Landing pages without navigation SEO-specific fields Custom 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 Option Type Required Description typeName integer ✓ Unique doktype number (use Unix timestamp) group string Group in selector: default, link, special

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.html to preview custom page properties:

<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">
Author: {data.author_name}
Published: {data.publish_date}
</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:

By {data.author_name}

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) } }

  1. Creating File Types (Extended Metadata)

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.

Available File Type Names typeName File Types image JPEG, PNG, GIF, WebP, SVG video MP4, WebM, OGG audio MP3, WAV, OGG text TXT, PDF, Markdown application ZIP, 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 Option Type Required Description typeName string ✓ One of: text, image, audio, video, application prefixFields boolean Disable prefixing (recommended: false) Use Cases for File Types Use Case Fields 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 Accessing File Type Fields

In Fluid templates, access custom metadata through FAL references:

Photo: {image.properties.photographer} | © {image.properties.copyright}

  1. Field Types Reference Simple Fields Type Description Example 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 Relational Fields Type Description Example 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 Structural Fields Type Description Example 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 Common Field Options fields:
  2. 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 fields: - identifier: gallery_images type: File allowed: common-image-types minitems: 1 maxitems: 10 appearance: createNewRelationLinkTitle: Add Image showAllLocalizationLink: true behaviour: allowLanguageSynchronization: true

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

  1. 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

  1. Templating Features Accessing Data in Fluid

{data.header}

{data.uid} {data.pid} {data.languageId} {data.mainType} {data.recordType} {data.fullType}

{data.rawRecord.some_field}

{data.systemProperties.createdAt} {data.systemProperties.lastUpdatedAt} {data.systemProperties.sorting}

{data.languageInfo.translationParent}

{item.title}

{item.content}

Asset ViewHelpers

Translation ViewHelper

  1. 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

  1. 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

ddev typo3 cache:flush ddev typo3 database:updateschema

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

  1. 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/Appearance - TYPO3/Links group: common prefixFields: true prefixType: full

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

  1. Best Practices DO ✅

Use Extbase-compatible table names for Record Types:

table: tx_myextension_domain_model_myrecord

Reuse existing fields when possible:

  • identifier: header useExistingField: true

Group related fields with Tabs and Palettes:

  • identifier: settings_tab type: Tab label: Settings

Use meaningful identifiers (snake_case):

  • identifier: hero_background_image

Clear caches after changes:

ddev typo3 cache:flush -g system ddev typo3 extension:setup --extension=my_sitepackage

Use labels.xlf for all user-facing labels

DON'T ❌

Don't use raw SQL - Content Blocks generates schema automatically

Don't duplicate TCA - Config.yaml is the single source of truth

Don't use short table names for Extbase integration:

❌ Wrong

table: team_member

✅ Correct

table: tx_mysitepackage_domain_model_teammember

Don't use dashes in identifiers:

❌ Wrong

identifier: hero-image

✅ Correct

identifier: hero_image

Don't forget shareAcross options when using foreign_table in multiple places

  1. 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

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 // 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', ], ], ];

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 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 Content Blocks Documentation YAML Reference Field Types Content Elements API Record Types API Page Types API File Types YAML Reference Migration Skill Packagist: friendsoftypo3/content-blocks 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

返回排行榜