Latte\Macros\BlockMacros::macroBlock PHP Method

macroBlock() public method

{block [name]} {snippet [name [,]] [tag]} {snippetArea [name]} {define name}
public macroBlock ( MacroNode $node, PhpWriter $writer )
$node Latte\MacroNode
$writer Latte\PhpWriter
    public function macroBlock(MacroNode $node, PhpWriter $writer)
    {
        $name = $node->tokenizer->fetchWord();
        if ($node->name === 'block' && $name === FALSE) {
            // anonymous block
            return $node->modifiers === '' ? '' : 'ob_start(function () {})';
        }
        $node->data->name = $name = ltrim($name, '#');
        if ($name == NULL) {
            if ($node->name === 'define') {
                throw new CompileException('Missing block name.');
            }
        } elseif (strpos($name, '$') !== FALSE) {
            // dynamic block/snippet
            if ($node->name === 'snippet') {
                for ($parent = $node->parentNode; $parent && !($parent->name === 'snippet' || $parent->name === 'snippetArea'); $parent = $parent->parentNode) {
                }
                if (!$parent) {
                    throw new CompileException('Dynamic snippets are allowed only inside static snippet/snippetArea.');
                }
                $parent->data->dynamic = TRUE;
                $node->data->leave = TRUE;
                $node->closingCode = "<?php \$this->global->snippetDriver->leave(); ?>";
                $enterCode = '$this->global->snippetDriver->enter(' . $writer->formatWord($name) . ', "' . SnippetDriver::TYPE_DYNAMIC . '");';
                if ($node->prefix) {
                    $node->attrCode = $writer->write("<?php echo ' id=\"' . htmlSpecialChars(\$this->global->snippetDriver->getHtmlId({$writer->formatWord($name)})) . '\"' ?>");
                    return $writer->write($enterCode);
                }
                $tag = trim($node->tokenizer->fetchWord(), '<>');
                if ($tag) {
                    trigger_error('HTML tag specified in {snippet} is deprecated, use n:snippet.', E_USER_DEPRECATED);
                }
                $tag = $tag ? $tag : 'div';
                $node->closingCode .= "\n</{$tag}>";
                $this->checkExtraArgs($node);
                return $writer->write("?>\n<{$tag} id=\"<?php echo htmlSpecialChars(\$this->global->snippetDriver->getHtmlId({$writer->formatWord($name)})) ?>\"><?php " . $enterCode);
            } else {
                $node->data->leave = TRUE;
                $node->data->func = $this->generateMethodName($name);
                $fname = $writer->formatWord($name);
                $node->closingCode = '<?php ' . ($node->name === 'define' ? '' : "\$this->renderBlock({$fname}, get_defined_vars());") . ' ?>';
                $blockType = var_export(implode($node->context), TRUE);
                $this->checkExtraArgs($node);
                return "\$this->checkBlockContentType({$blockType}, {$fname});" . "\$this->blockQueue[{$fname}][] = [\$this, '{$node->data->func}'];";
            }
        }
        // static snippet/snippetArea
        if ($node->name === 'snippet' || $node->name === 'snippetArea') {
            if ($node->prefix && isset($node->htmlNode->attrs['id'])) {
                throw new CompileException('Cannot combine HTML attribute id with n:snippet.');
            }
            $node->data->name = $name = '_' . $name;
        }
        if (isset($this->namedBlocks[$name])) {
            throw new CompileException("Cannot redeclare static {$node->name} '{$name}'");
        }
        $extendsCheck = $this->namedBlocks ? '' : 'if ($this->getParentName()) return get_defined_vars();';
        $this->namedBlocks[$name] = TRUE;
        if (Helpers::removeFilter($node->modifiers, 'escape')) {
            trigger_error('Macro ' . $node->getNotation() . ' provides auto-escaping, remove |escape.');
        }
        if (Helpers::startsWith($node->context[1], Latte\Compiler::CONTEXT_HTML_ATTRIBUTE)) {
            $node->context[1] = '';
            $node->modifiers .= '|escape';
        } elseif ($node->modifiers) {
            $node->modifiers .= '|escape';
        }
        $this->blockTypes[$name] = implode($node->context);
        $include = '$this->renderBlock(%var, ' . ($node->name === 'snippet' || $node->name === 'snippetArea' ? '$this->params' : 'get_defined_vars()') . ($node->modifiers ? ', function ($s, $type) { $_fi = new LR\\FilterInfo($type); return %modifyContent($s); }' : '') . ')';
        if ($node->name === 'snippet') {
            if ($node->prefix) {
                if (isset($node->htmlNode->macroAttrs['foreach'])) {
                    trigger_error('Combination of n:snippet with n:foreach is invalid, use n:inner-foreach.', E_USER_WARNING);
                }
                $node->attrCode = $writer->write('<?php echo \' id="\' . htmlSpecialChars($this->global->snippetDriver->getHtmlId(%var)) . \'"\' ?>', (string) substr($name, 1));
                return $writer->write($include, $name);
            }
            $tag = trim($node->tokenizer->fetchWord(), '<>');
            if ($tag) {
                trigger_error('HTML tag specified in {snippet} is deprecated, use n:snippet.', E_USER_DEPRECATED);
            }
            $tag = $tag ? $tag : 'div';
            $this->checkExtraArgs($node);
            return $writer->write("?>\n<{$tag} id=\"<?php echo htmlSpecialChars(\$this->global->snippetDriver->getHtmlId(%var)) ?>\"><?php {$include} ?>\n</{$tag}><?php ", (string) substr($name, 1), $name);
        } elseif ($node->name === 'define') {
            $tokens = $node->tokenizer;
            $args = [];
            while ($tokens->isNext()) {
                $args[] = $tokens->expectNextValue($tokens::T_VARIABLE);
                if ($tokens->isNext()) {
                    $tokens->expectNextValue(',');
                }
            }
            if ($args) {
                $node->data->args = 'list(' . implode(', ', $args) . ') = $_args + [' . str_repeat('NULL, ', count($args)) . '];';
            }
            return $extendsCheck;
        } else {
            // block, snippetArea
            $this->checkExtraArgs($node);
            return $writer->write($extendsCheck . $include, $name);
        }
    }

Usage Example

示例#1
0
 public function macroRedefine(MacroNode $node, PhpWriter $writer)
 {
     $node->name = 'define';
     $result = parent::macroBlock($node, $writer);
     $node->name = 'redefine';
     $this->redefinedBlocks[] = $node->data->name;
     return $result;
 }