For coders TYPO3 Tech Corner

Title und Metatags über Fluid in TYPO3 setzen

Title und Metatags über Fluid in TYPO3 setzen

Wie man Metatags, Title oder anderen Code im Head-Bereich der Frontendausgabe direkt über PHP setzen kann, haben wir schon in einem anderen Blogbeitrag beschrieben. Wir gehen hier aber noch einen Schritt weiter und wollen diese Tags künftig direkt im Fluid setzen.

Oldschool - über TypoScript

Tags im Head Bereich des HTML über TypoScript: Viele von euch kennen diesen Weg sicherlich bereits. Das sah dann so oder so ähnlich aus:

config.noPageTitle = 1 page.headerData { 10 = TEXT 10 { wrap3 = <title>|</title> noTrimWrap = ||: company - any claim| data = page:title } 20 = TEXT 20.value ( <link rel="apple-touch-icon" sizes="180x180" href="/typo3conf/ ext/in2template/Resources/Public/apple.png"> ) 30 = TEXT 30.value ( <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/rss.html"> ) }

Modern - direkt in Fluid in einer HTML Datei

Wir wollen künftig diese Art von Tags aber direkt im HTML pflegbar machen. Das ist nicht nur intuitiver, sondern auch einfacher zu nutzen, wenn Assets spätestens in TYPO3 12 nicht mehr über "/typo3conf/ext/" aufrufbar sind sondern im "vendor" Verzeichnis liegen.

Hierzu können wir ein Partial direkt im Page Template einbinden, das sich um alle Header Daten kümmert:

<in2template:meta.title> {data.title} - company claim </in2template:meta.title> <in2template:meta.addHeaderData> <link rel="stylesheet" sizes="180x180" href="{f:uri.resource(path:'Css/basic.css',extensionName:'In2template')}"> <link rel="apple-touch-icon" sizes="180x180" href="{f:uri.resource(path:'Favicons/apple-touch-icon.png',extensionName:'In2template')}"> <link rel="shortcut icon" href="{f:uri.resource(path:'Favicons/favicon.ico',extensionName:'In2template')}"> <meta name="msapplication-config" content="{f:uri.resource(path:'Favicons/browserconfig.xml',extensionName:'In2template')}"> <meta name="theme-color" content="#a5c85a"> <link rel="alternate" type="application/rss+xml" title="RSS Feed von in2code - Wir leben TYPO3" href="/rss.html"> <style> :root { --in2-modal-brand-color: #a5c85a; } </style> <script>var requireJsBasePath="{f:uri.resource(path:'JavaScripts/',extensionName:'In2template')}"</script> </in2template:meta.addHeaderData> <in2template:meta.addFooterData> <script async="" data-main="{f:uri.resource(path:'JavaScripts/',extensionName:'In2template')}main" src="{f:uri.resource(path:'JavaScripts/',extensionName:'In2template')}Vendor/require.js"></script> </in2template:meta.addFooterData>

Damit das funktioniert, benötigt es aber noch drei ViewHelper (und eine kleine TitleProvider Konfiguration). In allen folgenden Beispielen heißt unsere Sitepackage-Extension "in2template". Wo die Dateien liegen, könnt ihr über den Namespace herauslesen.

AddHeaderDataViewHelper um irgendwelche Tags in den Head-Bereich zu schreiben:

<?php declare(strict_types=1); namespace In2code\In2template\ViewHelpers\Meta; use Closure; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; class AddHeaderDataViewHelper extends AbstractViewHelper { /** * @param array $arguments * @param Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return void */ public static function renderStatic( array $arguments, Closure $renderChildrenClosure, RenderingContextInterface $renderingContext ) { $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); $pageRenderer->addHeaderData(self::removeWhitespaceBetweenTags($renderChildrenClosure())); } protected static function removeWhitespaceBetweenTags(string $html): string { return preg_replace('~\>\s+\<~m', '><', $html); } }

AddFooterDataViewHelper um irgendwelche Tags als letztes innerhalb des Body-Tags zu schreiben:

<?php declare(strict_types=1); namespace In2code\In2template\ViewHelpers\Meta; use Closure; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; class AddFooterDataViewHelper extends AbstractViewHelper { /** * @param array $arguments * @param Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return void */ public static function renderStatic( array $arguments, Closure $renderChildrenClosure, RenderingContextInterface $renderingContext ) { $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class); $pageRenderer->addFooterData(self::removeWhitespaceBetweenTags($renderChildrenClosure())); } protected static function removeWhitespaceBetweenTags(string $html): string { return preg_replace('~\>\s+\<~m', '><', $html); } }

Der TitleViewHelper hilft uns einen Title zu setzen:

<?php declare(strict_types=1); namespace In2code\In2template\ViewHelpers\Meta; use Closure; use In2code\In2template\PageTitle\Provider; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; class TitleViewHelper extends AbstractViewHelper { public function initializeArguments() { parent::initializeArguments(); $this->registerArgument('title', 'string', 'Any title for title tag', false); } /** * @param array $arguments * @param Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * @return void */ public static function renderStatic( array $arguments, Closure $renderChildrenClosure, RenderingContextInterface $renderingContext ) { $title = $arguments['title'] ?? $renderChildrenClosure(); $titleProvider = GeneralUtility::makeInstance(Provider::class); $titleProvider->setTitle(trim($title)); } }

Dafür muss ein TitleProvider über TypoScript (setup) registriert werden:

config.pageTitleProviders { page { provider = In2code\In2template\PageTitle\Provider after = seo,news before = record,altPageTitle } }

Und der Provider selber besteht lediglich aus einem Setter:

<?php declare(strict_types = 1); namespace In2code\In2template\PageTitle; use TYPO3\CMS\Core\PageTitle\AbstractPageTitleProvider; class Provider extends AbstractPageTitleProvider { public function setTitle(string $title): void { $this->title = $title; } }

Hinweise:

1) Wir haben in diesem Beispiel - wie so oft - ein paar Dinge weg gelassen, die ihr vermutlich sowieso schon kennt (Namespace Deklaration in FLUID der ViewHelper, Die Variable {data} in FLUID mit allen Werten pages.*, etc...)

2) Achtet darauf, dass ihr "config.noPageTitle" nicht gesetzt habt, wenn ihr den page title über einen Provider setzen wollt

3) Wenn ihr den Postfix eures Titles nicht haben wollt, solltet Ihr in der SiteConfiguration den Wert "websiteTitle" einfach leer lassen

Wir wünschen euch Happy TYPO3 Coding

Zurück

Kennst du das: Immer nur schnell schnell?

Wie wäre es einmal mit Zeit und Respekt für Codequalität? Arbeiten im Team? Automatisierte Tests?

Komm zu uns