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:     public static function install(Latte\Compiler $compiler)
 29:     {
 30:         $me = new static($compiler);
 31:         $me->addMacro('control', array($me, 'macroControl'));
 32: 
 33:         $me->addMacro('href', NULL, NULL, function (MacroNode $node, PhpWriter $writer) use ($me) {
 34:             return ' ?> href="<?php ' . $me->macroLink($node, $writer) . ' ?>"<?php ';
 35:         });
 36:         $me->addMacro('plink', array($me, 'macroLink'));
 37:         $me->addMacro('link', array($me, 'macroLink'));
 38:         $me->addMacro('ifCurrent', array($me, 'macroIfCurrent'), '}'); 
 39:     }
 40: 
 41: 
 42:      43:  44:  45: 
 46:     public function finalize()
 47:     {
 48:         $prolog = '
 49: // snippets support
 50: if (empty($_l->extends) && !empty($_control->snippetMode)) {
 51:     return Nette\Bridges\ApplicationLatte\UIRuntime::renderSnippets($_control, $_b, get_defined_vars());
 52: }';
 53:         return array($prolog, '');
 54:     }
 55: 
 56: 
 57:     
 58: 
 59: 
 60:      61:  62: 
 63:     public function macroControl(MacroNode $node, PhpWriter $writer)
 64:     {
 65:         $words = $node->tokenizer->fetchWords();
 66:         if (!$words) {
 67:             throw new CompileException('Missing control name in {control}');
 68:         }
 69:         $name = $writer->formatWord($words[0]);
 70:         $method = isset($words[1]) ? ucfirst($words[1]) : '';
 71:         $method = Strings::match($method, '#^\w*\z#') ? "render$method" : "{\"render$method\"}";
 72:         $param = $writer->formatArray();
 73:         if (!Strings::contains($node->args, '=>')) {
 74:             $param = substr($param, $param[0] === '[' ? 1 : 6, -1); 
 75:         }
 76:         return ($name[0] === '$' ? "if (is_object($name)) \$_l->tmp = $name; else " : '')
 77:             . '$_l->tmp = $_control->getComponent(' . $name . '); '
 78:             . 'if ($_l->tmp instanceof Nette\Application\UI\IRenderable) $_l->tmp->redrawControl(NULL, FALSE); '
 79:             . ($node->modifiers === '' ? "\$_l->tmp->$method($param)" : $writer->write("ob_start(function () {}); \$_l->tmp->$method($param); echo %modify(ob_get_clean())"));
 80:     }
 81: 
 82: 
 83:      84:  85:  86:  87: 
 88:     public function macroLink(MacroNode $node, PhpWriter $writer)
 89:     {
 90:         $node->modifiers = preg_replace('#\|safeurl\s*(?=\||\z)#i', '', $node->modifiers);
 91:         return $writer->using($node, $this->getCompiler())
 92:             ->write('echo %escape(%modify(' . ($node->name === 'plink' ? '$_presenter' : '$_control') . '->link(%node.word, %node.array?)))');
 93:     }
 94: 
 95: 
 96:      97:  98: 
 99:     public function macroIfCurrent(MacroNode $node, PhpWriter $writer)
100:     {
101:         if ($node->modifiers) {
102:             trigger_error("Modifiers are not allowed in {{$node->name}}", E_USER_WARNING);
103:         }
104:         return $writer->write($node->args
105:             ? 'if ($_presenter->isLinkCurrent(%node.word, %node.array?)) {'
106:             : 'if ($_presenter->getLastCreatedRequestFlag("current")) {'
107:         );
108:     }
109: 
110: 
111:     
112:     public static function renderSnippets(Nette\Application\UI\Control $control, \stdClass $local, array $params)
113:     {
114:         UIRuntime::renderSnippets($control, $local, $params);
115:     }
116: 
117: }
118: