public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_ForLoop) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_ForLoop, but got "%s".', get_class($node))); } if ($node->getAttribute('else')) { $compiler->write("")->subcompile(new \Twig_Node_Expression_Name('_iterated', $node->getLine()))->raw(" = true;\n"); } if ($node->getAttribute('with_loop')) { $compiler->write("++")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['index0'];\n")->write("++")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['index'];\n")->write("")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['first'] = false;\n"); if (!$node->getAttribute('ifexpr')) { $compiler->write("if (")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['length']) {\n")->indent()->write("--")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['revindex0'];\n")->write("--")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['revindex'];\n")->write("")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['last'] = 0 === ")->subcompile(new \Twig_Node_Expression_Name('loop', $node->getLine()))->raw("['revindex0'];\n")->outdent()->write("}\n"); } } }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Set) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Set, but got "%s".', get_class($node))); } $compiler->addDebugInfo($node); if (count($node->getNode('names')) > 1) { $values = $node->getNode('values'); foreach ($node->getNode('names') as $idx => $subNode) { $compiler->subcompile($subNode)->raw(' = ')->subcompile($values->getNode($idx))->raw(";\n"); } return; } $count = $this->count++; $captureStringBuffer = 'cSb' . ($count > 0 ? $count : ''); if ($node->getAttribute('capture')) { $compiler->write("var {$captureStringBuffer} = sb;\n")->write("sb = new twig.StringBuffer;")->subcompile($node->getNode('values')); } $compiler->subcompile($node->getNode('names'), false); if ($node->getAttribute('capture')) { $compiler->raw(" = new twig.Markup(sb.toString());\n")->write("sb = {$captureStringBuffer}"); } else { $compiler->raw(' = '); if ($node->getAttribute('safe')) { $compiler->raw("new twig.Markup(")->subcompile($node->getNode('values'))->raw(")"); } else { $compiler->subcompile($node->getNode('values')); } } $compiler->raw(";\n"); $this->count = $count; }
protected function compileClassHeader(JsCompiler $compiler, Twig_NodeInterface $node) { $this->functionName = $functionName = $compiler->templateFunctionName = $compiler->getFunctionName($node); $parts = explode('.', $functionName); array_pop($parts); $filename = $node->getAttribute('filename'); if (!empty($filename) && false !== strpos($filename, DIRECTORY_SEPARATOR)) { $parts = explode(DIRECTORY_SEPARATOR, realpath($filename)); $filename = implode(DIRECTORY_SEPARATOR, array_splice($parts, -4)); } $compiler->write("/**\n")->write(" * @fileoverview Compiled template for file\n")->write(" *\n")->write(" * " . str_replace('*/', '*\\/', $filename) . "\n")->write(" *\n")->write(" * @suppress {checkTypes|fileoverviewTags}\n")->write(" */\n")->write("\n"); $compiler->write("goog.provide('{$functionName}');\n")->write("\n")->write("goog.require('twig');\n")->write("goog.require('twig.filter');\n")->write("\n")->write("/**\n", " * @constructor\n", " * @param {twig.Environment} env\n", " * @extends {twig.Template}\n", " */\n")->write("{$functionName} = function(env) {\n")->indent()->write("twig.Template.call(this, env);\n"); if (count($node->getNode('blocks')) || count($node->getNode('traits'))) { $this->compileConstructor($compiler, $node); } $compiler->outdent()->write("};\n")->write("twig.inherits({$functionName}, twig.Template);\n\n"); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Include) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Include, but got "%s".', get_class($node))); } $compiler->addDebugInfo($node); // Is there are use case for conditional includes at runtime? // if ($node->getAttribute('ignore_missing')) { // $compiler // ->write("try {\n") // ->indent() // ; // } $compiler->isTemplateName = true; if ($node->getNode('expr') instanceof Twig_Node_Expression_Constant) { $compiler->write("(new ")->subcompile($node->getNode('expr'))->raw("(this.env_)).render_(sb, "); } else { $compiler->write("(new ")->subcompile($node->getNode('expr'))->raw("(this.env_)).render_(sb, "); } $compiler->isTemplateName = false; if (false === $node->getAttribute('only')) { if (null === $node->getNode('variables')) { $compiler->raw('context'); } else { $compiler->raw('twig.extend({}, context, ')->subcompile($node->getNode('variables'))->raw(')'); } } else { if (null === $node->getNode('variables')) { $compiler->raw('{}'); } else { $compiler->subcompile($node->getNode('variables')); } } $compiler->raw(");\n"); // if ($node->getAttribute('ignore_missing')) { // $compiler // ->outdent() // ->write("} catch (Twig_Error_Loader \$e) {\n") // ->indent() // ->write("// ignore missing template\n") // ->outdent() // ->write("}\n\n") // ; // } }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_For) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\For, but got "%s".', get_class($node))); } $count = $this->count++; $suffix = $count > 0 ? $count : ''; $seqName = 'seq' . $suffix; $keyName = 'k' . $suffix; $valueName = 'v' . $suffix; $iteratedName = 'iterated' . $suffix; $loopName = 'loop' . $suffix; if ($count > 0) { $compiler->enterScope(); } $compiler->setVar('_seq', $seqName)->setVar('_iterated', $iteratedName)->setVar('loop', $loopName)->addDebugInfo($node); // keep parent reference as some might rely on this if (0 === $count) { $compiler->write("context['_parent'] = context;\n"); } $compiler->write("var {$seqName} = ")->subcompile($node->getNode('seq'))->raw(";\n"); if (null !== $node->getNode('else')) { $compiler->write("var {$iteratedName} = false;\n"); } if ($node->getAttribute('with_loop')) { $compiler->write("var {$loopName} = {\n")->indent(); if ($count > 0) { $parentSuffix = $count - 1 > 0 ? $count - 1 : ''; $compiler->write("'parent': {loop: loop{$parentSuffix}},\n"); } $compiler->write("'index0': 0,\n")->write("'index': 1,\n")->write("'first': true\n")->outdent()->write("};\n"); if (false === $node->getAttribute('ifexpr')) { $compiler->write("if (twig.countable({$seqName})) {\n")->indent()->write("var length = twig.count({$seqName});\n")->write("{$loopName}['revindex0'] = length - 1;\n")->write("{$loopName}['revindex'] = length;\n")->write("{$loopName}['length'] = length;\n")->write("{$loopName}['last'] = 1 === length;\n")->outdent()->write("}\n"); } } $ref = new \ReflectionProperty($node, 'loop'); $ref->setAccessible(true); $loop = $ref->getValue($node); $loop->setAttribute('else', null !== $node->getNode('else')); $loop->setAttribute('with_loop', $node->getAttribute('with_loop')); $loop->setAttribute('ifexpr', $node->getAttribute('ifexpr')); $compiler->write("twig.forEach({$seqName}, function({$valueName}, {$keyName}) {\n")->indent()->write('')->subcompile($node->getNode('key_target'))->raw(" = {$keyName};\n")->write('')->subcompile($node->getNode('value_target'))->raw(" = {$valueName};\n")->subcompile($node->getNode('body'))->outdent()->write("}, this);\n"); if (null !== $node->getNode('else')) { $compiler->write("if (!{$iteratedName}) {\n")->indent()->subcompile($node->getNode('else'))->outdent()->write("}\n"); } if ($count > 0) { $compiler->leaveScope(); } $this->count = $count; }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_Macro) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\Twig_Node_Macro, but got "%s".', get_class($node))); } $compiler->enterScope(); $arguments = array(); foreach ($node->getNode('arguments') as $name => $argument) { if ($argument->hasAttribute('name')) { $name = $argument->getAttribute('name'); } $arguments[] = 'opt_' . $name; $compiler->setVar($name, 'opt_' . $name); } $compiler->addDebugInfo($node)->write("/**\n", " * Macro \"" . $node->getAttribute('name') . "\"\n", " *\n"); foreach ($arguments as $arg => $var) { $compiler->write(" * @param {*} {$var}\n"); } $compiler->write(" * @return {string}\n")->write(" */\n")->raw($compiler->templateFunctionName)->raw(".prototype.get")->raw($node->getAttribute('name'))->raw(" = function(" . implode(', ', $arguments) . ") {\n")->indent()->write("var context = twig.extend({}, this.env_.getGlobals());\n\n")->write("var sb = new twig.StringBuffer;\n")->subcompile($node->getNode('body'))->raw("\n")->write("return new twig.Markup(sb.toString());\n")->outdent()->write("};\n\n")->leaveScope(); }
public function compile(JsCompiler $compiler, \Twig_NodeInterface $node) { if (!$node instanceof \Twig_Node_If) { throw new \RuntimeException(sprintf('$node must be an instanceof of \\If, but got "%s".', get_class($node))); } $compiler->addDebugInfo($node); for ($i = 0; $i < count($node->getNode('tests')); $i += 2) { if ($i > 0) { $compiler->outdent()->write("} else if ("); } else { $compiler->write('if ('); } $compiler->subcompile($node->getNode('tests')->getNode($i))->raw(") {\n")->indent()->subcompile($node->getNode('tests')->getNode($i + 1)); } if ($node->hasNode('else') && null !== $node->getNode('else')) { $compiler->outdent()->write("} else {\n")->indent()->subcompile($node->getNode('else')); } $compiler->outdent()->write("}\n"); }
protected function compileClassFooter(JsCompiler $compiler, \Twig_NodeInterface $node) { $compiler->write("return " . $this->functionName . ";\n")->outdent()->write("});"); }
public function compileLoadTemplate(JsCompiler $compiler, $node, $var) { $compiler->isTemplateName = true; $compiler->write(sprintf("var %s = this.env_.createTemplate(", $var))->subcompile($node)->raw(");\n"); $compiler->isTemplateName = false; }