Record objects 

Record objects are instances of \TYPO3\CMS\Core\Domain\Record .

They are an advanced data object holding the data of a database row, taking the TCA definition and possible relations of that database row into account.

Provide records in TypoScript 

In TypoScript you can use the RecordTransformationProcessor, usually in combination with the DatabaseQueryProcessor to pass record objects to the Fluid templating engine.

Provide records in PHP 

In PHP a record object can be created by the \TYPO3\CMS\Core\Domain\RecordFactory .

The event RecordCreationEvent can be used to influence or replace the Record object and its properties during creation.

Use records in Fluid 

In frontend templates the record object is provided by TypoScript or passed to Fluid by a PHP class.

Content element preview templates automatically receive a record object representing the record of the content element that should currently be displayed.

The f:debug ViewHelper output of the Record object is misleading for integrators, as most properties are accessed differently as one would assume.

We are dealing with an object here. You however can access your record properties as you are used to with {record.title} or {record.uid} . In addition, you gain special, context-aware properties like the language {record.languageId} or workspace {data.versionInfo.workspaceId} .

Overview of all possibilities:

Demonstration of available variables in Fluid
<!-- Any property, which is available in the Record (like normal) -->
{record.title}
{record.uid}
{record.pid}

<!-- Language related properties -->
{record.languageId}
{record.languageInfo.translationParent}
{record.languageInfo.translationSource}

<!-- The overlaid uid -->
{record.overlaidUid}

<!-- Types are a combination of the table name and the Content Type name. -->
<!-- Example for table "tt_content" and CType "textpic": -->

<!-- "tt_content" (this is basically the table name) -->
{record.mainType}

<!-- "textpic" (this is the CType) -->
{record.recordType}

<!-- "tt_content.textpic" (Combination of mainType and record type, separated by a dot) -->
{record.fullType}

<!-- System related properties -->
{record.systemProperties.isDeleted}
{record.systemProperties.isDisabled}
{record.systemProperties.isLockedForEditing}
{record.systemProperties.createdAt}
{record.systemProperties.lastUpdatedAt}
{record.systemProperties.publishAt}
{record.systemProperties.publishUntil}
{record.systemProperties.userGroupRestriction}
{record.systemProperties.sorting}
{record.systemProperties.description}

<!-- Computed properties depending on the request context -->
{record.computedProperties.versionedUid}
{record.computedProperties.localizedUid}
{record.computedProperties.requestedOverlayLanguageId}
{record.computedProperties.translationSource} <!-- Only for pages, contains the Page model -->

<!-- Workspace related properties -->
{record.versionInfo.workspaceId}
{record.versionInfo.liveId}
{record.versionInfo.state.name}
{record.versionInfo.state.value}
{record.versionInfo.stageId}
Copied!

Using the raw record 

The RecordFactory object contains only the properties, relevant for the current record type, for example CType. In case you need to access properties, which are not defined for the record type, the "raw" record can be used by accessing it via {record.rawRecord} . Those properties are not transformed.

Field values a record object resolves from TCA 

A record object does not contain the raw database value of a field. The RecordFactory reads the TCA type of each field of the current record type. It then replaces the raw value with the data that this type describes.

A field of the relation types category, group, inline or select with a foreign_table contains the related records as record objects. A field of TCA type file contains \TYPO3\CMS\Core\Resource\FileReference objects. A field of TCA type folder contains \TYPO3\CMS\Core\Resource\Folder objects, including all subfolders.

TYPO3 resolves a relation when a template reads the field for the first time. It sends no database query for a field that no template reads. When TYPO3 resolves a field of one record, it also resolves this field of all records that it fetched together with this record.

TYPO3 converts the other field types as well:

  • A field of TCA type datetime contains a \DateTimeImmutable object. An empty nullable field contains NULL.
  • A field of TCA type json contains the decoded JSON value.
  • A field of TCA type link contains a \TYPO3\CMS\Core\LinkHandling\TypolinkParameter object. This object provides the parts of the link, for example the URL and the target.
  • A field of TCA type country contains a \TYPO3\CMS\Core\Country\Country object.
  • A field of TCA type flex contains the values of the FlexForm. TYPO3 resolves these values by the same rules and addresses them by sheet and field name.
  • A field of TCA type select without a foreign_table contains an array of the selected values. A field with renderType = selectSingle contains the single value.

Cardinality of a relation in a record object 

A relation field contains a collection of records, even when it allows one record only. Set the TCA option relationship to declare the cardinality. A field with the value oneToOne or manyToOne contains the related record itself. It contains NULL when TYPO3 cannot resolve the relation.

The option takes the values oneToOne, manyToOne, oneToMany and manyToMany. The TCA reference describes it for TCA type category in the relationship option.

The option maxitems does not declare a cardinality. A field without relationship contains a collection, even when maxitems allows one record only.

packages/my_extension/Configuration/TCA/tx_myextension_domain_model_item.php
<?php

declare(strict_types=1);

return [
  'ctrl' => [
    // ...
  ],
  'columns' => [
    // ...
    'author' => [
      'label' => 'Author',
      'config' => [
        'type' => 'select',
        'renderType' => 'selectSingle',
        'foreign_table' => 'tx_myextension_domain_model_author',
        // {item.author} contains one record instead of a collection
        'relationship' => 'manyToOne',
      ],
    ],
  ],
];
Copied!

Use the resolved relations of a record object in Fluid 

packages/my_extension/Resources/Private/Templates/Preview/Item.html
<!-- A relation without "relationship" contains a collection of records -->
<f:for each="{record.categories}" as="category">
  <span>{category.title}</span>
</f:for>

<!-- With "relationship" set to "manyToOne" the field contains one record -->
<h2>{record.author.title}</h2>

<!-- A field of TCA type "file" contains file references -->
<f:for each="{record.image}" as="image">
  <f:image image="{image}" width="400" />
</f:for>

<!-- A field of TCA type "datetime" contains a \DateTimeImmutable object -->
<f:format.date format="d.m.Y">{record.publish_date}</f:format.date>
Copied!