-
-
Notifications
You must be signed in to change notification settings - Fork 109
/
TranslatorExtension.php
106 lines (85 loc) · 2.32 KB
/
TranslatorExtension.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<?php
/**
* This file is part of the Latte (https://latte.nette.org)
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Latte\Essential;
use Latte;
use Latte\Compiler\NodeHelpers;
use Latte\Compiler\Nodes\Php;
use Latte\Compiler\Tag;
use Latte\Engine;
use Latte\Essential\Nodes\PrintNode;
use Nette\Localization\Translator;
/**
* Extension for translations.
*/
final class TranslatorExtension extends Latte\Extension
{
/** @var callable|Translator|null */
private $translator;
public function __construct(
callable|Translator|null $translator,
private ?string $key = null,
) {
$this->translator = $translator;
if ($translator instanceof Translator) {
$this->translator = [$translator, 'translate'];
}
}
public function getTags(): array
{
return [
'_' => [$this, 'parseTranslate'],
'translate' => fn(Tag $tag) => yield from Nodes\TranslateNode::create($tag, $this->key ? $this->translator : null),
];
}
public function getFilters(): array
{
return [
'translate' => fn(Latte\Runtime\FilterInfo $fi, ...$args): string => $this->translator
? ($this->translator)(...$args)
: $args[0],
];
}
public function getCacheKey(Engine $engine): mixed
{
return $this->key;
}
/**
* {_ ...}
*/
public function parseTranslate(Tag $tag): PrintNode
{
$tag->outputMode = $tag::OutputKeepIndentation;
$tag->expectArguments();
$node = new PrintNode;
$node->expression = $tag->parser->parseUnquotedStringOrExpression();
$args = new Php\Expression\ArrayNode;
if ($tag->parser->stream->tryConsume(',')) {
$args = $tag->parser->parseArguments();
}
$node->modifier = $tag->parser->parseModifier();
$node->modifier->escape = true;
if ($this->translator
&& $this->key
&& ($expr = self::toValue($node->expression))
&& is_array($values = self::toValue($args))
&& is_string($translation = ($this->translator)($expr, ...$values))
) {
$node->expression = new Php\Scalar\StringNode($translation);
return $node;
}
array_unshift($node->modifier->filters, new Php\FilterNode(new Php\IdentifierNode('translate'), $args->toArguments()));
return $node;
}
public static function toValue($args): mixed
{
try {
return NodeHelpers::toValue($args, constants: true);
} catch (\InvalidArgumentException) {
return null;
}
}
}