Soft references

Soft references are references to database elements, files, email addresses, URLs, etc. which are found inside of text fields.

For example, the tt_content.bodytext database field can contain soft references to pages, content elements and files. The page reference looks like this:

<a href="t3://page?uid=1">link to page 1</a>
Copied!

In contrast to this, the field pages.shortcut contains the page ID of a shortcut. This is a reference, but not a soft reference.

The soft reference parsers are used by the system to find these references and process them accordingly in import/export actions and copy operations. Also, the soft references are used by integrity checking functions. For example, when you try to delete a page, TYPO3 will warn you if there are incoming page links to this page.

All references, soft and ordinary ones, are written to the reference index (table sys_refindex).

You can define which soft reference parsers to use in the TCA field softref which is available for TCA column types text and input.

Default soft reference parsers

The \TYPO3\CMS\Core\DataHandling\SoftReference namespace contains generic parsers for the most well-known types, which are the default for most TYPO3 installations. This is the list of the pre-registered keys:

substitute
A full field value targeted for manual substitution (for import/export features).
notify
Just report, if a value is found, nothing more.
typolink
References to page ID, record or file in typolink format. The typolink soft reference parser can take an additional argument, which can be linklist (typolink['linklist']). In this case the links will be separated by commas.
typolink_tag
Same as typolink, but with an <a> tag encapsulating it.
ext_fileref
Relative file reference, prefixed EXT:[extkey]/ - for finding extension dependencies.
email
Email highlight.
url
URL highlights (with a scheme).

The default setup is found in EXT:core/Configuration/Services.yaml (GitHub):

Excerpt from EXT:core/Configuration/Services.yaml
services:
  # ... other configuration

  # Soft Reference Parsers
  TYPO3\CMS\Core\DataHandling\SoftReference\SubstituteSoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: substitute

  TYPO3\CMS\Core\DataHandling\SoftReference\NotifySoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: notify

  TYPO3\CMS\Core\DataHandling\SoftReference\TypolinkSoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: typolink

  TYPO3\CMS\Core\DataHandling\SoftReference\TypolinkTagSoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: typolink_tag

  TYPO3\CMS\Core\DataHandling\SoftReference\ExtensionPathSoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: ext_fileref

  TYPO3\CMS\Core\DataHandling\SoftReference\EmailSoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: email

  TYPO3\CMS\Core\DataHandling\SoftReference\UrlSoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: url
Copied!

Examples

For the tt_content.bodytext field of type text from the example above, the configuration looks like this:

Excerpt from EXT:frontend/Configuration/TCA/tt_content.php
<?php

$GLOBALS['TCA']['tt_content']['columns']['bodytext'] = [
    // ...
    'config' => [
        'type' => 'text',
        'softref' => 'typolink_tag,email[subst],url',
        // ...
    ],
    // ...
];
Copied!

This means, the parsers for the soft reference types typolink_tag, email and url will all be applied. The email soft reference parser receives the additional parameter subst.

The content could look like this:

<p><a href="t3://page?uid=96">Congratulations</a></p>
<p>To read more about <a href="https://example.org/some-cool-feature">this cool feature</a></p>
<p>Contact: email@example.org</p>
Copied!

The parsers will return an instance of \TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserResult containing information about the references contained in the string. This object has two properties: $content and $elements.

Property $content

<p><a href="{softref:424242}">Congratulations</a></p>
<p>To read more about <a href="{softref:78910}">this cool feature</a></p>
<p>Contact: {softref:123456}</p>
Copied!

This property contains the input content. Links to be substituted have been replaced by soft reference tokens.

For example: <p>Contact: {softref:123456}</p>

Tokens are strings like {softref:123456} which are placeholders for values extracted by a soft reference parser.

For each token there is an entry in $elements which has a subst key defining the tokenID and the tokenValue. See below.

Property $elements

[
    [
        'matchString' => '<a href="t3://page?uid=96">',
        'error' => 'There is a glitch in the universe, page 42 not found.',
        'subst' => [
            'type' => 'db',
            'tokenID' => '424242',
            'tokenValue' => 't3://page?uid=96',
            'recordRef' => 'pages:96',
        ]
    ],
    [
        'matchString' => '<a href="https://example.org/some-cool-feature">',
        'subst' => [
            'type' => 'string',
            'tokenID' => '78910',
            'tokenValue' => 'https://example.org/some-cool-feature',
        ]
    ],
    [
        'matchString' => 'email@example.org',
        'subst' => [
            'type' => 'string',
            'tokenID' => '123456',
            'tokenValue' => 'test@example.com',
        ]
    ]
]
Copied!

This property is an array of arrays, each with these keys:

  • matchString: The value of the match. This is only for informational purposes to show, what was found.
  • error: An error message can be set here, like "file not found" etc.
  • subst: exists on a successful match and defines the token from content

    • tokenID: The tokenID string corresponding to the token in output content, {softref:[tokenID]}. This is typically a md5 hash of a string uniquely defining the position of the element.
    • tokenValue: The value that the token substitutes in the text. If this value is inserted instead of the token, the content should match what was inputted originally.
    • type: the type of substitution. file is a relative file reference, db is a database record reference, string is a manually modified string content (email, external url, phone number)
    • relFileName: (for file type): Relative filename.
    • recordRef: (for db type): Reference to DB record on the form <table>:<uid>.

User-defined soft reference parsers

Soft reference parsers can be user-defined. They are set up by registering them in your Services.yaml file. This will load them via dependency injection:

EXT:my_extension/Configuration/Services.yaml
services:
  # Place here the default dependency injection configuration

  MyVendor\MyExtension\SoftReference\YourSoftReferenceParser:
    tags:
      - name: softreference.parser
        parserKey: my_softref_key
Copied!

Read how to configure dependency injection in extensions.

Do not forget to clear the hard caches in Admin Tools > Maintenance or via the cache:flush CLI command after modifying the DI configuration.

The soft reference parser class registered there must implement EXT:core/DataHandling/SoftReference/SoftReferenceParserInterface.php (GitHub). This interface describes the parse method, which takes 5 parameters in total as arguments:

  • $table
  • $field
  • $uid
  • $content
  • $structurePath (optional)

The return type must be an instance of EXT:core/DataHandling/SoftReference/SoftReferenceParserResult.php (GitHub). This model possesses the properties $content and $elements and has appropriate getter methods for them. The structure of these properties has been described in the examples section. This result object should be created by its own factory method SoftReferenceParserResult::create(), which expects both above-mentioned arguments to be provided. If the result is empty, SoftReferenceParserResult::createWithoutMatches() should be used instead. If $elements is an empty array, this method will also be used internally.

Using the soft reference parser

To get an instance of a soft reference parser, it is recommended to use the \TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory class. This factory class already holds all registered instances of the parsers. They can be retrieved with the getSoftReferenceParser() method. You have to provide the desired key as the first and only argument.

EXT:my_extension/Classes/MyController.php
<?php

declare(strict_types=1);

use TYPO3\CMS\Core\DataHandling\SoftReference\SoftReferenceParserFactory;

final class MyController
{
    public function __construct(
        private readonly SoftReferenceParserFactory $softReferenceParserFactory,
    ) {}

    public function doSomething(): void
    {
        // Get the soft reference parser with the key "my_softref_key"
        $mySoftRefParser = $this->softReferenceParserFactory->getSoftReferenceParser(
            'my_softref_key',
        );

        // ... do something with $mySoftRefParser
    }
}
Copied!