1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Bridges\ApplicationLatte;
9:
10: use Nette;
11: use Latte;
12: use Latte\MacroNode;
13: use Latte\PhpWriter;
14: use Latte\CompileException;
15: use Nette\Utils\Strings;
16:
17:
18: 19: 20: 21: 22: 23: 24:
25: class UIMacros extends Latte\Macros\MacroSet
26: {
27:
28: private $extends;
29:
30:
31: public static function install(Latte\Compiler $compiler)
32: {
33: $me = new static($compiler);
34: $me->addMacro('control', [$me, 'macroControl']);
35:
36: $me->addMacro('href', NULL, NULL, function (MacroNode $node, PhpWriter $writer) use ($me) {
37: return ' ?> href="<?php ' . $me->macroLink($node, $writer) . ' ?>"<?php ';
38: });
39: $me->addMacro('plink', [$me, 'macroLink']);
40: $me->addMacro('link', [$me, 'macroLink']);
41: $me->addMacro('ifCurrent', [$me, 'macroIfCurrent'], '}');
42: $me->addMacro('extends', [$me, 'macroExtends']);
43: $me->addMacro('layout', [$me, 'macroExtends']);
44: }
45:
46:
47: 48: 49: 50:
51: public function initialize()
52: {
53: $this->extends = FALSE;
54: }
55:
56:
57: 58: 59: 60:
61: public function finalize()
62: {
63: return [$this->extends . 'Nette\Bridges\ApplicationLatte\UIRuntime::initialize($this, $this->parentName, $this->blocks);'];
64: }
65:
66:
67:
68:
69:
70: 71: 72:
73: public function macroControl(MacroNode $node, PhpWriter $writer)
74: {
75: $words = $node->tokenizer->fetchWords();
76: if (!$words) {
77: throw new CompileException('Missing control name in {control}');
78: }
79: $name = $writer->formatWord($words[0]);
80: $method = isset($words[1]) ? ucfirst($words[1]) : '';
81: $method = Strings::match($method, '#^\w*\z#') ? "render$method" : "{\"render$method\"}";
82:
83: $tokens = $node->tokenizer;
84: $pos = $tokens->position;
85: $param = $writer->formatArray();
86: $tokens->position = $pos;
87: while ($tokens->nextToken()) {
88: if ($tokens->isCurrent('=>') && !$tokens->depth) {
89: $wrap = TRUE;
90: break;
91: }
92: }
93: if (empty($wrap)) {
94: $param = substr($param, 1, -1);
95: }
96: return "/* line $node->startLine */ "
97: . ($name[0] === '$' ? "if (is_object($name)) \$_tmp = $name; else " : '')
98: . '$_tmp = $this->global->uiControl->getComponent(' . $name . '); '
99: . 'if ($_tmp instanceof Nette\Application\UI\IRenderable) $_tmp->redrawControl(NULL, FALSE); '
100: . ($node->modifiers === ''
101: ? "\$_tmp->$method($param);"
102: : $writer->write("ob_start(function () {}); \$_tmp->$method($param); echo %modify(ob_get_clean());")
103: );
104: }
105:
106:
107: 108: 109: 110: 111:
112: public function macroLink(MacroNode $node, PhpWriter $writer)
113: {
114: $node->modifiers = preg_replace('#\|safeurl\s*(?=\||\z)#i', '', $node->modifiers);
115: return $writer->using($node, $this->getCompiler())
116: ->write('echo %escape(%modify('
117: . ($node->name === 'plink' ? '$this->global->uiPresenter' : '$this->global->uiControl')
118: . '->link(%node.word, %node.array?)))'
119: );
120: }
121:
122:
123: 124: 125:
126: public function macroIfCurrent(MacroNode $node, PhpWriter $writer)
127: {
128: if ($node->modifiers) {
129: throw new CompileException('Modifiers are not allowed in ' . $node->getNotation());
130: }
131: return $writer->write($node->args
132: ? 'if ($this->global->uiPresenter->isLinkCurrent(%node.word, %node.array?)) {'
133: : 'if ($this->global->uiPresenter->getLastCreatedRequestFlag("current")) {'
134: );
135: }
136:
137:
138: 139: 140:
141: public function macroExtends(MacroNode $node, PhpWriter $writer)
142: {
143: if ($node->modifiers || $node->parentNode || $node->args !== 'auto') {
144: return $this->extends = FALSE;
145: }
146: $this->extends = $writer->write('$this->parentName = $this->global->uiPresenter->findLayoutTemplateFile();');
147: }
148:
149:
150:
151: public static function renderSnippets(Nette\Application\UI\Control $control, \stdClass $local, array $params)
152: {
153: trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED);
154: UIRuntime::renderSnippets($control, $local, $params);
155: }
156:
157: }
158: