feat: Use an extensible document title driver implementation (#3109)

* feat: Use an extensible document title driver implementation
* chore: Add todo to use DI in 2.0
This commit is contained in:
Sami Mazouz 2021-11-08 23:15:32 +01:00 committed by GitHub
parent d274adb0e4
commit 029e34bfd7
7 changed files with 151 additions and 9 deletions

View File

@ -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);
});
}
}
}

View File

@ -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);
}
/**

View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Frontend\Driver;
use Flarum\Frontend\Document;
use Illuminate\Support\Arr;
use Psr\Http\Message\ServerRequestInterface;
class BasicTitleDriver implements TitleDriverInterface
{
public function makeTitle(Document $document, ServerRequestInterface $request, array $forumApiDocument): string
{
$onHomePage = rtrim($request->getUri()->getPath(), '/') === '';
return ($document->title && ! $onHomePage ? $document->title.' - ' : '').Arr::get($forumApiDocument, 'data.attributes.title');
}
}

View File

@ -0,0 +1,18 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Frontend\Driver;
use Flarum\Frontend\Document;
use Psr\Http\Message\ServerRequestInterface;
interface TitleDriverInterface
{
public function makeTitle(Document $document, ServerRequestInterface $request, array $forumApiDocument): string;
}

View File

@ -12,6 +12,8 @@ namespace Flarum\Frontend;
use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Foundation\Paths;
use Flarum\Frontend\Compiler\Source\SourceCollector;
use Flarum\Frontend\Driver\BasicTitleDriver;
use Flarum\Frontend\Driver\TitleDriverInterface;
use Flarum\Http\UrlGenerator;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Container\Container;
@ -107,6 +109,12 @@ class FrontendServiceProvider extends AbstractServiceProvider
}
);
$this->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' => [

View File

@ -15,9 +15,10 @@ if (! function_exists('resolve')) {
/**
* Resolve a service from the container.
*
* @param string $name
* @template T
* @param class-string<T>|string $name
* @param array $parameters
* @return mixed
* @return T|mixed
*/
function resolve($name, $parameters = [])
{

View File

@ -0,0 +1,74 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Tests\integration\extenders;
use Flarum\Extend\Frontend;
use Flarum\Frontend\Document;
use Flarum\Frontend\Driver\TitleDriverInterface;
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
use Psr\Http\Message\ServerRequestInterface;
class FrontendTitleTest extends TestCase
{
use RetrievesAuthorizedUsers;
protected function setUp(): void
{
$this->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' => '<t><p>can i haz potat?</p></t>'],
],
]);
$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\>(?<title>[^<]+)\<\/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';
}
}