feat: allow replacing of blade template namespaces via extender (#3167)

* feat: allow replacing of blade template namespaces

* wip: add `prependNamespace` support

* test: add replace namespace test

* Apply fixes from StyleCI

[ci skip] [skip ci]

* fix: add missing property

* test: add prepend test

* fix: add view namespaces before resolving

Allows `replaceNamespace()` extender to actually remove old routes.

* test: make replace test ensure that replaced view does not exist

* docs: update docblock

* Apply fixes from StyleCI

[ci skip] [skip ci]

* fix: missing `\` before class

* fix: change test view namespace

* chore: simplify test

* Remove replace namespace code

We only really need prepend.

* chore: rename extender

* ci: add override test

* Apply fixes from StyleCI

[ci skip] [skip ci]

* fix(tests): add `trim` call

* revert: 3d46ead14b

Co-authored-by: luceos <luceos@users.noreply.github.com>
This commit is contained in:
David Wheatley 2021-12-20 09:56:48 +01:00 committed by GitHub
parent c8febb6199
commit fbaf936e7e
3 changed files with 59 additions and 3 deletions

View File

@ -14,20 +14,24 @@ use Flarum\Foundation\Paths;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\View\Factory;
/**
* Views are PHP files that use the Laravel Blade syntax for creation of server-side generated HTML.
*
* Flarum's core uses them for error pages, the installer, HTML emails, and the skeletons for the forum and admin sites.
*/
class View implements ExtenderInterface, LifecycleInterface
{
private $namespaces = [];
private $prependNamespaces = [];
/**
* Register a new namespace of Laravel views.
*
* Views are php files that use the Laravel Blade syntax for creation of server-side generated html.
* Flarum core uses them for error pages, the installer, HTML emails, and the skeletons for the forum and admin sites.
* To create and use views in your extension, you will need to put them in a folder, and register that folder as a namespace.
*
* Views can then be used in your extension by injecting an instance of `Illuminate\Contracts\View\Factory`,
* and calling its `make` method. The `make` method takes the view parameter in the format NAMESPACE::VIEW_NAME.
* You can also pass variables into a view: for more information, see https://laravel.com/api/8.x/Illuminate/View/Factory.html#method_make
* You can also pass variables into a view. For more information, see: https://laravel.com/api/8.x/Illuminate/View/Factory.html#method_make
*
* @param string $namespace: The name of the namespace.
* @param string|string[] $hints: This is a path (or an array of paths) to the folder(s)
@ -41,12 +45,33 @@ class View implements ExtenderInterface, LifecycleInterface
return $this;
}
/**
* Extend an existing namespace of Laravel views.
*
* To extend an existing namespace, you will need to put views in a folder in your extension,
* and register that folder under the existing namespace with this extender.
*
* @param string $namespace: The name of the namespace.
* @param string|string[] $hints: This is a path (or an array of paths) to the folder(s)
* where view files are stored, relative to the extend.php file.
* @return self
*/
public function extendNamespace(string $namespace, $hints): self
{
$this->prependNamespaces[$namespace] = $hints;
return $this;
}
public function extend(Container $container, Extension $extension = null)
{
$container->resolving(Factory::class, function (Factory $view) {
foreach ($this->namespaces as $namespace => $hints) {
$view->addNamespace($namespace, $hints);
}
foreach ($this->prependNamespaces as $namespace => $hints) {
$view->prependNamespace($namespace, $hints);
}
});
}

View File

@ -0,0 +1 @@
<html><body>We have overridden the core app view.</body></html>

View File

@ -36,4 +36,34 @@ class ViewTest extends TestCase
$this->assertEquals('<html><body>Hello World!</body></html>', trim($this->app()->getContainer()->make(Factory::class)->make('integration.test::test')->render()));
}
/**
* @test
*/
public function can_add_view_to_namespace_by_prepend_extender()
{
$this->extend(
(new Extend\View)
->extendNamespace('flarum', dirname(__FILE__, 3).'/fixtures/views')
);
$this->assertEquals('<html><body>Hello World!</body></html>', trim($this->app()->getContainer()->make(Factory::class)->make('flarum::test')->render()));
}
/**
* @test
*/
public function can_override_view_in_namespace_by_prepend_extender()
{
$this->extend(
(new Extend\View)
->extendNamespace('flarum', dirname(__FILE__, 3).'/fixtures/views/override')
);
$response = $this->send(
$this->request('GET', '/')
);
$this->assertEquals('<html><body>We have overridden the core app view.</body></html>', trim($response->getBody()->getContents()));
}
}