<?php
/**
* Reprezentace Latte tagu k zobrazení Nette flash zpráv
*
* Použití: {flashMessages} nebo {flashMessages $flashes}
*/
class FlashMessagesNode extends \Latte\Compiler\Nodes\AreaNode
{ // AreaNode reprezentuje v Latte 3 obecný tag, který se zobrazuje v šabloně
public static function create(\Latte\Compiler\Tag $tag): self
{
$flashes = NULL;
if ($tag->parser->isEnd()) {
$flashes = $tag->parser->parseUnquotedStringOrExpression();
} // Definujeme nepovinný argument tagu a uložíme jeho hodnotu
return new self($flashes);
}
public function __construct(
public ?\Latte\Compiler\Nodes\Php\ExpressionNode $flashes = NULL,
)
{
}
public function print(\Latte\Compiler\PrintContext $context): string
{
return $context->format(
'echo $this->global->%raw->render(%node);',
FlashMessagesExtension::FLASH_MESSAGES_RENDERER,
$this->flashes ?? new \Latte\Compiler\Nodes\Php\Expression\VariableNode('flashes'),
);
}
public function &getIterator(): \Generator
{
// Důležitá funkce, kterou musí každý tag s obsahem implementovat.
// Umožňuje dále ve stromu nahrazovat tagy za jiné.
if ($this->flashes !== NULL) {
yield $this->flashes;
}
}
}
final class FlashMessagesRenderer
{
public function __construct(
private \Nette\Localization\Translator $translator,
)
{
}
public function render(?array $flashes): ?\Nette\Utils\Html
{
if ($flashes === NULL || $flashes === []) {
return NULL;
}
$container = \Nette\Utils\Html::el();
foreach ($flashes as $flash) {
$el = \Nette\Utils\Html::el('p');
$el->class(\sprintf('message message--%s', $flash->type));
if ($flash->message instanceof \Nette\Utils\Html) {
$el->addHtml($flash->message);
} else {
$message = $this->translator->translate($flash->message);
$el->addHtml(\Nette\Utils\Html::el('span')->addText($message));
}
$container->addHtml($el);
}
return $container;
}
}
class FlashMessagesExtension extends \Latte\Extension
{ // Latte rozšíření pro registraci našeho vlastního tagu
public const FLASH_MESSAGES_RENDERER = 'flashMessagesRenderer';
public function __construct(
private readonly FlashMessagesRenderer $flashMessagesRenderer,
)
{
}
public function getProviders(): array
{
return [
self::FLASH_MESSAGES_RENDERER => $this->flashMessagesRenderer,
];
}
public function getTags(): array
{
return [
'flashMessages' => FlashMessagesNode::create(...),
];
}
}