Before we can understand how content is rendered, we have to see how it is structured and organized. These basics are explained in this section.
Nodes inside the TYPO3 Content Repository¶
The content in Neos is stored not inside tables of a relational database, but inside a tree-based structure: the so-called TYPO3 Content Repository.
To a certain extent, it is comparable to files in a file-system: They are also structured as a tree, and are identified uniquely by the complete path towards the file.
Internally, the TYPO3CR currently stores the nodes inside database tables as well, but you do not need to worry about that as you’ll never deal with the database directly. This high-level abstraction helps to decouple the data modelling layer from the data persistence layer.
Each element in this tree is called a Node, and is structured as follows:
- It has a node name which identifies the node, in the same way as a file or folder name identifies an element in your local file system.
- It has a node type which determines which properties a node has. Think of it as the type of a file in your file system.
- Furthermore, it has properties which store the actual data of the node.
The node type determines which properties exist for a node. As an example,
Textnode might have a
- Of course, nodes may have sub nodes underneath them.
If we imagine a classical website with a hierarchical menu structure, then each
of the pages is represented by a TYPO3CR Node of type
Document. However, not only
the pages themselves are represented as tree: Imagine a page has two columns,
with different content elements inside each of them. The columns are stored as
Nodes of type
ContentCollection, and they contain nodes of type
whatever structure is needed. This nesting can be done indefinitely: Inside
ContentCollection, there could be another three-column element which again contains
ContentCollection elements with arbitrary content inside.
Comparison to TYPO3 CMS
In TYPO3 CMS, the page tree is the central data structure, and the content of a page is stored in a more-or-less flat manner in a separate database table.
Because this was too limited for complex content, TemplaVoila was invented. It allows to create an arbitrary nesting of content elements, but is still plugged into the classical table-based architecture.
Basically, Neos generalizes the tree-based concept found in TYPO3 CMS and TemplaVoila and implements it in a consistent manner, where we do not have to distinguish between pages and other content.
Node Type Definition¶
Each TYPO3CR Node (we’ll just call it Node in the remaining text) has a specific
node type. Node Types can be defined in any package by declaring them in
Each node type can have one or multiple parent types. If these are specified, all properties and settings of the parent types are inherited.
A node type definition can look as follows:
'My.Package:SpecialHeadline': superTypes: ['TYPO3.Neos:Content'] ui: label: 'Special Headline' group: 'general' properties: headline: type: 'string' defaultValue: 'My Headline Default' ui: inlineEditable: TRUE validation: 'TYPO3.Neos/Validation/StringLengthValidator': minimum: 1 maximum: 255
The following options are allowed:
An array of parent node types inherited from. If named keys are used, it is possible to remove a defined super type again for a specific nodetype, by setting the value for that key to
'TYPO3.Neos:Document': superTypes: 'Acme.Demo.ExtraMixin': 'Acme.Demo:ExtraMixin' 'TYPO3.Neos:Shortcut': superTypes: 'Acme.Demo.ExtraMixin': ~
Constraint definitions stating which nested child node types are allowed. Also see the dedicated chapter Node Type Constraints for detailed explanation:
constraints: nodeTypes: # ALLOW text, DISALLOW Image 'TYPO3.Neos.NodeTypes:Text': TRUE 'TYPO3.Neos.NodeTypes:Image': FALSE # DISALLOW as Fallback (for not-explicitely-listed node types) '*': FALSE
A list of child nodes that are automatically created if a node of this type is created. For each child the
typehas to be given. Additionally, for each of these child nodes, the
constraintscan be specified to override the “global” constraints per type. Here is an example:
childNodes: someChild: type: 'TYPO3.Neos:ContentCollection' constraints: nodeTypes: # only allow images in this ContentCollection 'TYPO3.Neos.NodeTypes:Image': TRUE '*': FALSE
Configuration options related to the user interface representation of the node type
- The human-readable label of the node type
Name of the group this content element is grouped into for the ‘New Content Element’ dialog. It can only be created through the user interface if
groupis defined and it is valid.
All valid groups are given in the
This setting define the icon to use in the Neos UI for the node type
Currently it’s only possible to use a predefined selection of icons, which are available in Font Awesome http://fortawesome.github.io/Font-Awesome/3.2.1/icons/.
- If TRUE, it is possible to interact with this Node directly in the content view.
If FALSE, an overlay is shown preventing any interaction with the node.
If not given, checks if any property is marked as
These settings configure the inspector in the Neos UI for the node type
Defines an inspector tab that can be used to group property groups of the node type
- The human-readable label for this inspector tab
- Position of the inspector tab, small numbers are sorted on top
This setting define the icon to use in the Neos UI for the tab
Currently it’s only possible to use a predefined selection of icons, which are available in Font Awesome http://fortawesome.github.io/Font-Awesome/3.2.1/icons/.
Defines an inspector group that can be used to group properties of the node type
- The human-readable label for this inspector group
- Position of the inspector group, small numbers are sorted on top
- The tab the group belongs to. If left empty the group is added to the
A list of named properties for this node type. For each property the following settings are available.
- Data type of this property. This may be a simple type (like in PHP), a fully qualified PHP class name, or one of
these three special types:
dateto store dates / time as a DateTime object. Use
referencesto store references that point to other nodes.
referenceonly accepts a single node or node identifier, while
referencesaccepts an array of nodes or node identifiers.
- Default value of this property. Used at node creation time. Type must match specified ‘type’.
Configuration options related to the user interface representation of the property
- The human-readable label of the property
- If TRUE, the whole content element needs to be re-rendered on the server side if the value
changes. This only works for properties which are displayed inside the property inspector,
i.e. for properties which have a
- If TRUE, this property is inline editable, i.e. edited directly on the page through Aloha.
This section controls the text formatting options the user has available for this property. Example:
aloha: 'format': # Enable specific formatting options. 'strong': TRUE 'b': FALSE 'em': TRUE 'i': FALSE 'u': TRUE 'sub': TRUE 'sup': TRUE 'p': TRUE 'h1': TRUE 'h2': TRUE 'h3': TRUE 'h4': FALSE 'h5': FALSE 'h6': FALSE 'code': FALSE 'removeFormat': TRUE 'table': 'table': TRUE 'link': 'a': TRUE 'list': 'ul': TRUE 'ol': TRUE 'alignment': 'left': TRUE 'center': TRUE 'right': TRUE 'justify': TRUE 'formatlesspaste': 'button': TRUE # Show toggle button for formatless pasting. 'formatlessPasteOption': FALSE # Whether the format less pasting should be enable by default. 'strippedElements': ['a'] # If not set the default setting is used. 'autoparagraph': TRUE # Automatically wrap non-wrapped text blocks in paragraph blocks.
Example of disabling all formatting options:
aloha: 'format':  'table':  'link':  'list':  'alignment':  'formatlesspaste': 'button': FALSE 'formatlessPasteOption': TRUE
These settings configure the inspector in the Neos UI for the property.
Identifier of the inspector group this property is categorized into in the content editing user interface. If none is given, the property is not editable through the property inspector of the user interface.
The value here must reference a groups configured in the
ui.inspector.groupselement of the node type this property belongs to.
- Position inside the inspector group, small numbers are sorted on top.
- A set of options for the given editor
- A list of validators to use on the property. Below each validator type any options for the validator can be given. See below for more information.
Unset a property by setting the property configuration to null (~).
Here is one of the standard Neos node types (slightly shortened):
'TYPO3.Neos.NodeTypes:Image': superTypes: ['TYPO3.Neos:Content'] ui: label: 'Image' icon: 'icon-picture' inspector: groups: image: label: 'Image' position: 5 properties: image: type: TYPO3\Media\Domain\Model\ImageVariant ui: label: 'Image' reloadIfChanged: TRUE inspector: group: 'image' alignment: type: string defaultValue: '' ui: label: 'Alignment' reloadIfChanged: TRUE inspector: group: 'image' editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: placeholder: 'Default' values: '': label: '' center: label: 'Center' left: label: 'Left' right: label: 'Right' alternativeText: type: string ui: label: 'Alternative text' reloadIfChanged: TRUE inspector: group: 'image' validation: 'TYPO3.Neos/Validation/StringLengthValidator': minimum: 1 maximum: 255 hasCaption: type: boolean ui: label: 'Enable caption' reloadIfChanged: TRUE inspector: group: 'image' caption: type: string defaultValue: '<p>Enter caption here</p>' ui: inlineEditable: TRUE
Property Editor Reference¶
For each property which is defined in
NodeTypes.yaml, the editor inside the Neos inspector can be customized
using various options. Here follows the reference for each property type.
Property Type: boolean
BooleanEditor – Checkbox editor¶
boolean value is rendered using a checkbox in the inspector:
'isActive' type: boolean ui: label: 'is active' inspector: group: 'document'
- (no options)
Property Type: string
TextFieldEditor – Single-line Text Editor (default)¶
subtitle: type: string ui: label: 'Subtitle' inspector: group: 'document' editorOptions: placeholder: 'Enter subtitle here' maxlength: 20
placeholderproperty, which is shown if the text field is empty.
TRUE, disable this textfield.
maxlengthproperty. Maximum number of characters allowed to be entered.
TRUE, this field is cannot be written to.
TRUE, input is required.
- Custom HTML
- Custom HTML
Property Type: string
TextAreaEditor – Multi-line Text Editor¶
In case the text input should span multiple lines, a
TextAreaEditor should be used as follows:
'description': type: 'string' ui: label: 'Description' inspector: group: 'document' editor: 'TYPO3.Neos/Inspector/Editors/TextAreaEditor' editorOptions: rows: 7
- all options from Text Field Editor – see above
rows(integer): Number of lines this textarea should have; Default
Property Type: string
CodeEditor – Full-Screen Code Editor¶
In case a lot of space is needed for the text (f.e. for HTML source code), a
CodeEditor can be used:
'source': type: 'string' ui: label: 'Source' inspector: group: 'document' editor: 'TYPO3.Neos/Inspector/Editors/CodeEditor'
Furthermore, the button label can be adjusted by specifying
buttonLabel. Furthermore, the highlighting mode
can be customized, which is helpful for editing markdown and similar contents:
'markdown': type: 'string' ui: label: 'Markdown' inspector: group: 'document' editor: 'TYPO3.Neos/Inspector/Editors/CodeEditor' editorOptions: buttonLabel: 'Edit Markdown' highlightingMode: 'text/plain'
- label of the button which is used to open the full-screen editor. Default
- CodeMirror highlighting mode to use. These formats are support by default:
Property Type: string / array<string>
SelectBoxEditor – Dropdown Select Editor¶
In case only fixed strings are allowed to be chosen, a select box can be used. Multiple selection is supported as well.
The most important option is called
values, containing the choices which can be made. If wanted, an icon can be displayed
for each choice by setting the
icon class appropriately.
Basic Example – simple select box:
targetMode: type: string defaultValue: 'firstChildNode' ui: label: 'Target mode' inspector: group: 'document' editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: firstChildNode: label: 'First child node' icon: 'icon-legal' parentNode: label: 'Parent node' icon: 'icon-fire' selectedTarget: label: 'Selected target'
If the selection list should be grouped, this can be done by setting the
group key of each individual value:
country: type: string ui: label: 'Country' inspector: group: 'document' editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: italy: label: 'Italy' group: 'Southern Europe' austria: label: 'Austria' group: 'Central Europe' germany: label: 'Germany' group: 'Central Europe'
Furthermore, multiple selection is also possible, by setting
TRUE, which is automatically set
for properties of type
array. If an empty value is allowed as well,
allowEmpty should be set to
placeholder should be set to a helpful text:
styleOptions: type: array ui: label: 'Styling Options' inspector: group: 'document' editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: # The next line is set automatically for type array # multiple: TRUE allowEmpty: TRUE placeholder: 'Select Styling Options' values: leftColumn: label: 'Show Left Column' rightColumn: label: 'Show Right Column'
Because selection options shall be fetched from server-side code frequently, the Select Box Editor contains
support for so-called data sources, by setting a
dataSourceIdentifier, or optionally a
This helps to provide data to the editing interface without having to define routes, policies or a controller.:
questions: ui: inspector: editor: 'Content/Inspector/Editors/SelectBoxEditor' editorOptions: dataSourceIdentifier: 'questions' # alternatively using a custom uri: # dataSourceUri: 'custom-route/end-point'
See Data sources for more details.
The output of the data source has to be a JSON formatted array matching the
values option. Make sure you sort by
group first, if using the grouping option.
return json_encode(array( 'key' => array('label' => 'Foo', group => 'A', 'icon' => 'icon-key'), 'fire' => array('label' => 'Fire', group => 'A', 'icon' => 'icon-fire') 'legal' => array('label' => 'Legal', group => 'B', 'icon' => 'icon-legal') ));
the list of values which can be chosen from
- label of this value.
- group of this value.
- CSS icon class for this value.
- if TRUE, it is allowed to choose an empty value.
- placeholder text which is shown if nothing is selected. Only works if
TRUE, multi-selection is allowed. Default
- If set, this URI will be called for loading the options of the select field.
- If set, a server-side data source will be called for loading the possible options of the select field.
Property Type: integer
cropAfterCharacters: type: integer ui: label: 'Crop after characters' inspector: group: 'document'
all TextFieldEditor options apply
Property Type: reference / references
ReferencesEditor – Reference Selection Editors¶
The most important option for the property type
nodeTypes, which allows to
restrict the type of the target nodes which can be selected in the editor.
authors: type: references ui: label: 'Article Authors' inspector: group: 'document' editorOptions: nodeTypes: ['My.Website:Author']
nodeTypes(array of strings)
- List of node types which are allowed to be selected. By default, is set
TYPO3.Neos:Document, allowing only to choose other document nodes.
- Placeholder text to be shown if nothing is selected
- Minimum amount of characters which trigger a search
Property Type: date
DateTimeEditor – Date & Time Selection Editor¶
The most important option for
date properties is the
format, which is configured like in PHP, as the following
05-12-2014– allows to set only the date
05-12-2014 17:07– allows to set date and time
17:07– allows to set only the time
publishingDate: type: date ui: label: 'Publishing Date' inspector: group: 'document' position: 10 editorOptions: format: 'd.m.Y'
- The date format, a combination of y, Y, F, m, M, n, t, d, D, j, l, N,
S, w, a, A, g, G, h, H, i, s. Default
- The placeholder shown when no date is selected
- The granularity on which a time can be selected. Example: If set to
30, only half-hour increments of time can be chosen. Default
For the date format, these are the available placeholders:
y: A two digit representation of a year - Examples: 99 or 03
Y: A full numeric representation of a year, 4 digits - Examples: 1999 or 2003
F: A full textual representation of a month, such as January or March - January through December
m: Numeric representation of a month, with leading zeros - 01 through 12
M: A short textual representation of a month, three letters - Jan through Dec
n: Numeric representation of a month, without leading zeros - 1 through 12
t: Number of days in the given month - 28 through 31
d: Day of the month, 2 digits with leading zeros - 01 to 31
D: A textual representation of a day, three letters - Mon through Sun
j: Day of the month without leading zeros - 1 to 31
l: A full textual representation of the day of the week - Sunday through Saturday
N: ISO-8601 numeric representation of the day of the week - 1 (for Monday) through 7 (for Sunday)
S: English ordinal suffix for the day of the month, 2 characters - st, nd, rd or th.
w: Numeric representation of the day of the week - 0 (for Sunday) through 6 (for Saturday)
a: Lowercase Ante meridiem and Post meridiem - am or pm
A: Uppercase Ante meridiem and Post meridiem - AM or PM
g: hour without leading zeros - 12-hour format - 1 through 12
G: hour without leading zeros - 24-hour format - 0 through 23
h: 12-hour format of an hour with leading zeros - 01 through 12
H: 24-hour format of an hour with leading zeros - 00 through 23
i: minutes, 2 digits with leading zeros - 00 to 59
s: seconds, 2 digits with leading zeros - 00 through 59
Property Type: image (TYPO3\Media\Domain\Model\ImageVariant)
ImageEditor – Image Selection/Upload Editor¶
For properties of type
TYPO3\Media\Domain\Model\ImageVariant, an image editor is rendered. If you want cropping
and resizing functionality, you need to set
TRUE, as in the following
'teaserImage' type: 'TYPO3\Media\Domain\Model\ImageInterface' ui: label: 'Teaser Image' inspector: group: 'document' editorOptions: features: crop: TRUE resize: TRUE
If cropping is enabled, you might want to enforce a certain aspect ratio, which can be done by setting
crop.aspectRatio.locked.height. In the following example, the
image format must be
'teaserImage' type: 'TYPO3\Media\Domain\Model\ImageInterface' ui: label: 'Teaser Image' inspector: group: 'document' editorOptions: features: crop: TRUE crop: aspectRatio: locked: width: 16 height: 9
If not locking the cropping to a specific ratio, a set of predefined ratios can be chosen by the user. Elements can be
added or removed from this list underneath
crop.aspectRatio.options. If the aspect ratio of the original image
shall be added to the list,
crop.aspectRatio.enableOriginal must be set to
TRUE. If the user should be allowed
to choose a custom aspect ratio, set
'teaserImage' type: 'TYPO3\Media\Domain\Model\ImageInterface' ui: label: 'Teaser Image' inspector: group: 'document' editorOptions: crop: aspectRatio: options: square: width: 1 height: 1 label: 'Square' fourFive: width: 4 height: 5 # disable this ratio (if it was defined in a supertype) fiveSeven: ~ enableOriginal: TRUE allowCustom: TRUE
- Set the maximum allowed file size to be uploaded. Accepts numeric or formatted string values, e.g. “204800” or “204800b” or “2kb”. Defaults to the maximum allowed upload size configured in php.ini
crop-related options. Only relevant if
Locks the aspect ratio to a specific width/height ratio
- width of the aspect ratio which shall be enforced
- height of the aspect ratio which shall be enforced
aspect-ratio presets. Only effective if
lockedis not set.
- the width of the aspect ratio preset
- the height of the aspect ratio preset
- a human-readable name of the aspect ratio preset
TRUE, the image ratio of the original image can be chosen in the selector. Only effective if
lockedis not set. Default
TRUE, a completely custom image ratio can be chosen. Only effective if
lockedis not set. Default
- default aspect ratio option to be chosen if no cropping has been applied already.
Property Type: asset (TYPO3\Media\Domain\Model\Asset / array<TYPO3\Media\Domain\Model\Asset>)
AssetEditor – File Selection Editor¶
If an asset, i.e.
TYPO3\Media\Domain\Model\Asset, shall be uploaded or selected, the following configuration
is an example:
'caseStudyPdf' type: 'TYPO3\Media\Domain\Model\Asset' ui: label: 'Case Study PDF' inspector: group: 'document'
Conversely, if multiple assets shall be uploaded, use
array<TYPO3\Media\Domain\Model\Asset> as type:
'caseStudies' type: 'array<TYPO3\Media\Domain\Model\Asset>' ui: label: 'Case Study PDF' inspector: group: 'document'
The validators that can be assigned to properties in the node type configuration are used on properties
that are edited via the inspector and are applied on the client-side only. The available validators can
be found in the Neos package in
The options are in sync with the Flow validators, so feel free to check the Flow documentation for details.
To apply options, just specify them like this:
someProperty: validation: 'TYPO3.Neos/Validation/StringLengthValidator': minimum: 1 maximum: 255
http://requirejs.org) and by this custom validators into Neos. Validators should be named ‘<SomeType>Validator’,
and can be referenced by
My.Package/Public/Scripts/Validators/FooValidator for example.
Namespaces can be registered like this in Settings.yaml:
TYPO3: Neos: userInterface: requireJsPathMapping: 'My.Package/Validation': 'resource://My.Package/Public/Scripts/Validators'
Registering specific validators is also possible like this:
TYPO3: Neos: userInterface: validators: 'My.Package/AlphanumericValidator': path: 'resource://My.Package/Public/Scripts/Validators/FooValidator'
Like with validators, using custom editors is possible as well. Every dataType has it’s default editor set, which can have options applied like:
TYPO3: Neos: userInterface: inspector: dataTypes: 'string': editor: 'TYPO3.Neos/Editors/TextFieldEditor' editorOptions: placeholder: 'This is a placeholder'
On a property level this can be overridden like:
TYPO3: Neos: userInterface: inspector: properties: 'string': editor: 'My.Package/Editors/TextFieldEditor' editorOptions: placeholder: 'This is my custom placeholder'
Namespaces can be registered like this, as with validators:
TYPO3: Neos: userInterface: requireJsPathMapping: 'My.Package/Editors': 'resource://My.Package/Public/Scripts/Inspector/Editors'
Editors should be named <SomeType>Editor and can be referenced by My.Package/Inspector/Editors/MyCustomEditor for example.
Registering specific editors is also possible like this:
Predefined Node Types¶
Neos is shipped with a number of node types. It is helpful to know some of them, as they can be useful elements to extend, and Neos depends on some of them for proper behavior.
There are a few core node types which are needed by Neos; these are shipped in
directly. All other node types such as Text, Image, ... are shipped inside the
TYPO3.Neos:Node is a (more or less internal) base type which should be extended by
all content types which are used in the context of Neos.
It does not define any properties.
An important distinction is between nodes which look and behave like pages and “normal content” such as text, which is rendered inside a page. Nodes which behave like pages are called Document Nodes in Neos. This means they have a unique, externally visible URL by which they can be rendered.
The standard page in Neos is implemented by
TYPO3.Neos.NodeTypes:Page which directly extends from
TYPO3.Neos:ContentCollection and TYPO3.Neos:Content¶
All content which does not behave like pages, but which lives inside them, is implemented by two different node types:
First, there is the
TYPO3.Neos:ContentCollection type: A
TYPO3.Neos:ContentCollection has a structural purpose.
It usually does not contain any properties itself, but it contains an ordered list of child
nodes which are rendered inside.
TYPO3.Neos:ContentCollection should not be extended by custom types.
Second, the node type for all standard elements (such as text, image, youtube,
TYPO3.Neos:Content. This is–by far–the most often extended node type.