1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 15:37:51 +02:00

feat: frontend content flexible order priorities (#3765)

* Fix frontend factory so it includes controller content
* chore: more readable parameter passing
* feat: add priorities to frontend content
This commit is contained in:
Gary Green
2023-10-29 11:59:48 +00:00
committed by GitHub
parent 577fc3e6a8
commit 7c885c72fd
7 changed files with 123 additions and 22 deletions

View File

@@ -109,7 +109,7 @@ class AdminServiceProvider extends AbstractServiceProvider
/** @var \Flarum\Frontend\Frontend $frontend */
$frontend = $container->make('flarum.frontend.factory')('admin');
$frontend->content($container->make(Content\AdminPayload::class));
$frontend->content($container->make(Content\AdminPayload::class), 100);
return $frontend;
});

View File

@@ -132,12 +132,13 @@ class Frontend implements ExtenderInterface
* - \Psr\Http\Message\ServerRequestInterface $request
*
* The callable should return void.
* @param int $priority: The priority of the content. Higher priorities are executed first.
*
* @return self
*/
public function content(callable|string|null $callback): self
public function content(callable|string|null $callback, int $priority = 0): self
{
$this->content[] = $callback;
$this->content[] = compact('callback', 'priority');
return $this;
}
@@ -303,7 +304,7 @@ class Frontend implements ExtenderInterface
"flarum.frontend.$this->frontend",
function (ActualFrontend $frontend, Container $container) {
foreach ($this->content as $content) {
$frontend->content(ContainerUtil::wrapCallback($content, $container));
$frontend->content(ContainerUtil::wrapCallback($content['callback'], $container), $content['priority']);
}
}
);
@@ -323,7 +324,7 @@ class Frontend implements ExtenderInterface
$preloads = is_callable($preloadArr) ? ContainerUtil::wrapCallback($preloadArr, $container)($document) : $preloadArr;
$document->preloads = array_merge($document->preloads, $preloads);
}
});
}, 110);
}
);
}

View File

@@ -22,6 +22,7 @@ use Flarum\Frontend\AddLocaleAssets;
use Flarum\Frontend\AddTranslations;
use Flarum\Frontend\Assets;
use Flarum\Frontend\Compiler\Source\SourceCollector;
use Flarum\Frontend\Frontend;
use Flarum\Frontend\RecompileFrontendAssets;
use Flarum\Http\Middleware as HttpMiddleware;
use Flarum\Http\RouteCollection;
@@ -127,8 +128,15 @@ class ForumServiceProvider extends AbstractServiceProvider
return $assets;
});
$this->container->bind('flarum.frontend.forum', function (Container $container) {
return $container->make('flarum.frontend.factory')('forum');
$this->container->bind('flarum.frontend.forum', function (Container $container, array $parameters = []) {
/** @var Frontend $frontend */
$frontend = $container->make('flarum.frontend.factory')('forum');
if (isset($parameters['content'])) {
$frontend->content(is_callable($parameters['content']) ? $parameters['content'] : $container->make($parameters['content']), 100);
}
return $frontend;
});
$this->container->singleton('flarum.forum.discussions.sortmap', function () {

View File

@@ -17,7 +17,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
class Frontend
{
/**
* @var callable[]
* @var array<array{callback: callable, priority: int}>
*/
protected array $content = [];
@@ -27,9 +27,9 @@ class Frontend
) {
}
public function content(callable $content): void
public function content(callable $callback, int $priority): void
{
$this->content[] = $content;
$this->content[] = compact('callback', 'priority');
}
public function document(Request $request): Document
@@ -45,8 +45,14 @@ class Frontend
protected function populate(Document $document, Request $request): void
{
foreach ($this->content as $content) {
$content($document, $request);
$content = $this->content;
usort($content, function ($a, $b) {
return $b['priority'] <=> $a['priority'];
});
foreach ($content as $item) {
$item['callback']($document, $request);
}
}

View File

@@ -54,15 +54,16 @@ class FrontendServiceProvider extends AbstractServiceProvider
$this->container->singleton('flarum.frontend.factory', function (Container $container) {
return function (string $name) use ($container) {
/** @var Frontend $frontend */
$frontend = $container->make(Frontend::class);
$frontend->content(function (Document $document) use ($name) {
$document->layoutView = 'flarum::frontend.'.$name;
});
}, 200);
$frontend->content($container->make(Content\Assets::class)->forFrontend($name));
$frontend->content($container->make(Content\CorePayload::class));
$frontend->content($container->make(Content\Meta::class));
$frontend->content($container->make(Content\Assets::class)->forFrontend($name), 190);
$frontend->content($container->make(Content\CorePayload::class), 180);
$frontend->content($container->make(Content\Meta::class), 170);
$frontend->content(function (Document $document) use ($container) {
$default_preloads = $container->make('flarum.frontend.default_preloads');
@@ -90,7 +91,7 @@ class FrontendServiceProvider extends AbstractServiceProvider
$default_preloads,
$document->preloads,
);
});
}, 160);
return $frontend;
};

View File

@@ -40,11 +40,7 @@ class RouteHandlerFactory
public function toFrontend(string $frontend, callable|string|null $content = null): Closure
{
return $this->toController(function (Container $container) use ($frontend, $content) {
$frontend = $container->make("flarum.frontend.$frontend");
if ($content) {
$frontend->content(is_callable($content) ? $content : $container->make($content));
}
$frontend = $container->make("flarum.frontend.$frontend", compact('content'));
return new FrontendController($frontend);
});

View File

@@ -0,0 +1,89 @@
<?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\Testing\integration\RetrievesAuthorizedUsers;
use Flarum\Testing\integration\TestCase;
class FrontendContentTest extends TestCase
{
use RetrievesAuthorizedUsers;
/**
* @test
*/
public function content_added_with_low_priority_by_default()
{
$title = null;
$this->extend(
(new Frontend('forum'))
->content(function (Document $document) use (&$title) {
$title = $document->title;
}),
);
$body = $this->send(
$this->request('GET', '/')
)->getBody()->getContents();
$this->assertNotNull($title, $body);
}
/**
* @test
*/
public function content_can_be_added_with_high_priority()
{
$title = 1;
$this->extend(
(new Frontend('forum'))
->content(function (Document $document) use (&$title) {
$title = $document->title;
}, 110),
);
$body = $this->send(
$this->request('GET', '/')
)->getBody()->getContents();
$this->assertNull($title, $body);
}
/**
* @test
*/
public function contents_can_be_added_with_different_priorities()
{
$test = [];
$this->extend(
(new Frontend('forum'))
->content(function (Document $document) use (&$test) {
$test[] = 1;
}, 110)
->content(function (Document $document) use (&$test) {
$test[] = 3;
}, 90)
->content(function (Document $document) use (&$test) {
$test[] = 2;
}, 100),
);
$body = $this->send(
$this->request('GET', '/')
)->getBody()->getContents();
$this->assertEquals([1, 2, 3], $test, $body);
}
}