Skip to content

Commit 8535055

Browse files
committed
added {linkBase}
1 parent 593c9bb commit 8535055

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed

src/Application/LinkGenerator.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,4 +294,12 @@ private function isDeprecated(?UI\Presenter $presenter, \ReflectionClass|\Reflec
294294
return $presenter?->invalidLinkMode
295295
&& (UI\ComponentReflection::parseAnnotation($reflection, 'deprecated') || $reflection->getAttributes(Attributes\Deprecated::class));
296296
}
297+
298+
299+
public static function applyBase(string $link, string $base): string
300+
{
301+
return str_contains($link, ':') && $link[0] !== ':'
302+
? ":$base:$link"
303+
: $link;
304+
}
297305
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Nette Framework (https://nette.org)
5+
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Nette\Bridges\ApplicationLatte\Nodes;
11+
12+
use Latte\CompileException;
13+
use Latte\Compiler\Node;
14+
use Latte\Compiler\NodeHelpers;
15+
use Latte\Compiler\Nodes\Php\Expression\AuxiliaryNode;
16+
use Latte\Compiler\Nodes\Php\ExpressionNode;
17+
use Latte\Compiler\Nodes\Php\Scalar\StringNode;
18+
use Latte\Compiler\Nodes\StatementNode;
19+
use Latte\Compiler\Nodes\TemplateNode;
20+
use Latte\Compiler\PrintContext;
21+
use Latte\Compiler\Tag;
22+
use Nette\Application\LinkGenerator;
23+
24+
25+
/**
26+
* {linkBase presenter}
27+
*/
28+
class LinkBaseNode extends StatementNode
29+
{
30+
public ExpressionNode $base;
31+
32+
33+
public static function create(Tag $tag): static
34+
{
35+
$tag->expectArguments();
36+
if (!$tag->isInHead()) {
37+
throw new CompileException("{{$tag->name}} must be placed in template head.", $tag->position);
38+
}
39+
40+
$node = new static;
41+
$node->base = $tag->parser->parseUnquotedStringOrExpression();
42+
return $node;
43+
}
44+
45+
46+
public function print(PrintContext $context): string
47+
{
48+
return '';
49+
}
50+
51+
52+
public function &getIterator(): \Generator
53+
{
54+
false && yield;
55+
}
56+
57+
58+
public static function applyLinkBasePass(TemplateNode $templateNode): void
59+
{
60+
$base = NodeHelpers::findFirst($templateNode, fn(Node $node) => $node instanceof LinkBaseNode)?->base;
61+
if ($base === null) {
62+
return;
63+
}
64+
65+
$linkNodes = NodeHelpers::find($templateNode, fn(Node $node) => $node instanceof LinkNode);
66+
foreach ($linkNodes as $linkNode) {
67+
if ($linkNode->destination instanceof StringNode && $base instanceof StringNode) {
68+
$linkNode->destination->value = LinkGenerator::applyBase($linkNode->destination->value, $base->value);
69+
} else {
70+
$origDestination = $linkNode->destination;
71+
$linkNode->destination = new AuxiliaryNode(
72+
fn(PrintContext $context) => $context->format(
73+
LinkGenerator::class . '::applyBase(%node, %node)',
74+
$origDestination,
75+
$base,
76+
),
77+
);
78+
}
79+
}
80+
}
81+
}

src/Bridges/ApplicationLatte/UIExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public function getTags(): array
7575
'control' => Nodes\ControlNode::create(...),
7676
'plink' => Nodes\LinkNode::create(...),
7777
'link' => Nodes\LinkNode::create(...),
78+
'linkBase' => Nodes\LinkBaseNode::create(...),
7879
'ifCurrent' => Nodes\IfCurrentNode::create(...),
7980
'templatePrint' => Nodes\TemplatePrintNode::create(...),
8081
'snippet' => Nodes\SnippetNode::create(...),
@@ -89,6 +90,7 @@ public function getPasses(): array
8990
{
9091
return [
9192
'snippetRendering' => $this->snippetRenderingPass(...),
93+
'applyLinkBase' => [Nodes\LinkBaseNode::class, 'applyLinkBasePass'],
9294
];
9395
}
9496

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/**
4+
* Test: {linkBase ...}
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Tester\Assert;
10+
11+
require __DIR__ . '/../bootstrap.php';
12+
13+
if (version_compare(Latte\Engine::VERSION, '3', '<')) {
14+
Tester\Environment::skip('Test for Latte 3');
15+
}
16+
17+
18+
$latte = new Latte\Engine;
19+
$latte->setLoader(new Latte\Loaders\StringLoader);
20+
$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(null));
21+
22+
23+
Assert::contains(
24+
'$this->global->uiControl->link(\'foo\')',
25+
$latte->compile('{linkBase Base}{link foo}'),
26+
);
27+
Assert::contains(
28+
'$this->global->uiControl->link(\':Base:Foo:\')',
29+
$latte->compile('{linkBase Base}{link Foo:}'),
30+
);
31+
Assert::contains(
32+
'$this->global->uiControl->link(\':Foo:\')',
33+
$latte->compile('{linkBase Base}{link :Foo:}'),
34+
);
35+
36+
37+
// dynamic
38+
Assert::contains(
39+
'$this->global->uiControl->link(Nette\Application\LinkGenerator::applyBase($link, \'Base\')))',
40+
$latte->compile('{linkBase Base}{link $link}'),
41+
);
42+
Assert::contains(
43+
'$this->global->uiControl->link(Nette\Application\LinkGenerator::applyBase(\'foo\', $base)))',
44+
$latte->compile('{linkBase $base}{link foo}'),
45+
);

0 commit comments

Comments
 (0)