Introduction¶
Motivation:
Defining “Content Elements” in TYPO3 is hard and the learning curve is steep.
The concept of a so called Content Block
is introduced in the form of a new
system extension content_blocks
into the Core. A Content Block is a simplified
way to define new Content Types. This includes Content Elements
, Page Types
and generic Record Types
. The definition is declared mainly inside a YAML
file. This YAML file defines both, the required fields and the structure in
which they are displayed in the editing view in the backend. From this single
file all other “low-level” definitions are generated during the runtime and
stored in a dedicated cache. Content Blocks is not there (and not able) to
replace the current system, but adds another abstraction layer to a complicated
API.
For more insights about what Content Blocks replaces, read this article.
Structure¶
To create a new Content Block, a folder ContentBlocks
has to be created
on the root level inside an existing and loaded extension. Then, depending on
the Content Type you want to create, you either create a ContentElements
,
PageTypes
or RecordTypes
folder, in which you finally put your Content
Block inside. To quickly kickstart a new Content Block, the command
make:content-block
can be used.
A minimal Content Block consists of this directory structure:
Assets/
Icon.svg
Source/
Language/
Labels.xlf
EditorPreview.html
Frontend.html
EditorInterface.yaml
The Assets
folder can be compared with the Resources/Public
folder and the
Source
folder with Resources/Private
. The Assets/Icon.svg
is registered
automatically for the Content Type icon. Only Content Elements can have a
EditorPreview.html
and Frontend.html
file. The backend translations are put
inside Source/Language/Labels.xlf
.
EditorInterface.yaml¶
The heart of a Content Block is the EditorInterface.yaml
file. This YAML file
defines both the available fields and the structure:
name: vendor/content-block-name
fields:
- identifier: header
useExistingField: true
- identifier: my_text_field
type: Text
max: 10
First of all, a name
has to be defined. It must be unique inside your
installation. It consists, similarly to composer package names, of a vendor and
a package part separated by a slash. It is used to prefix new field names, new
tables and record type identifiers.
Inside fields
you define the structure and configuration of the
necessary fields. The identifier
has to be unique per Content Block.
It is possible to reuse existing fields with the flag useExistingField
.
This allows e.g. to use the same field header
or bodytext
across multiple
Content Blocks with different configuration. Be aware that system fields
shouldn’t be reused. A list of sane reusable fields can be referenced in the
documentation. Of course, own custom fields can be reused as well.
Fluid templating¶
The EditorPreview.html
is the Fluid template for the backend preview and the
Frontend.html
template for the frontend. Both contain the above defined fields
inside the variable data
and can be directly accessed.
<cb:asset.css identifier="content-block-foo" file="Frontend.css"/>
<cb:asset.script identifier="content-block-foo" file="Frontend.js"/>
<cb:translate key="my-key"/>
My header: {data.header}
My textfield: {data.my_text_field}
Content Blocks provides its own asset ViewHelpers <cb:asset.css>
and
<cb:asset.script>
. Required arguments are identifier
,
and file
(relative to the “Assets” folder inside the Content Block).
Be aware: the Core asset ViewHelpers won’t work for Content Blocks in composer
mode.
For frontend translations Content Blocks also provides its own translation
ViewHelper. This can be seen as a simplified f:translate
ViewHelper.
The only required argument is key
. The ViewHelper will automatically
resolve the path to the Labels.xlf
file of the current Content Block.
Further reading