Skip to content

Commit

Permalink
Defer added prefix + unique now only renders once
Browse files Browse the repository at this point in the history
  • Loading branch information
boekkooi committed Jul 16, 2014
1 parent e506b4d commit 46fdbe6
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 17 deletions.
3 changes: 2 additions & 1 deletion src/DependencyInjection/BoekkooiTwigJackExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public function load(array $config, ContainerBuilder $container)
$processor = new Processor();
$config = $processor->processConfiguration(new Configuration(), $config);

if ($config['defer']) {
if ($config['defer']['enabled']) {
$container->setParameter('boekkooi.twigjack.defer.prefix', $config['defer']['prefix']);
$loader->load('defer.yml');
}

Expand Down
10 changes: 9 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ public function getConfigTreeBuilder()
$rootNode = $treeBuilder->root('boekkooi_twig_jack');
$rootNode
->children()
->booleanNode('defer')->defaultTrue()->end()
->arrayNode('defer')
->treatNullLike(array())
->treatFalseLike(array('enabled' => false))
->treatTrueLike(array('enabled' => true))
->children()
->booleanNode('enabled')->defaultTrue()->end()
->scalarNode('prefix')->defaultValue('_defer_ref_')->end()
->end()
->end()
->booleanNode('exclamation')->defaultTrue()->end()
->end();

Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/defer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ services:
# defer extension
boekkooi.twigjack.defer.extension:
class: %boekkooi.twigjack.defer.extension.class%
arguments: [ %boekkooi.twigjack.defer.prefix% ]
tags:
- { name: "twig.extension" }
15 changes: 14 additions & 1 deletion src/Twig/Extension/DeferExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@
class DeferExtension extends \Twig_Extension
{
protected $references = array();

protected $deferBlockPrefix;

public function __construct($deferBlockPrefix = '_defer_ref_')
{
$this->deferBlockPrefix = $deferBlockPrefix;
}

/**
* {@inheritdoc}
*/
public function getTokenParsers()
{
return array(
new TokenParser\Defer()
new TokenParser\Defer($this->deferBlockPrefix)
);
}

Expand All @@ -36,6 +44,11 @@ public function cache($type, $name, $content)
$this->references[$type][$name] = $content;
}

public function contains($type, $name)
{
return isset($this->references[$type]) && isset($this->references[$type][$name]);
}

public function retrieve($type, $clear = true)
{
if (!isset($this->references[$type])) {
Expand Down
22 changes: 17 additions & 5 deletions src/Twig/Node/DeferReference.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
*/
class DeferReference extends Twig_Node_BlockReference
{
public function __construct($name, $reference, $lineno, $tag = null)
public function __construct($name, $unique, $reference, $lineno, $tag = null)
{
parent::__construct($name, $lineno, $tag);

$this->setAttribute('reference', $reference);
$this->setAttribute('unique', $unique);
}

/**
Expand All @@ -28,9 +29,20 @@ public function compile(Twig_Compiler $compiler)
$name = $this->getAttribute('name');
$reference = $this->getAttribute('reference');

$compiler
->addDebugInfo($this)
->write("\$this->env->getExtension('defer')->cache('{$reference}', '{$name}', \$this->renderBlock('{$name}', \$context, \$blocks));\n")
;
if ($this->getAttribute('unique')) {
$compiler
->addDebugInfo($this)
->write("if (!\$this->env->getExtension('defer')->contains('{$reference}', '{$name}')) {\n")
->indent()
->write("\$this->env->getExtension('defer')->cache('{$reference}', '{$name}', \$this->renderBlock('{$name}', \$context, \$blocks));\n")
->outdent()
->write("}\n")
;
} else {
$compiler
->addDebugInfo($this)
->write("\$this->env->getExtension('defer')->cache('{$reference}', '{$name}', \$this->renderBlock('{$name}', \$context, \$blocks));\n")
;
}
}
}
22 changes: 15 additions & 7 deletions src/Twig/TokenParser/Defer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ class Defer extends Twig_TokenParser
{
private static $i = 0;

protected $blockPrefix;

public function __construct($blockPrefix)
{
$this->blockPrefix = $blockPrefix;
}

/**
* Parses a token and returns a node.
*
Expand All @@ -39,15 +46,16 @@ public function parse(Twig_Token $token)
$reference = $stream->expect(Twig_Token::NAME_TYPE)->getValue();

$name = $stream->nextIf(\Twig_Token::NAME_TYPE);
if ($name === null) {
do {
$name = 'defer_ref_' . $reference . (self::$i++);
} while ($this->parser->hasBlock($name));
} else {
$name = $name->getValue();
$unique = $name === null;
if ($unique) {
$name = $this->blockPrefix . $name->getValue();
if ($this->parser->hasBlock($name)) {
return null;
}
} else {
do {
$name = $this->blockPrefix . $reference . (self::$i++);
} while ($this->parser->hasBlock($name));
}

$this->parser->setBlock($name, $block = new Node\Defer($name, new Twig_Node(array()), $lineno));
Expand All @@ -74,7 +82,7 @@ public function parse(Twig_Token $token)
$this->parser->popBlockStack();
$this->parser->popLocalScope();

return new Node\DeferReference($name, $reference, $lineno, $this->getTag());
return new Node\DeferReference($name, $unique, $reference, $lineno, $this->getTag());
}

public function decideBlockEnd(Twig_Token $token)
Expand Down
12 changes: 10 additions & 2 deletions tests/Twig/Node/DeferReferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ class DeferReferenceTest extends \Twig_Test_NodeTestCase
*/
public function testConstructor()
{
$node = new DeferReference('foo', 'bar', 1);
$node = new DeferReference('foo', false, 'bar', 1);

$this->assertEquals('foo', $node->getAttribute('name'));
$this->assertEquals('bar', $node->getAttribute('reference'));
$this->assertEquals(false, $node->getAttribute('unique'));
}

/**
Expand All @@ -31,9 +32,16 @@ public function testCompile($node, $source, $environment = null)
public function getTests()
{
return array(
array(new DeferReference('foo', 'js', 1), <<<EOF
array(new DeferReference('foo', false, 'js', 1), <<<EOF
// line 1
\$this->env->getExtension('defer')->cache('js', 'foo', \$this->renderBlock('foo', \$context, \$blocks));
EOF
),
array(new DeferReference('foo', true, 'js', 1), <<<EOF
// line 1
if (!\$this->env->getExtension('defer')->contains('js', 'foo')) {
\$this->env->getExtension('defer')->cache('js', 'foo', \$this->renderBlock('foo', \$context, \$blocks));
}
EOF
),
);
Expand Down

0 comments on commit 46fdbe6

Please sign in to comment.