mirror of
https://github.com/flarum/core.git
synced 2025-08-05 07:57:46 +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:
@@ -109,7 +109,7 @@ class AdminServiceProvider extends AbstractServiceProvider
|
|||||||
/** @var \Flarum\Frontend\Frontend $frontend */
|
/** @var \Flarum\Frontend\Frontend $frontend */
|
||||||
$frontend = $container->make('flarum.frontend.factory')('admin');
|
$frontend = $container->make('flarum.frontend.factory')('admin');
|
||||||
|
|
||||||
$frontend->content($container->make(Content\AdminPayload::class));
|
$frontend->content($container->make(Content\AdminPayload::class), 100);
|
||||||
|
|
||||||
return $frontend;
|
return $frontend;
|
||||||
});
|
});
|
||||||
|
@@ -132,12 +132,13 @@ class Frontend implements ExtenderInterface
|
|||||||
* - \Psr\Http\Message\ServerRequestInterface $request
|
* - \Psr\Http\Message\ServerRequestInterface $request
|
||||||
*
|
*
|
||||||
* The callable should return void.
|
* The callable should return void.
|
||||||
|
* @param int $priority: The priority of the content. Higher priorities are executed first.
|
||||||
*
|
*
|
||||||
* @return self
|
* @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;
|
return $this;
|
||||||
}
|
}
|
||||||
@@ -303,7 +304,7 @@ class Frontend implements ExtenderInterface
|
|||||||
"flarum.frontend.$this->frontend",
|
"flarum.frontend.$this->frontend",
|
||||||
function (ActualFrontend $frontend, Container $container) {
|
function (ActualFrontend $frontend, Container $container) {
|
||||||
foreach ($this->content as $content) {
|
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;
|
$preloads = is_callable($preloadArr) ? ContainerUtil::wrapCallback($preloadArr, $container)($document) : $preloadArr;
|
||||||
$document->preloads = array_merge($document->preloads, $preloads);
|
$document->preloads = array_merge($document->preloads, $preloads);
|
||||||
}
|
}
|
||||||
});
|
}, 110);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ use Flarum\Frontend\AddLocaleAssets;
|
|||||||
use Flarum\Frontend\AddTranslations;
|
use Flarum\Frontend\AddTranslations;
|
||||||
use Flarum\Frontend\Assets;
|
use Flarum\Frontend\Assets;
|
||||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||||
|
use Flarum\Frontend\Frontend;
|
||||||
use Flarum\Frontend\RecompileFrontendAssets;
|
use Flarum\Frontend\RecompileFrontendAssets;
|
||||||
use Flarum\Http\Middleware as HttpMiddleware;
|
use Flarum\Http\Middleware as HttpMiddleware;
|
||||||
use Flarum\Http\RouteCollection;
|
use Flarum\Http\RouteCollection;
|
||||||
@@ -127,8 +128,15 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||||||
return $assets;
|
return $assets;
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->container->bind('flarum.frontend.forum', function (Container $container) {
|
$this->container->bind('flarum.frontend.forum', function (Container $container, array $parameters = []) {
|
||||||
return $container->make('flarum.frontend.factory')('forum');
|
/** @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 () {
|
$this->container->singleton('flarum.forum.discussions.sortmap', function () {
|
||||||
|
@@ -17,7 +17,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
|
|||||||
class Frontend
|
class Frontend
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var callable[]
|
* @var array<array{callback: callable, priority: int}>
|
||||||
*/
|
*/
|
||||||
protected array $content = [];
|
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
|
public function document(Request $request): Document
|
||||||
@@ -45,8 +45,14 @@ class Frontend
|
|||||||
|
|
||||||
protected function populate(Document $document, Request $request): void
|
protected function populate(Document $document, Request $request): void
|
||||||
{
|
{
|
||||||
foreach ($this->content as $content) {
|
$content = $this->content;
|
||||||
$content($document, $request);
|
|
||||||
|
usort($content, function ($a, $b) {
|
||||||
|
return $b['priority'] <=> $a['priority'];
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach ($content as $item) {
|
||||||
|
$item['callback']($document, $request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -54,15 +54,16 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
|||||||
|
|
||||||
$this->container->singleton('flarum.frontend.factory', function (Container $container) {
|
$this->container->singleton('flarum.frontend.factory', function (Container $container) {
|
||||||
return function (string $name) use ($container) {
|
return function (string $name) use ($container) {
|
||||||
|
/** @var Frontend $frontend */
|
||||||
$frontend = $container->make(Frontend::class);
|
$frontend = $container->make(Frontend::class);
|
||||||
|
|
||||||
$frontend->content(function (Document $document) use ($name) {
|
$frontend->content(function (Document $document) use ($name) {
|
||||||
$document->layoutView = 'flarum::frontend.'.$name;
|
$document->layoutView = 'flarum::frontend.'.$name;
|
||||||
});
|
}, 200);
|
||||||
|
|
||||||
$frontend->content($container->make(Content\Assets::class)->forFrontend($name));
|
$frontend->content($container->make(Content\Assets::class)->forFrontend($name), 190);
|
||||||
$frontend->content($container->make(Content\CorePayload::class));
|
$frontend->content($container->make(Content\CorePayload::class), 180);
|
||||||
$frontend->content($container->make(Content\Meta::class));
|
$frontend->content($container->make(Content\Meta::class), 170);
|
||||||
|
|
||||||
$frontend->content(function (Document $document) use ($container) {
|
$frontend->content(function (Document $document) use ($container) {
|
||||||
$default_preloads = $container->make('flarum.frontend.default_preloads');
|
$default_preloads = $container->make('flarum.frontend.default_preloads');
|
||||||
@@ -90,7 +91,7 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
|||||||
$default_preloads,
|
$default_preloads,
|
||||||
$document->preloads,
|
$document->preloads,
|
||||||
);
|
);
|
||||||
});
|
}, 160);
|
||||||
|
|
||||||
return $frontend;
|
return $frontend;
|
||||||
};
|
};
|
||||||
|
@@ -40,11 +40,7 @@ class RouteHandlerFactory
|
|||||||
public function toFrontend(string $frontend, callable|string|null $content = null): Closure
|
public function toFrontend(string $frontend, callable|string|null $content = null): Closure
|
||||||
{
|
{
|
||||||
return $this->toController(function (Container $container) use ($frontend, $content) {
|
return $this->toController(function (Container $container) use ($frontend, $content) {
|
||||||
$frontend = $container->make("flarum.frontend.$frontend");
|
$frontend = $container->make("flarum.frontend.$frontend", compact('content'));
|
||||||
|
|
||||||
if ($content) {
|
|
||||||
$frontend->content(is_callable($content) ? $content : $container->make($content));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FrontendController($frontend);
|
return new FrontendController($frontend);
|
||||||
});
|
});
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user