From 1d3c28f2282c0f1926679e6bbafb3b7dcd791989 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Wed, 29 Nov 2023 10:52:57 +0100 Subject: [PATCH] Provide Page Titles (#46) That way it is possible to alter the TYPO3 page title when showing a date or event. Relates: #10640 --- Classes/Domain/Model/Event.php | 2 +- .../DateMetaInformationService.php | 6 ++- .../EventMetaInformationService.php | 6 ++- .../PageTitleProvider/DateTitleProvider.php | 48 +++++++++++++++++++ .../DateTitleProviderInterface.php | 33 +++++++++++++ .../PageTitleProvider/EventTitleProvider.php | 45 +++++++++++++++++ .../EventTitleProviderInterface.php | 33 +++++++++++++ Documentation/Changelog/4.0.0.rst | 3 ++ Documentation/Features/PageTitle.rst | 15 ++++++ Tests/Functional/Frontend/DatesTest.php | 16 +++++++ .../DatesTestFixtures/DatePageTitle.php | 32 +++++++++++++ Tests/Functional/Frontend/EventsTest.php | 16 +++++++ .../EventsTestFixtures/EventPageTitle.php | 23 +++++++++ .../Fixtures/TypoScript/Rendering.typoscript | 13 +++++ 14 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 Classes/Frontend/PageTitleProvider/DateTitleProvider.php create mode 100644 Classes/Frontend/PageTitleProvider/DateTitleProviderInterface.php create mode 100644 Classes/Frontend/PageTitleProvider/EventTitleProvider.php create mode 100644 Classes/Frontend/PageTitleProvider/EventTitleProviderInterface.php create mode 100644 Documentation/Features/PageTitle.rst create mode 100644 Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php create mode 100644 Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php diff --git a/Classes/Domain/Model/Event.php b/Classes/Domain/Model/Event.php index b1b7743..7c742cf 100644 --- a/Classes/Domain/Model/Event.php +++ b/Classes/Domain/Model/Event.php @@ -70,7 +70,7 @@ class Event extends AbstractEntity */ protected ObjectStorage $features; - protected string $keywords; + protected string $keywords = ''; /** * @var ObjectStorage diff --git a/Classes/Frontend/MetaInformation/DateMetaInformationService.php b/Classes/Frontend/MetaInformation/DateMetaInformationService.php index dc4c1e1..613c046 100644 --- a/Classes/Frontend/MetaInformation/DateMetaInformationService.php +++ b/Classes/Frontend/MetaInformation/DateMetaInformationService.php @@ -25,6 +25,7 @@ namespace WerkraumMedia\Events\Frontend\MetaInformation; use TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry; use WerkraumMedia\Events\Domain\Model\Date; +use WerkraumMedia\Events\Frontend\PageTitleProvider\DateTitleProviderInterface; /** * TYPO3 has many different APIs to set meta information like: Page Title, Meta Tags, OpenGraph Tags, etc. @@ -34,7 +35,8 @@ use WerkraumMedia\Events\Domain\Model\Date; final class DateMetaInformationService implements DateMetaInformationInterface { public function __construct( - private readonly MetaTagManagerRegistry $metaTagManagerRegistry + private readonly MetaTagManagerRegistry $metaTagManagerRegistry, + private readonly DateTitleProviderInterface $titleProvider ) { } @@ -42,6 +44,8 @@ final class DateMetaInformationService implements DateMetaInformationInterface { $this->setDescription($date); $this->setKeywords($date); + + $this->titleProvider->setDate($date); } private function setDescription(Date $date): void diff --git a/Classes/Frontend/MetaInformation/EventMetaInformationService.php b/Classes/Frontend/MetaInformation/EventMetaInformationService.php index 6982433..b908e40 100644 --- a/Classes/Frontend/MetaInformation/EventMetaInformationService.php +++ b/Classes/Frontend/MetaInformation/EventMetaInformationService.php @@ -25,6 +25,7 @@ namespace WerkraumMedia\Events\Frontend\MetaInformation; use TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry; use WerkraumMedia\Events\Domain\Model\Event; +use WerkraumMedia\Events\Frontend\PageTitleProvider\EventTitleProviderInterface; /** * TYPO3 has many different APIs to set meta information like: Page Title, Meta Tags, OpenGraph Tags, etc. @@ -34,7 +35,8 @@ use WerkraumMedia\Events\Domain\Model\Event; final class EventMetaInformationService implements EventMetaInformationInterface { public function __construct( - private readonly MetaTagManagerRegistry $metaTagManagerRegistry + private readonly MetaTagManagerRegistry $metaTagManagerRegistry, + private readonly EventTitleProviderInterface $titleProvider ) { } @@ -42,6 +44,8 @@ final class EventMetaInformationService implements EventMetaInformationInterface { $this->setDescription($event); $this->setKeywords($event); + + $this->titleProvider->setEvent($event); } private function setDescription(Event $event): void diff --git a/Classes/Frontend/PageTitleProvider/DateTitleProvider.php b/Classes/Frontend/PageTitleProvider/DateTitleProvider.php new file mode 100644 index 0000000..d711ff4 --- /dev/null +++ b/Classes/Frontend/PageTitleProvider/DateTitleProvider.php @@ -0,0 +1,48 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace WerkraumMedia\Events\Frontend\PageTitleProvider; + +use WerkraumMedia\Events\Domain\Model\Date; + +final class DateTitleProvider implements DateTitleProviderInterface +{ + private ?Date $date = null; + + public function setDate(Date $date): void + { + $this->date = $date; + } + + public function getTitle(): string + { + if ($this->date === null || $this->date->getEvent() === null) { + return ''; + } + + return implode(' ', [ + $this->date->getEvent()->getTitle(), + $this->date->getStart()->format('d.m.Y H:i'), + ]); + } +} diff --git a/Classes/Frontend/PageTitleProvider/DateTitleProviderInterface.php b/Classes/Frontend/PageTitleProvider/DateTitleProviderInterface.php new file mode 100644 index 0000000..1b71cb6 --- /dev/null +++ b/Classes/Frontend/PageTitleProvider/DateTitleProviderInterface.php @@ -0,0 +1,33 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace WerkraumMedia\Events\Frontend\PageTitleProvider; + +use TYPO3\CMS\Core\PageTitle\PageTitleProviderInterface; +use TYPO3\CMS\Core\SingletonInterface; +use WerkraumMedia\Events\Domain\Model\Date; + +interface DateTitleProviderInterface extends PageTitleProviderInterface, SingletonInterface +{ + public function setDate(Date $date): void; +} diff --git a/Classes/Frontend/PageTitleProvider/EventTitleProvider.php b/Classes/Frontend/PageTitleProvider/EventTitleProvider.php new file mode 100644 index 0000000..44bb2ce --- /dev/null +++ b/Classes/Frontend/PageTitleProvider/EventTitleProvider.php @@ -0,0 +1,45 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace WerkraumMedia\Events\Frontend\PageTitleProvider; + +use WerkraumMedia\Events\Domain\Model\Event; + +final class EventTitleProvider implements EventTitleProviderInterface +{ + private ?Event $event = null; + + public function setEvent(Event $event): void + { + $this->event = $event; + } + + public function getTitle(): string + { + if ($this->event === null) { + return ''; + } + + return $this->event->getTitle(); + } +} diff --git a/Classes/Frontend/PageTitleProvider/EventTitleProviderInterface.php b/Classes/Frontend/PageTitleProvider/EventTitleProviderInterface.php new file mode 100644 index 0000000..8d955d9 --- /dev/null +++ b/Classes/Frontend/PageTitleProvider/EventTitleProviderInterface.php @@ -0,0 +1,33 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace WerkraumMedia\Events\Frontend\PageTitleProvider; + +use TYPO3\CMS\Core\PageTitle\PageTitleProviderInterface; +use TYPO3\CMS\Core\SingletonInterface; +use WerkraumMedia\Events\Domain\Model\Event; + +interface EventTitleProviderInterface extends PageTitleProviderInterface, SingletonInterface +{ + public function setEvent(Event $event): void; +} diff --git a/Documentation/Changelog/4.0.0.rst b/Documentation/Changelog/4.0.0.rst index f7e4b0d..f1f3159 100644 --- a/Documentation/Changelog/4.0.0.rst +++ b/Documentation/Changelog/4.0.0.rst @@ -33,6 +33,9 @@ Features * Import keywords for events from destination.one. That way keywords are available for usage in meta tags. +* Add page title provider. + That way it is possible to alter the TYPO3 page title when showing a date or event. + Fixes ----- diff --git a/Documentation/Features/PageTitle.rst b/Documentation/Features/PageTitle.rst new file mode 100644 index 0000000..edbc6b3 --- /dev/null +++ b/Documentation/Features/PageTitle.rst @@ -0,0 +1,15 @@ +.. index:: single: page title +.. _pageTitle: + +Page Title +========== + +The extension comes with default implementations for PageTitleProvider. + +The default implementation can be exchanged by leveraging TYPO3 Dependency Injection. + +Further resources: + +* https://docs.typo3.org/m/typo3/reference-coreapi/12.4/en-us/ApiOverview/Seo/PageTitleApi.html + +* https://docs.typo3.org/m/typo3/reference-coreapi/12.4/en-us/ApiOverview/DependencyInjection/Index.html diff --git a/Tests/Functional/Frontend/DatesTest.php b/Tests/Functional/Frontend/DatesTest.php index b0c7ae1..da53c3e 100644 --- a/Tests/Functional/Frontend/DatesTest.php +++ b/Tests/Functional/Frontend/DatesTest.php @@ -204,4 +204,20 @@ class DatesTest extends AbstractFunctionalTestCase self::assertStringContainsString('', $html); self::assertStringContainsString('', $html); } + + #[Test] + public function altersPageTitle(): void + { + $this->importPHPDataSet(__DIR__ . '/DatesTestFixtures/DatePageTitle.php'); + + $request = new InternalRequest(); + $request = $request->withPageId(1); + $request = $request->withQueryParameter('tx_events_dateshow[date]', '1'); + $response = $this->executeFrontendSubRequest($request); + + self::assertSame(200, $response->getStatusCode()); + $html = (string)$response->getBody(); + + self::assertStringContainsString('Title of Event 15.02.2023 00:00', $html); + } } diff --git a/Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php b/Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php new file mode 100644 index 0000000..ce6fbfd --- /dev/null +++ b/Tests/Functional/Frontend/DatesTestFixtures/DatePageTitle.php @@ -0,0 +1,32 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '1', + 'CType' => 'list', + 'list_type' => 'events_dateshow', + 'header' => 'Singleview', + ], + ], + 'tx_events_domain_model_event' => [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'title' => 'Title of Event', + 'hidden' => '0', + ], + ], + 'tx_events_domain_model_date' => [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'event' => '1', + 'start' => '1676419200', + 'end' => '1676484000', + ], + ], +]; diff --git a/Tests/Functional/Frontend/EventsTest.php b/Tests/Functional/Frontend/EventsTest.php index 6e913f6..cd3ae8f 100644 --- a/Tests/Functional/Frontend/EventsTest.php +++ b/Tests/Functional/Frontend/EventsTest.php @@ -57,4 +57,20 @@ class EventsTest extends AbstractFunctionalTestCase self::assertStringContainsString('', $html); self::assertStringContainsString('', $html); } + + #[Test] + public function altersPageTitle(): void + { + $this->importPHPDataSet(__DIR__ . '/EventsTestFixtures/EventPageTitle.php'); + + $request = new InternalRequest(); + $request = $request->withPageId(1); + $request = $request->withQueryParameter('tx_events_eventshow[event]', '1'); + $response = $this->executeFrontendSubRequest($request); + + self::assertSame(200, $response->getStatusCode()); + $html = (string)$response->getBody(); + + self::assertStringContainsString('Title of Event', $html); + } } diff --git a/Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php b/Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php new file mode 100644 index 0000000..0d3ff66 --- /dev/null +++ b/Tests/Functional/Frontend/EventsTestFixtures/EventPageTitle.php @@ -0,0 +1,23 @@ + [ + 0 => [ + 'uid' => '1', + 'pid' => '1', + 'CType' => 'list', + 'list_type' => 'events_eventshow', + 'header' => 'Singleview', + ], + ], + 'tx_events_domain_model_event' => [ + 0 => [ + 'uid' => '1', + 'pid' => '2', + 'title' => 'Title of Event', + 'hidden' => '0', + ], + ], +]; diff --git a/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript b/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript index a8b7333..3201d00 100644 --- a/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript +++ b/Tests/Functional/Frontend/Fixtures/TypoScript/Rendering.typoscript @@ -38,3 +38,16 @@ plugin.tx_events { start = 1660158000 } } + +config { + pageTitleProviders { + date { + provider = WerkraumMedia\Events\Frontend\PageTitleProvider\DateTitleProvider + before = record + } + event { + provider = WerkraumMedia\Events\Frontend\PageTitleProvider\EventTitleProvider + before = record + } + } +}