Zum Inhalt springen

Einleitung

In RealURL gab es die Konfigurationen defaultToHTMLsuffixOnPrev und acceptHTMLsuffix, mit der man die gewünschte Endung der URL einstellen konnte. Auch mit dem in TYPO3 v9 hinzugefügten Routing-Feature sind beide Schreibweisen möglich. Hierfür gibt es den PageType Enhancer.

Der PageType Enhancer (auch: Decorator)

Mit dem PageType Enhancer lassen sich die verschiedenen typeNum einer TYPO3-Website umschreiben. Sein Ergebnis wird immer am Ende einer URL ergänzt.

Zur Erinnerung: PAGE Objekte in TYPO3 besitzen immer einen type. Mit der Eigenschaft typeNum wird dem jeweiligen PAGE Objekt eine ID (Integer) zugewiesen. Fehlt diese Angabe im TypoScript, wird der Defaultwert 0 verwendet. Im Frontend sind die konfigurierten Seitentypen mit dem Parameter &type=123 aufrufbar.

Dabei kann dieser Routing Enhancer nicht nur für Endungen wie / oder .html sorgen. In vielen TYPO3-Websites gibt es spezielle PAGE Objekte für RSS-Feeds oder eine Sitemap. Der PageType Enhancer kann diese auf Wunsch z.B. zu rss.xml oder sitemap.xml umschreiben.

Wichtig: Sobald der PageType Enhancer verwendet wird, muss für alle vorhandenen PAGE Objekte bzw. typeNum ein Mapping eingerichtet werden! Andernfalls kommt es zu Problemen beim Aufruf (siehe letzter Abschnitt).

Anfängliche Probleme mit dem neuen Routing

"Sprechende URLs" direkt über den TYPO3-Kern sind wahrscheinlich eines der größten Features, die TYPO3 in den letzten Jahren erhalten hat. Um es zu ermöglichen, waren einige Anpassungen im Kern notwendig. Naturgemäß gab es in den ersten Minor-Versionen von TYPO3 v9 noch ein paar Startschwierigkeiten, die inzwischen größtenteils behoben wurden.

Die folgenden YAML-Konfigurationen werden in der Site Configuration ergänzt. Falls dir dieser Begriff noch nichts sagen sollte, findest du im ersten Teil der Routing-Tutorialreihe das notwendige Rüstzeug.

Konfiguration für URLs mit Trailing Slash

In diesem ersten Beispiel habe ich eine vollständige config.yaml aufgeführt. In eurer Seite werden diese Angaben etwas abweichen. Der für das Routing relevante Teil ist hervorgehoben.

Die nachfolgende Konfiguration führt zu folgenden URLs:

  • Startseite (root-Ebene): mydomain.de
  • Unterseiten: mydomain.de/unterseite/
rootPageId: 7
base: 'https://mydomain.de/'
baseVariants:
  -
    base: 'http://mydomain.test/'
    condition: 'applicationContext == "Development"'
languages:
  -
    title: English
    enabled: true
    languageId: '0'
    base: /
    typo3Language: default
    locale: en_US.UTF-8
    iso-639-1: en
    navigationTitle: English
    hreflang: en-US
    direction: ''
    flag: en-us-gb
errorHandling: {  }
routes: {  }
routeEnhancers:
  PageTypeSuffix:
    type: PageType
    default: '/'
    index: ''
    map:
      '/': 0
      feed.xml: 9818
      sitemap.xml: 1533906435

Erläuterung der Routing-Eigenschaften, nach Zeile nummeriert

22) routeEnhancers:

Hier werden alle individuellen Konfigurationen für das Routing aufgeführt.

23) PageTypeSuffix:

Wie bei jedem konfigurierten Routing Enhancer ist dies ein frei wählbarer Name, der nur einmal vorkommen darf. Der Bezeichner PageTypeSuffix scheint sich aber als Standard etabliert zu haben.

24) type:

PageType ist der Bezeichner des PageType Enhancer.

25) default:

Hier wird eine Endung für alle Standard-Seiten festgelegt. default ist eine Pflichtangabe! Ohne diese Eigenschaft wird der gesamte Routing Enhancer nicht verwendet.

26) index:

Diese Eigenschaft enthält im Grunde das Equivalent des Slug-Feldes für die root-Ebene. Fehlt diese Eigenschaft, wird der Standardwert "index" verwendet. In unserer Konfiguration ersetzen wir diesen durch einen leeren String. Die Startseite (root-Seite) wird dann über https://www.example.org aufgerufen.

27) map:

Hier weisen wir jeder typeNum die gewünschte Endung zu. Um das zu verdeutlichen, habe ich noch zwei weitere typeNum ergänzt: für einen ggf. vorhandenen RSS-Feed unter type=9818 sowie der Sitemap von EXT:seo, die unter der typeNum 1533906435 erreichbar ist.

Konfiguration für URLs mit .html Suffix

Dieser Routing Enhancer generiert die folgenden URLs:

  • Startseite (root-Ebene): mydomain.de/index.html
  • Unterseiten: mydomain.de/unterseite.html
routeEnhancers:
  PageTypeSuffix:
    type: PageType
    default: '.html'
    index: 'index'
    map:
      '.html': 0

Die Startseite wird hier immer mit "index.html" aufgerufen. In vielen Fällen ist dies nicht gewünscht. Wer also das .html Suffix verwenden, die Startseite aber ohne jede Endung aufrufen will, benötigt aktuell (TYPO3 9.5.14) noch einen eigenen PageType Enhancer.

Eigener PageType Enhancer: "index.html" auf root-Seite vermeiden

Der TYPO3-Entwickler Daniel Dorndorf hat auf TYPO3 Forge netterweise einen eigenen PageType Enhancer bereitgestellt, der unser oben genanntes Problem umgehen wird.
Die folgende Lösung stammt also nicht von mir, ich habe lediglich die notwendige Registrierung dieses Routing Enhancers in TYPO3 ergänzt.

Um den eigenen Enhancer verwenden zu können, müsst ihr ihn in einer TYPO3-Extension bereitstellen. Dies kann auch eure Template-Extension ("Sitepackage") sein. Ihr benötigt zwei Dateien: zum einen die Datei mit der PHP-Klasse des Enhancers, zum anderen die ext_localconf.php zur Registrierung des neuen Routing Enhancers.

Dieser CustomPageTypeDecorator ermöglicht dann die Generierung der folgenden URLs:

  • Startseite (root-Ebene): mydomain.de
  • Unterseiten: mydomain.de/unterseite.html

/Classes/Routing/Enhancer/CustomPageTypeDecorator.php

<?php

namespace Brand\Extensionname\Routing\Enhancer;

use TYPO3\CMS\Core\Routing\Enhancer\PageTypeDecorator;
use TYPO3\CMS\Core\Routing\RouteCollection;

/**
 * Class CustomPageTypeDecorator
 */
class CustomPageTypeDecorator extends PageTypeDecorator
{
    public const IGNORE_INDEX = [
        '/index.html',
        '/index/',
    ];

    public const ROUTE_PATH_DELIMITERS = ['.', '-', '_', '/'];

    /**
     * @param \TYPO3\CMS\Core\Routing\RouteCollection $collection
     * @param array $parameters
     */
    public function decorateForGeneration(RouteCollection $collection, array $parameters): void
    {
        parent::decorateForGeneration($collection, $parameters);

        /**
         * @var string $routeName
         * @var \TYPO3\CMS\Core\Routing\Route $route
         */
        foreach ($collection->all() as $routeName => $route) {
            $path = $route->getPath();

            if (true === \in_array($path, self::IGNORE_INDEX, true)) {
                $route->setPath('/');
            }
        }
    }
}

ext_localconf.php

<?php
defined('TYPO3_MODE') or die();

// Register custom PageTypeDecorator:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['enhancers'] += ['CustomPageType' => \Brand\Extensionname\Routing\Enhancer\CustomPageTypeDecorator::class];

Den PHP Namespace \Brand\Extensionname\ könnt ihr natürlich anpassen (in beiden Dateien!).

config.yaml

routeEnhancers:
  PageTypeSuffix:
    type: CustomPageType
    default: '.html'
    index: 'index'
    map:
      '.html': 0

Beachtet hier vor allem den neuen type. Der index-Eintrag wird am Ende vom CustomPageTypeDecorator herausgefiltert.

Auch für die Einrichtung von Trailing Slashes könnte dieser eigene PageType Enhancer verwendet werden (wie das erste Beispiel). Und tatsächlich habe ich ihn in ersten Projekten mit TYPO3 v9 für diesen Zweck eingesetzt, als noch das Problem mit doppelten Slashes bestand.

Bei Verwendung des PageType Decorators wird das Mapping zur Pflicht!

Dieser Umstand kann schon einmal zu Problemen an unvermuteter Stelle führen:

  • Die "yoast_seo" Extension verwendet ein PAGE Objekt für die Snippet-Vorschau. Ohne das dazugehörige Mapping kann diese Vorschau nicht geladen werden.
  • Die SEO-Sitemap in TYPO3 v9 ist per Default unter mydomain.de/?type=1533906435 erreichbar. Ohne Mapping dieser typeNum ist zwar die Übersicht aller Sitemaps aufrufbar, der Link zur Pages-Sitemap ruft dann aber fälschlicherweise die Startseite auf.

Prüft also eure TYPO3-Installation auf konfigurierte PAGE Objekte, z.B. für eine JSON-View oder eine Printausgabe. Diese könnten auch durch installierte Extensions ergänzt worden sein.

Einige häufig verwendete typeNum:

    map:
      # EXT:news / RSS-Feed:
      feed.xml: 9818
      # EXT:seo / SEO-Sitemap:
      sitemap.xml: 1533906435
      # EXT:yoast_seo / Snippet-Vorschau:
      yoast-snippetpreview.json: 1480321830