Extending Routing
The TYPO3 Routing is extendable by design, so you can write both custom aspects as well as custom enhancers.
- You should write a custom enhancer if you need to manipulate how the full route looks like and gets resolved.
- You should write a custom aspect if you want to manipulate how a single route parameter ("variable") gets mapped and resolved.
Writing custom aspects
Custom aspects can either be modifiers or mappers. A modifier provides static modifications to a route path based on a given context (for example "language"). A mapper provides a mapping table (either a static table or one with dynamic values from the database).
All aspects derive from the interface \TYPO3\
.
To write a custom modifier, your aspect has to
extend \TYPO3\
and implement the modify
method
(see \TYPO3\
as example).
To write a custom mapper, your aspect should either implement \TYPO3\
or \TYPO3\
, depending on whether you have a static or dynamic mapping table.
The latter interface is used for mappers that need more expensive - for example database related - queries as execution is deferred to improve performance.
All mappers need to implement the methods generate
and resolve
. The first one is used on URL generation, the second one on URL resolution.
After implementing the matching interface, your aspect needs to be registered in ext_
:
<?php
declare(strict_types=1);
use MyVendor\MyExtension\Routing\Aspect\MyCustomMapper;
defined('TYPO3') or die();
$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['aspects']['MyCustomMapperNameAsUsedInYamlConfig'] =
MyCustomMapper::class;
It can now be used in the routing configuration as type
. The example above could be used as type: My
.
If your aspect is language aware, it should additionally implement Site
with the methods set
and get
. set
will automatically be called with the current site language object.
Impact
Routing aspects respecting the site language are now using the Site
in addition
to the Site
. The Aspect
check has been adjusted to check for the interface
_or_ the trait. If you are currently using the trait, you should implement the interface as well.
Writing custom enhancers
Enhancers can be either decorators or routing enhancers providing variants for a page.
- To write a custom decorator your enhancer should implement the
\TYPO3\
.CMS\ Core\ Routing\ Enhancer\ Decorating Enhancer Interface - To write a custom route enhancer your enhancer should implement both
\TYPO3\
andCMS\ Core\ Routing\ Enhancer\ Routing Enhancer Interface \TYPO3\
CMS\ Core\ Routing\ Enhancer\ Resulting Interface
The interfaces contain methods you need to implement as well as a description of what the methods are supposed to do. Please take a look there.
To register the enhancer, add the following to your ext_
:
<?php
declare(strict_types=1);
use MyVendor\MyExtension\Routing\Enhancer\MyCustomEnhancer;
defined('TYPO3') or die();
$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['enhancers']['MyCustomEnhancerAsUsedInYaml']
= MyCustomEnhancer::class;
Now you can use your new enhancer in the routing configuration as type
. The
example above could be used as type: My
.
Manipulating generated slugs
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';
in EXT:
, where $tableName can be a table like pages
and
$field
matches the slug field name, e.g. slug
.
$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.
Any extension can modify a specific slug, for instance only for a specific part of the page tree.
It is also possible for extensions to implement custom functionality like "Do not include in slug generation" as known from RealURL.