Die Entwickler des CMS haben sich daher viele Gedanken über das Thema gemacht und dieses Feature „Routing“ nun auch in den Core von TYPO3 integriert – nachdem andere CMS hier bereits nutzerfreundlicher aufgestellt waren. Man kann zwar schon über den Pagetree für einfache Seiten sogennante Slugs defninieren oder ganze URL-Pfadsegmente ändern, aber bei Erweiterungen hörten hier die Möglichkeiten schon auf.
Wie funktioniert das neue Routing?
Man hat inzwischen die Möglichkeit einen oder meherere Ausgangspunkte in einem Seitenbaum zu definieren. Wichtig ist, dass man eine „Seiten-Konfiguration“ über das TYPO3 Backend anlegt über welches man das Wurzelverzeichnis (die Rootpage) definiert.
TYPO3 Backend > SITE MANAGEMENT > Sites:
+ Add new site Configuration
==> eine conig.yaml wird automatisch generiert
Man vergibt über die Site-Configuration einen sogenannten „Site-Identifier“, ein eindeutiges Schlüsselwort, unter dessen Namen nun eine Konfigurationsdatei (config.yml) generiert wird. Innerhalb dieser .yml lassen sich die grundlegenden Regeln für alle gewünschten Routes konfigurieren. Weiterhin kann man einen Entry-Point definieren. Dieser kann z.B. die vollständige Domain beinhalten (https://www.example.com) oder komplett relativ mit „/“ definiert werden. Dazu lassen sich verschiedenste zusätzliche Domain-Varianten definieren. Das war bisher auch möglich, allerdings passiert dies unter TYPO3 9.5 gebündelt in einem Konfigurationsbereich.
Mithilfe der sogenannten Routing Enhancer lassen sich nun Regeln für jede Form von GET-Parametern, die im Projekt auftreten werden, festlegen und das Seiten-Routing somit flexibel für jede Extension erweitern. Um Routing Enhancer zu definieren fügt man in seiner config.yml einen Abschnitt „routeEnhancers“ hinzu.
Routing Enhancer
Enhancer werden zweckgebunden in verschiedenen Typen zur Verfügung gestellt. Außerdem lassen sich damit zusätzliche Platzhalter in Seitenpfaden ergänzen.
Folgende Enhancer-Typen können definiert werden:
- Simple Enhancer (type "Simple")
- PageType Enhancer (type „PageType“)
- Plugin Enhancer (type "Plugin")
- Extbase Plugin Enhancer (type "Extbase")
Es ist möglich, dieselben Enhancer mehrfach mit unterschiedlichen Konfigurationen zu verwenden, allerdings lassen sie sich nicht miteinander kombinieren.
Enhancer liefern die Gesamtstruktur und die Segmente einer URL und die Details, wie ein Segment aussehen wird, wird imittels der "Aspekten" definiert.
Simple Enhancer
Der Simple Enhancer arbeitet mit verschiedenen Routenargumenten, um sie einem Argument zuzuordnen, das später verwendet werden soll. Die routeEnhancers werden auf der Root-Ebene der Konfiguration definiert. Dabei erhält jeder Enhancer eine eindeutige Bezeichnung (hier CatListing) und dann wird festgelegt um welchen Typ es sich handelt. Hier type: Simple. Der routePath definiert, wie die URL letzten Endes aussehen soll. Über defaults definiert man die Werte, die auch optional wegfallen können und requirements schränk jene Werte der verwendeten Variablen nach bestimmten RegEx-Regelements ein.
routeEnhancers:
# eindeutiger Name für die Enhancer, der intern für
# die Referenzierung verwendet wird
CatListing:
type: Simple
limitToPages: [5]
routePath: '/show-by-category/{cat_id}/{tag}'
defaults:
tag: ''
requirements:
cat_id: '[0-9]{1..3}'
tag: '^[a-zA-Z0-9].*$'
PageType Enhancer
Weiterhin lässt sich mittels eines PageTypeSuffixEnhancern festlegen, welcher Seitentyp einen Suffix erhalten soll. Das gilt Beispielweise für Dateiendungen, RSS-Feeds, JSON-Files, etc. Hiermit werden die Suffixe der URL auf die in den TypoScript-Einstellungen definierten typeNum-Werte abgebildet.
routeEnhancers:
PageTypeSuffix:
type: PageType
default: '.html'
index: 'index'
map:
'rss.feed': 13
'.json': 26
Plugin Enhancer
Der PluginEnhancer wurde für die Unterstützung der Plugins aus der pi-Based-Ära zur Verfügung gestellt, bei denen URL-Pfade in dieser Form entstanden sind:
/page-1/sub-page?tx_felogin_pi1[forgot]=1&&tx_felogin_pi1[user]=123&tx_felogin_pi1[hash]=ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
aus dieser wird:
/page-1/sub-page/frontend-login/123/ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
routeEnhancers:
FrontendLogin:
type: Plugin
# pageid of sub-page
limitToPages: [13]
routePath: '/frontend-login/{user}/{hash}'
namespace: 'tx_felogin_pi1'
defaults:
forgot: "1"
requirements:
user: '[0-9]{1..3}'
hash: '^[a-zA-Z0-9]{32}$'
Hier dient der namespace zur Deklaration des betreffendes Plugins (im Beispiel tx_felogin_pi1)
Extbase Plugin Enhancer
Bei diesem Enhancer werden explizit Extbase-Extensions angesprochen und verarbeitet.
routeEnhancers:
NewsPlugin:
type: Extbase
limitToPages: [13]
extension: News
plugin: Pi1
routes:
# News-Listenansicht
- { routePath: '/list/{page}', _controller: 'News::list', _arguments: {'page': '@widget_0/currentPage'} }
# Tags/Listenansicht
- { routePath: '/tag/{tag_name}', _controller: 'News::list', _arguments: {'tag_name': 'overwriteDemand/tags'}}
# News-Detailansicht
- { routePath: '/blog/{news_title}', _controller: 'News::detail', _arguments: {'news_title': 'news'} }
# News-Archiv
- { routePath: '/archive/{year}/{month}', _controller: 'News::archive' }
defaultController: 'News::list'
defaults:
page: '0'
requirements:
page: '\d+'
Hier wird mit 3 neuen Argumenten (extension, plugin und routes) gearbeitet, wobei man extension und plugin wie im vorherigen Enhancer durch namespace zusammenfassen kann. Unter routes lassen sich nun verschiedene actions einer Extension ansprechen. Dabei wird der gewünschte Pfad definiert, die angesprochene Controller-Action genannt und alle notwendigen Argumente definiert um ein eindeutige URL zu generieren. Sollte der Request ergebnislos bleiben, gibt’s einen Fallback auf den definierten defaultController.
Ausgangs-URL:
index.php?id=13&tx_news_pi1[controller]=News&tx_news_pi1[action]=detail&tx_news_pi1[news]=13
Speaking URL:
/path-to/my-page/detail/13
Benutzerdefinierte Enhancers
Es besteht auch die Möglichkeit benutzerdefinierte Enhancer zu erstellen. Damit lassen sich auch individuelle / komplexere Anwendungsfälle überwinden, wenn beispielsweise zwei Plugins gleichnamige Parameter nutzen.
Benutzerdefinierte Enhancer werden in der ext_localconf.php registriert:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['CustomPlugin'] = \MyVendor\MyPackage\Routing\CustomEnhancer::class;
Aspekte
Auf bestimmte Enhancer lassen sich auch Aspekte registrieren, um einen bestimmten Platzhalter (z.B. nummerische Werte) innerhalb des Pfades zu ändern bzw. verschönern – seien es statisch generierte oder dynamische Platzhalter. Es sind die sogenannten Aliase. Je nach Anwendungsfall werden diese auch als Mapper oder Modifier bezeichnet werden.
Man registriert Aspekte innerhalb einer Routing-Enhancer-Konfiguration mittels option aspects und kann diese dann mit jedem beliebigen Enhancer verwenden.
StaticValueMapper
Dieser Mapper ersetzt Werte einfach auf einer 1:1-Mapping-Liste eines Arguments in ein sprechendes Segment. Im Beispiel werden im Auszug Sprachsegmente für die verfügbaren Monate zu erstellt
(...)
aspects:
month:
type: StaticValueMapper
map:
january: 1
february: 2
(...)
(...)
LocaleModifier
Dieser Modifier bietet die Möglichkeit in mehrsprachigen Umgebungen Platzhalter je Sprache und Seitenübersetzung auszuspielen. Im Beispiel wird das News-Pfadsegment /archive/ für französisch und deutsch definiert:
(...)
aspects:
localized_archive:
type: LocaleModifier
default: 'archive'
localeMap:
- locale: 'fr_FR.*|fr_CA.*'
value: 'archives'
- locale: 'de_DE.*'
value: 'archiv'
(...)
StaticRageMapper
Dieser Mapper ermöglicht es, den cHash in einer URL zu vermeiden, die verfügbaren Möglichkeiten für einen Platzhalter einzuschränken und explizit einen Bereich für einen Wert zu definieren, der für alle Arten von Paginierungsfunktionalitäten empfohlen wird. Im Beispiel wird der Seitenumbruch auf max. 20 Seiten begrenzt. Ab Seite 21 würde der Platzhalter nicht mehr greifen.
(...)
aspects:
page:
type: StaticRangeMapper
start: '1'
end: '20'
(...)
PersistedAliasMapper
Der PersistedAliasMapper ordnet eine UID einem bestimmten Feld innerhalb dieses Datensatzes zu (i. d. R. dem Slug-Feld, ehemals bekannt als das Feld "sprechende URL-Pfadsegment").
(...)
aspects:
news_title:
type: PersistedAliasMapper
tableName: 'tx_news_domain_model_news'
routeFieldName: 'path_segment'
routeValuePrefix: '/'
(...)
PersistedPatternMapper
Dieser Aspekt erstellt den sprechenden URL-Pfad abhängig von mehreren Feldern aus einem Datenbankeintrag. Dies ist nützlich, wenn ein verwendetes Feld möglicherweise nicht eindeutig ist. Das Hinzufügen der UID zur sprechenden URL macht diese einzigartig.
(...)
aspects:
blogpost:
type: PersistedPatternMapper
tableName: 'tx_blogexample_domain_model_post'
routeFieldPattern: '^(?P<title>.+)-(?P<uid>\d+)$'
routeFieldResult: '{title}-{uid}'
(...)
Detailliertere Infos zum Thema erfahrt ihr der TYPO3 Dokumentation der auch ein Großteil der Beispiele entnommen sind.