first commit
This commit is contained in:
21
vendor/phive/twig-extensions-deferred/LICENSE
vendored
Normal file
21
vendor/phive/twig-extensions-deferred/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2017 Eugene Leonovich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
128
vendor/phive/twig-extensions-deferred/README.md
vendored
Normal file
128
vendor/phive/twig-extensions-deferred/README.md
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
Deferred Twig Extension
|
||||
=======================
|
||||
[](https://travis-ci.org/rybakit/twig-extensions-deferred)
|
||||
|
||||
An extension for Twig that allows to defer block rendering.
|
||||
|
||||
## Installation
|
||||
|
||||
The recommended way to install the extension is through [Composer](http://getcomposer.org):
|
||||
|
||||
```sh
|
||||
$ composer require phive/twig-extensions-deferred:^1.0
|
||||
```
|
||||
|
||||
|
||||
## Initialization
|
||||
|
||||
```php
|
||||
$twig = new Twig_Environment($loader);
|
||||
$twig->addExtension(new Phive\Twig\Extensions\Deferred\DeferredExtension());
|
||||
```
|
||||
|
||||
## Simple Example
|
||||
|
||||
```jinja
|
||||
{# outputs bar #}
|
||||
{% block foo deferred %}
|
||||
{{ bar }}
|
||||
{% endblock %}
|
||||
|
||||
{% set bar = 'bar' %}
|
||||
```
|
||||
|
||||
|
||||
## Advanced Example
|
||||
|
||||
Just for example purposes, first create a [global twig variable](http://twig.sensiolabs.org/doc/advanced.html#globals):
|
||||
|
||||
```php
|
||||
$twig = new Twig_Environment($loader);
|
||||
$twig->addGlobal('data', new ArrayObject());
|
||||
```
|
||||
|
||||
Then build the following set of templates:
|
||||
|
||||
```jinja
|
||||
{# layout.html.twig #}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
...
|
||||
</head>
|
||||
<body>
|
||||
{% block content '' %}
|
||||
|
||||
{{ data.append('/js/layout-header.js') }}
|
||||
|
||||
{% block javascripts deferred %}
|
||||
{% for item in data %}
|
||||
<script src="{{ item }}"></script>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{{ data.append('/js/layout-footer.js') }}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
{# page.html.twig #}
|
||||
{% extends "layout.html.twig" %}
|
||||
|
||||
{% block content %}
|
||||
{{ data.append('/js/page-header.js') }}
|
||||
|
||||
{% if foo is not defined %}
|
||||
{{ include("subpage1.html.twig") }}
|
||||
{% else %}
|
||||
{{ include("subpage2.html.twig") }}
|
||||
{% endif %}
|
||||
|
||||
{{ data.append('/js/page-footer.js') }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{# subpage1.html.twig #}
|
||||
{{ data.append('/js/subpage1.js') }}
|
||||
|
||||
|
||||
{# subpage2.html.twig #}
|
||||
{{ data.append('/js/subpage2.js') }}
|
||||
```
|
||||
|
||||
The resulting html will be the following:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
...
|
||||
</head>
|
||||
<body>
|
||||
<script src="/js/layout-header.js"></script>
|
||||
<script src="/js/page-header.js"></script>
|
||||
<script src="/js/subpage1.js"></script>
|
||||
<script src="/js/page-footer.js"></script>
|
||||
<script src="/js/layout-footer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
## Block overriding
|
||||
|
||||
```jinja
|
||||
{# index.twig #}
|
||||
{% extends "base.twig" %}
|
||||
{% block foo %}foo is not deferred anymore{% endblock %}
|
||||
{% block bar deferred %}bar is deferred now{% endblock %}
|
||||
|
||||
{# base.twig #}
|
||||
{% block foo deferred %}foo is deferred{% endblock %}
|
||||
{% block bar %}bar is not deferred{% endblock %}
|
||||
```
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Deferred Twig Extension is released under the MIT License. See the bundled [LICENSE](LICENSE) file for details.
|
29
vendor/phive/twig-extensions-deferred/src/DeferredBlockNode.php
vendored
Executable file
29
vendor/phive/twig-extensions-deferred/src/DeferredBlockNode.php
vendored
Executable file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Phive\Twig\Extensions\Deferred;
|
||||
|
||||
class DeferredBlockNode extends \Twig_Node_Block
|
||||
{
|
||||
public function compile(\Twig_Compiler $compiler)
|
||||
{
|
||||
$name = $this->getAttribute('name');
|
||||
|
||||
$compiler
|
||||
->write("public function block_$name(\$context, array \$blocks = array())\n", "{\n")
|
||||
->indent()
|
||||
->write("\$this->env->getExtension('Phive\\Twig\\Extensions\\Deferred\\DeferredExtension')->defer(\$this, '$name');\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("public function block_{$name}_deferred(\$context, array \$blocks = array())\n", "{\n")
|
||||
->indent()
|
||||
->subcompile($this->getNode('body'))
|
||||
->write("\$this->env->getExtension('Phive\\Twig\\Extensions\\Deferred\\DeferredExtension')->resolve(\$this, \$context, \$blocks);\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
}
|
63
vendor/phive/twig-extensions-deferred/src/DeferredExtension.php
vendored
Normal file
63
vendor/phive/twig-extensions-deferred/src/DeferredExtension.php
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Phive\Twig\Extensions\Deferred;
|
||||
|
||||
class DeferredExtension extends \Twig_Extension
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $blocks = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(new DeferredTokenParser());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNodeVisitors()
|
||||
{
|
||||
return array(new DeferredNodeVisitor());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'deferred';
|
||||
}
|
||||
|
||||
public function defer(\Twig_Template $template, $blockName)
|
||||
{
|
||||
$templateName = $template->getTemplateName();
|
||||
$this->blocks[$templateName][] = $blockName;
|
||||
ob_start();
|
||||
}
|
||||
|
||||
public function resolve(\Twig_Template $template, array $context, array $blocks)
|
||||
{
|
||||
$templateName = $template->getTemplateName();
|
||||
if (empty($this->blocks[$templateName])) {
|
||||
return;
|
||||
}
|
||||
|
||||
while ($blockName = array_pop($this->blocks[$templateName])) {
|
||||
$buffer = ob_get_clean();
|
||||
|
||||
$blocks[$blockName] = array($template, 'block_'.$blockName.'_deferred');
|
||||
$template->displayBlock($blockName, $context, $blocks);
|
||||
|
||||
echo $buffer;
|
||||
}
|
||||
|
||||
if ($parent = $template->getParent($context)) {
|
||||
$this->resolve($parent, $context, $blocks);
|
||||
}
|
||||
}
|
||||
}
|
13
vendor/phive/twig-extensions-deferred/src/DeferredNode.php
vendored
Executable file
13
vendor/phive/twig-extensions-deferred/src/DeferredNode.php
vendored
Executable file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Phive\Twig\Extensions\Deferred;
|
||||
|
||||
class DeferredNode extends \Twig_Node
|
||||
{
|
||||
public function compile(\Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("\$this->env->getExtension('Phive\\Twig\\Extensions\\Deferred\\DeferredExtension')->resolve(\$this, \$context, \$blocks);\n")
|
||||
;
|
||||
}
|
||||
}
|
41
vendor/phive/twig-extensions-deferred/src/DeferredNodeVisitor.php
vendored
Normal file
41
vendor/phive/twig-extensions-deferred/src/DeferredNodeVisitor.php
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Phive\Twig\Extensions\Deferred;
|
||||
|
||||
class DeferredNodeVisitor implements \Twig_NodeVisitorInterface
|
||||
{
|
||||
private $hasDeferred = false;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
|
||||
{
|
||||
if (!$this->hasDeferred && $node instanceof DeferredBlockNode) {
|
||||
$this->hasDeferred = true;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function leaveNode(\Twig_NodeInterface $node, \Twig_Environment $env)
|
||||
{
|
||||
if ($this->hasDeferred && $node instanceof \Twig_Node_Module) {
|
||||
$node->setNode('display_end', new \Twig_Node(array(new DeferredNode(), $node->getNode('display_end'))));
|
||||
$this->hasDeferred = false;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
57
vendor/phive/twig-extensions-deferred/src/DeferredTokenParser.php
vendored
Normal file
57
vendor/phive/twig-extensions-deferred/src/DeferredTokenParser.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Phive\Twig\Extensions\Deferred;
|
||||
|
||||
class DeferredTokenParser extends \Twig_TokenParser
|
||||
{
|
||||
private $blockTokenParser;
|
||||
|
||||
public function setParser(\Twig_Parser $parser)
|
||||
{
|
||||
parent::setParser($parser);
|
||||
|
||||
$this->blockTokenParser = new \Twig_TokenParser_Block();
|
||||
$this->blockTokenParser->setParser($parser);
|
||||
}
|
||||
|
||||
public function parse(\Twig_Token $token)
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
$nameToken = $stream->next();
|
||||
$deferredToken = $stream->nextIf(\Twig_Token::NAME_TYPE, 'deferred');
|
||||
$stream->injectTokens(array($nameToken));
|
||||
|
||||
$node = $this->blockTokenParser->parse($token);
|
||||
|
||||
if ($deferredToken) {
|
||||
$this->replaceBlockNode($nameToken->getValue());
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return 'block';
|
||||
}
|
||||
|
||||
private function replaceBlockNode($name)
|
||||
{
|
||||
$block = $this->parser->getBlock($name)->getNode(0);
|
||||
$this->parser->setBlock($name, $this->createDeferredBlockNode($block));
|
||||
}
|
||||
|
||||
private function createDeferredBlockNode(\Twig_Node_Block $block)
|
||||
{
|
||||
$name = $block->getAttribute('name');
|
||||
$deferredBlock = new DeferredBlockNode($name, new \Twig_Node(array()), $block->getTemplateLine());
|
||||
|
||||
foreach ($block as $nodeName => $node) {
|
||||
$deferredBlock->setNode($nodeName, $node);
|
||||
}
|
||||
|
||||
$deferredBlock->setTemplateName($block->getTemplateName());
|
||||
|
||||
return $deferredBlock;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user