Attention

TYPO3 v10 has reached end-of-life as of April 30th 2023 and is no longer being maintained. Use the version switcher on the top left of this page to select documentation for a supported version of TYPO3.

Need more time before upgrading? You can purchase Extended Long Term Support (ELTS) for TYPO3 v10 here: TYPO3 ELTS.

type = 'slug'

Table of contents:

Introduction

The main purpose of this type is to define parts of a URL path to generate and resolve URLs.

With a URL like https://www.typo3.org/ch/community/values/core-values/ a URL slug is typically a part like /community or /community/values/core-values.

Within TYPO3, a slug is always part of the URL "path" - it does not contain scheme, host, HTTP verb, etc.

A slug is usually added to a TCA-based database table, containing some rules for evaluation and definition. A slug is a segment of a URL, but it is not limited to be separated by slashes. Therefore, a slug can contain slashes.

If a TCA table contains a field called "slug", it needs to be filled for every existing record. It can be shown and edited via regular Backend Forms, and is also evaluated during persistence via DataHandler.

The default behaviour of a slug is as follows:

  • A slug only contains characters which are allowed within URLs. Spaces, commas and other special characters are converted to a fallback character.

  • A slug is always lower-cased.

  • A slug is unicode-aware.

It is possible to build a default value from the rootline (very helpful for pages, or categorized slugs), but also to just generate a "speaking" segment from e.g. a news title.

Sanitation and Validation configuration options apply when persisting a record via DataHandler.

In the backend forms a validation happens by an AJAX call, which immediately checks any input and receives a new proposal in case the slug is already used.

Examples

'slug' => [
    'label' => '<path-to-locallang-file>.slug',
    'exclude' => 1,
    'config' => [
        'type' => 'slug',
        'generatorOptions' => [
            'fields' => ['title', 'nav_title'],
            'fieldSeparator' => '/',
            'prefixParentPageSlug' => true,
            'replacements' => [
                '/' => '',
            ],
        ],
        'appearance' => [
           'prefix' => \Vendor\Extension\UserFunctions\FormEngine\SlugPrefix::class . '->getPrefix'
        ],
        'fallbackCharacter' => '-',
        'eval' => 'uniqueInSite',
        'default' => ''
    ],
],

Properties

appearance

Datatype

array

Scope

Display

Description

Provides a custom base url that is displayed in front of the input field.

prefix

Assign a user function. It receives two arguments:

  • The first argument is the parameters array containing the site object, the language id, the current table and the current row.

  • The second argument is the reference object TcaSlug.

The user function should return the string which is then used as the base url.

Example:

<?php
declare(strict_types = 1);

namespace Vendor\Extension\UserFunctions\FormEngine

use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSlug;

class SlugPrefix
{
    public function getPrefix(array $parameters, TcaSlug $reference): string
    {
        return 'custom base url';
    }
}

eval

Datatype

string (list of keywords)

Scope

Proc. / Display

Description

Configuration of field evaluation. No other eval setting is checked for. It is possible to set multiple keywords, however it is recommended not to do so.

Keywords:

unique

Evaluate if a record is unique in the whole TYPO3 installation (specific to a language). This option is recommended as it allows to show any record stored inside other sites. The only downside is that it is not possible to have the same slug on multiple sites.

uniqueInSite

Requires the field to be unique for the current site and language. This allows for multiple records of the same table to have the same slug as long as these records are separated by their sites. Consequently records of a foreign site are not accessible with uniqueInsite since slugs are looked up respecting the current site.

Warning

Be aware that using this option makes it impossible to show records stored inside other sites. If this is required, unique should be used instead.

uniqueInPid

Requires the field to be unique for the current PID among other records on the same page.

fallbackCharacter

Datatype

string

Scope

Proc. / Display

Description

Character that represents the separator of slug sections, that contain the fieldSeparator.

generatorOptions

Datatype

array

Scope

Display

Description

Holds information about the record fields to be used for slug generation:

fields (array)

Insert several field names (of type string) that will be considered during slug construction.

Can also be used as nested array to combine multiple fields [['nav_title', 'title'], 'other_field'].

Info

Inserting multiple fields in a simple array would result in an concatenated slug.

Nested array values would result in "take nav_title if not empty, otherwise take value from title".

Examples:

Configuration value

Values of an example page record

Resulting slug

['nav_title', 'title']

['title' => 'Products', 'nav_title' => '', 'subtitle' => '']

/products

['nav_title', 'title']

['title' => 'Products', 'nav_title' => 'Best products', 'subtitle' => '']

/best-products/products

[['nav_title', 'title']]

['title' => 'Products', 'nav_title' => 'Best products', 'subtitle' => '']

/best-products

['subtitle', 'nav_title', 'title']

['title' => 'Products', 'nav_title' => 'Best products', 'subtitle' => 'Product subtitle']

/product-subtitle/best-products/products

[['nav_title', 'title'], 'subtitle']

['title' => 'Products', 'nav_title' => 'Best products', 'subtitle' => 'Product subtitle']

/best-products/product-subtitle

[['seo_title', 'title'], ['nav_title', 'subtitle']]

['title' => 'Products', 'nav_title' => 'Best products', 'subtitle' => 'Product subtitle', 'seo_title' => 'SEO product title']

/seo-product-title/best-products

fieldSeparator (string)

This value will divide the slug parts. If a section value contains this very value, it will be replaced by the value given in fallbackCharacter.

prefixParentPageSlug (boolean)

The slugs of parent pages will be prefixed to the slug for the page itself. Disable it for shorter URLs, but take the higher chance of collision into consideration.

replacements (array)

It allows to replace strings of a slug part. Add one of more array items with the key being the string to replace and the value being the replacement string.

Example:

'config' => [
    'type' => 'slug',
    'generatorOptions' => [
        'fields' => ['title'],
        'replacements' => [
            '(f/m)' => '',
            '/' => '-'
        ],
    ],
    'fallbackCharacter' => '-',
    'prependSlash' => true,
    'eval' => 'uniqueInPid',
],

This will change the provided slug 'Some Job in city1/city2 (f/m)' to 'some-job-in-city1-city2'.

postModifiers (array)

The "slug" TCA type includes a possibility to hook into the generation of a slug via custom TCA generation options. Hooks can be registered via:

$GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config']['generatorOptions']['postModifiers'][] = My\Class::class . '->method';

Consider $tableName = 'pages' and $fieldName = 'slug' inside EXT:myextension/Configuration/TCA/Overrides/table.php:

$GLOBALS['TCA']['pages']['columns']['slug']['config']['generatorOptions']['postModifiers'][] = \My\Class::class . '->modifySlug';

The method then receives an parameter array with the following values:

 [
     'slug' // ... the slug to be used
     'workspaceId' // ... the workspace ID, "0" if in live workspace
     'configuration' // ... the configuration of the TCA field
     'record' // ... the full record to be used
     'pid' // ... the resolved parent page ID
     'prefix' // ... the prefix that was added
     'tableName' // ... the table of the slug field
     'fieldName' // ... the field name of the slug field
];

All hooks need to return the modified slug value.

prependSlash

Datatype

boolean

Scope

Proc. / Display

Description

Defines whether a slug field should contain a prepending slash, e.g. for nested categories with speaking segments