• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / latte / 15809643126

22 Jun 2025 06:35PM UTC coverage: 93.67% (+0.09%) from 93.583%
15809643126

push

github

dg
added {include?} {import?} {embed?} {sandbox?}

34 of 36 new or added lines in 7 files covered. (94.44%)

164 existing lines in 43 files now uncovered.

5164 of 5513 relevant lines covered (93.67%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.11
/src/Latte/Essential/Nodes/EmbedNode.php
1
<?php
2

3
/**
4
 * This file is part of the Latte (https://latte.nette.org)
5
 * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Latte\Essential\Nodes;
11

12
use Latte\CompileException;
13
use Latte\Compiler\Nodes\FragmentNode;
14
use Latte\Compiler\Nodes\Php\Expression\ArrayNode;
15
use Latte\Compiler\Nodes\Php\ExpressionNode;
16
use Latte\Compiler\Nodes\Php\Scalar\StringNode;
17
use Latte\Compiler\Nodes\StatementNode;
18
use Latte\Compiler\Nodes\TextNode;
19
use Latte\Compiler\PrintContext;
20
use Latte\Compiler\Tag;
21
use Latte\Compiler\TemplateParser;
22
use function count, preg_match;
23

24

25
/**
26
 * {embed [block|file] name [,] [params]}
27
 */
28
class EmbedNode extends StatementNode
29
{
30
        public ExpressionNode $name;
31
        public string $mode;
32
        public ArrayNode $args;
33
        public FragmentNode $blocks;
34
        public int|string|null $layer;
35
        public bool $optional = false;
36

37

38
        /** @return \Generator<int, ?array, array{FragmentNode, ?Tag}, static> */
39
        public static function create(Tag $tag, TemplateParser $parser): \Generator
1✔
40
        {
41
                if ($tag->isNAttribute()) {
1✔
UNCOV
42
                        throw new CompileException('Attribute n:embed is not supported.', $tag->position);
×
43
                }
44

45
                $tag->outputMode = $tag::OutputRemoveIndentation;
1✔
46
                $tag->expectArguments();
1✔
47

48
                $node = $tag->node = new static;
1✔
49
                $node->optional = str_ends_with($tag->name, '?');
1✔
50
                $mode = $tag->parser->tryConsumeTokenBeforeUnquotedString('block', 'file')?->text;
1✔
51
                $node->name = $tag->parser->parseUnquotedStringOrExpression();
1✔
52
                $node->mode = $mode ?? ($node->name instanceof StringNode && preg_match('~[\w-]+$~DA', $node->name->value) ? 'block' : 'file');
1✔
53
                $tag->parser->stream->tryConsume(',');
1✔
54
                $node->args = $tag->parser->parseArguments();
1✔
55

56
                $prevIndex = $parser->blockLayer;
1✔
57
                $parser->blockLayer = $node->layer = count($parser->blocks);
1✔
58
                $parser->blocks[$parser->blockLayer] = [];
1✔
59
                [$node->blocks] = yield;
1✔
60

61
                foreach ($node->blocks->children as $child) {
1✔
62
                        if (!$child instanceof ImportNode && !$child instanceof BlockNode && !$child instanceof TextNode) {
1✔
63
                                throw new CompileException('Unexpected content inside {embed} tags.', $child->position);
1✔
64
                        }
65
                }
66

67
                $parser->blockLayer = $prevIndex;
1✔
68
                return $node;
1✔
69
        }
70

71

72
        public function print(PrintContext $context): string
1✔
73
        {
74
                $imports = '';
1✔
75
                foreach ($this->blocks->children as $child) {
1✔
76
                        if ($child instanceof ImportNode) {
1✔
77
                                $imports .= $child->print($context);
1✔
78
                        } else {
79
                                $child->print($context);
1✔
80
                        }
81
                }
82

83
                return $this->mode === 'file'
1✔
84
                        ? $context->format(
1✔
85
                                <<<'XX'
86
                                        $this->enterBlockLayer(%dump, get_defined_vars()) %line; %raw
1✔
87
                                        try {
88
                                                $this->createTemplate(%node, %node, "embed", %dump)?->renderToContentType(%dump) %1.line;
89
                                        } finally {
90
                                                $this->leaveBlockLayer();
91
                                        }
92

93
                                        XX,
94
                                $this->layer,
1✔
95
                                $this->position,
1✔
96
                                $imports,
97
                                $this->name,
1✔
98
                                $this->args,
1✔
99
                                $this->optional,
1✔
100
                                $context->getEscaper()->export(),
1✔
101
                        )
102
                        : $context->format(
1✔
103
                                <<<'XX'
104
                                        $this->enterBlockLayer(%dump, get_defined_vars()) %line; %raw
1✔
105
                                        $this->copyBlockLayer();
106
                                        try {
107
                                                %raw
108
                                        } finally {
109
                                                $this->leaveBlockLayer();
110
                                        }
111

112
                                        XX,
113
                                $this->layer,
1✔
114
                                $this->position,
1✔
115
                                $imports,
116
                                $context->format(
1✔
117
                                        $this->optional
1✔
118
                                                ? 'if ($this->hasBlock($ʟ_nm = %node)) $this->renderBlock($ʟ_nm, %node, %dump) %line;'
1✔
119
                                                : '$this->renderBlock(%node, %node, %dump) %line;',
1✔
120
                                        $this->name,
1✔
121
                                        $this->args,
1✔
122
                                        $context->getEscaper()->export(),
1✔
123
                                        $this->position,
1✔
124
                                ),
125
                        );
126
        }
127

128

129
        public function &getIterator(): \Generator
1✔
130
        {
131
                yield $this->name;
1✔
132
                yield $this->args;
1✔
133
                yield $this->blocks;
1✔
134
        }
1✔
135
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc