diff --git a/framework/core/src/Extend/View.php b/framework/core/src/Extend/View.php index 176eb021e..b40b41075 100644 --- a/framework/core/src/Extend/View.php +++ b/framework/core/src/Extend/View.php @@ -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); + } }); } diff --git a/framework/core/tests/fixtures/views/override/frontend/app.blade.php b/framework/core/tests/fixtures/views/override/frontend/app.blade.php new file mode 100644 index 000000000..7f29b7100 --- /dev/null +++ b/framework/core/tests/fixtures/views/override/frontend/app.blade.php @@ -0,0 +1 @@ +We have overridden the core app view. diff --git a/framework/core/tests/integration/extenders/ViewTest.php b/framework/core/tests/integration/extenders/ViewTest.php index f9c101eac..7eb87a274 100644 --- a/framework/core/tests/integration/extenders/ViewTest.php +++ b/framework/core/tests/integration/extenders/ViewTest.php @@ -36,4 +36,34 @@ class ViewTest extends TestCase $this->assertEquals('Hello World!', 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('Hello World!', 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('We have overridden the core app view.', trim($response->getBody()->getContents())); + } }