diff --git a/framework/core/src/Extend/Frontend.php b/framework/core/src/Extend/Frontend.php index ac35255fb..f44d2ee43 100644 --- a/framework/core/src/Extend/Frontend.php +++ b/framework/core/src/Extend/Frontend.php @@ -35,6 +35,7 @@ class Frontend implements ExtenderInterface private $removedRoutes = []; private $content = []; private $preloadArrs = []; + private $titleDriver; /** * @param string $frontend: The name of the frontend. @@ -159,12 +160,23 @@ class Frontend implements ExtenderInterface return $this; } + /** + * Register a new title driver to change the title of frontend documents. + */ + public function title(string $driverClass): self + { + $this->titleDriver = $driverClass; + + return $this; + } + public function extend(Container $container, Extension $extension = null) { $this->registerAssets($container, $this->getModuleName($extension)); $this->registerRoutes($container); $this->registerContent($container); $this->registerPreloads($container); + $this->registerTitleDriver($container); } private function registerAssets(Container $container, string $moduleName): void @@ -295,4 +307,13 @@ class Frontend implements ExtenderInterface { return $extension ? $extension->getId() : 'site-custom'; } + + private function registerTitleDriver(Container $container): void + { + if ($this->titleDriver) { + $container->extend('flarum.frontend.title_driver', function ($driver, Container $container) { + return $container->make($this->titleDriver); + }); + } + } } diff --git a/framework/core/src/Frontend/Document.php b/framework/core/src/Frontend/Document.php index d08ab658b..037e4a61e 100644 --- a/framework/core/src/Frontend/Document.php +++ b/framework/core/src/Frontend/Document.php @@ -9,6 +9,7 @@ namespace Flarum\Frontend; +use Flarum\Frontend\Driver\TitleDriverInterface; use Illuminate\Contracts\Support\Renderable; use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\View; @@ -159,10 +160,6 @@ class Document implements Renderable */ protected $request; - /** - * @param Factory $view - * @param array $forumApiDocument - */ public function __construct(Factory $view, array $forumApiDocument, Request $request) { $this->view = $view; @@ -202,9 +199,8 @@ class Document implements Renderable */ protected function makeTitle(): string { - $onHomePage = rtrim($this->request->getUri()->getPath(), '/') === ''; - - return ($this->title && ! $onHomePage ? $this->title.' - ' : '').Arr::get($this->forumApiDocument, 'data.attributes.title'); + // @todo v2.0 inject as dependency instead + return resolve(TitleDriverInterface::class)->makeTitle($this, $this->request, $this->forumApiDocument); } /** diff --git a/framework/core/src/Frontend/Driver/BasicTitleDriver.php b/framework/core/src/Frontend/Driver/BasicTitleDriver.php new file mode 100644 index 000000000..71cd8ec40 --- /dev/null +++ b/framework/core/src/Frontend/Driver/BasicTitleDriver.php @@ -0,0 +1,24 @@ +getUri()->getPath(), '/') === ''; + + return ($document->title && ! $onHomePage ? $document->title.' - ' : '').Arr::get($forumApiDocument, 'data.attributes.title'); + } +} diff --git a/framework/core/src/Frontend/Driver/TitleDriverInterface.php b/framework/core/src/Frontend/Driver/TitleDriverInterface.php new file mode 100644 index 000000000..14b5d4382 --- /dev/null +++ b/framework/core/src/Frontend/Driver/TitleDriverInterface.php @@ -0,0 +1,18 @@ +container->singleton(TitleDriverInterface::class, function (Container $container) { + return $container->make(BasicTitleDriver::class); + }); + + $this->container->alias(TitleDriverInterface::class, 'flarum.frontend.title_driver'); + $this->container->singleton('flarum.less.config', function (Container $container) { return [ 'config-primary-color' => [ diff --git a/framework/core/src/helpers.php b/framework/core/src/helpers.php index 8e219155d..9033587ca 100644 --- a/framework/core/src/helpers.php +++ b/framework/core/src/helpers.php @@ -15,9 +15,10 @@ if (! function_exists('resolve')) { /** * Resolve a service from the container. * - * @param string $name + * @template T + * @param class-string|string $name * @param array $parameters - * @return mixed + * @return T|mixed */ function resolve($name, $parameters = []) { diff --git a/framework/core/tests/integration/extenders/FrontendTitleTest.php b/framework/core/tests/integration/extenders/FrontendTitleTest.php new file mode 100644 index 000000000..c3410428b --- /dev/null +++ b/framework/core/tests/integration/extenders/FrontendTitleTest.php @@ -0,0 +1,74 @@ +prepareDatabase([ + 'users' => [ + $this->normalUser(), + ], + 'discussions' => [ + ['id' => 1, 'title' => 'Test Discussion', 'user_id' => 1, 'first_post_id' => 1] + ], + 'posts' => [ + ['id' => 1, 'discussion_id' => 1, 'user_id' => 2, 'type' => 'comment', 'content' => '

can i haz potat?

'], + ], + ]); + + $this->setting('forum_title', 'Flarum'); + } + + /** + * @test + */ + public function basic_title_driver_is_used_by_default() + { + $this->assertTitleEquals('Test Discussion - Flarum'); + } + + /** + * @test + */ + public function custom_title_driver_works_if_set() + { + $this->extend((new Frontend('forum'))->title(CustomTitleDriver::class)); + + $this->assertTitleEquals('CustomTitle'); + } + + private function assertTitleEquals(string $title): void + { + $response = $this->send($this->request('GET', '/d/1')); + + preg_match('/\(?[^<]+)\<\/title\>/m', $response->getBody()->getContents(), $matches); + + $this->assertEquals($title, $matches['title']); + } +} + +class CustomTitleDriver implements TitleDriverInterface +{ + public function makeTitle(Document $document, ServerRequestInterface $request, array $forumApiDocument): string + { + return 'CustomTitle'; + } +}