mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-03 22:17:36 +00:00
added the apply tag
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
* 1.40.0 (2019-XX-XX)
|
||||
|
||||
* added the "apply" tag as a replacement for the "filter" tag
|
||||
* allowed Twig\Loader\FilesystemLoader::findTemplate() to return "null" instead of "false" (same meaning)
|
||||
* added support for "Twig\Markup" instances in the "in" test
|
||||
* fixed Lexer when using custom options containing the # char
|
||||
|
||||
+8
-3
@@ -400,16 +400,21 @@ Most of the time though, a tag is not needed:
|
||||
{{ '**markdown** text'|markdown }}
|
||||
|
||||
If you want use this filter on large amounts of text, wrap it with the
|
||||
:doc:`filter <tags/filter>` tag:
|
||||
:doc:`apply <tags/apply>` tag:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% filter markdown %}
|
||||
{% apply markdown %}
|
||||
Title
|
||||
=====
|
||||
|
||||
Much better than creating a tag as you can **compose** filters.
|
||||
{% endfilter %}
|
||||
{% endapply %}
|
||||
|
||||
.. note::
|
||||
|
||||
The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
|
||||
previous versions.
|
||||
|
||||
* If your tag does not output anything, but only exists because of a side
|
||||
effect, create a **function** that returns nothing and call it via the
|
||||
|
||||
@@ -18,19 +18,24 @@ whitespace within HTML tags or whitespace in plain text:
|
||||
|
||||
{# output will be <div><strong>foo</strong></div> #}
|
||||
|
||||
You can combine ``spaceless`` with the ``filter`` tag to apply the
|
||||
transformation on large amounts of HTML:
|
||||
You can combine ``spaceless`` with the ``apply`` tag to apply the transformation
|
||||
on large amounts of HTML:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% filter spaceless %}
|
||||
{% apply spaceless %}
|
||||
<div>
|
||||
<strong>foo</strong>
|
||||
</div>
|
||||
{% endfilter %}
|
||||
{% endapply %}
|
||||
|
||||
{# output will be <div><strong>foo</strong></div> #}
|
||||
|
||||
.. note::
|
||||
|
||||
The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
|
||||
previous versions.
|
||||
|
||||
This tag is not meant to "optimize" the size of the generated HTML content but
|
||||
merely to avoid extra whitespace between HTML tags to avoid browser rendering
|
||||
quirks under some circumstances.
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
``apply``
|
||||
=========
|
||||
|
||||
The ``apply`` tag allows you to apply Twig filters on a block of template data:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% apply upper %}
|
||||
This text becomes uppercase
|
||||
{% endapply %}
|
||||
|
||||
You can also chain filters and pass arguments to them:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% apply lower|escape('html') %}
|
||||
<strong>SOME TEXT</strong>
|
||||
{% endapply %}
|
||||
|
||||
{# outputs "<strong>some text</strong>" #}
|
||||
@@ -1,6 +1,11 @@
|
||||
``filter``
|
||||
==========
|
||||
|
||||
.. note::
|
||||
|
||||
As of Twig 1.40, you should use the ``apply`` tag instead which does the
|
||||
same thing except that the wrapped template data is not scoped.
|
||||
|
||||
Filter sections allow you to apply regular Twig filters on a block of template
|
||||
data. Just wrap the code in the special ``filter`` section:
|
||||
|
||||
|
||||
+15
-5
@@ -167,17 +167,22 @@ example will join a list by commas:
|
||||
{{ list|join(', ') }}
|
||||
|
||||
To apply a filter on a section of code, wrap it in the
|
||||
:doc:`filter<tags/filter>` tag:
|
||||
:doc:`apply<tags/apply>` tag:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% filter upper %}
|
||||
{% apply upper %}
|
||||
This text becomes uppercase
|
||||
{% endfilter %}
|
||||
{% endapply %}
|
||||
|
||||
Go to the :doc:`filters<filters/index>` page to learn more about built-in
|
||||
filters.
|
||||
|
||||
.. note::
|
||||
|
||||
The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
|
||||
previous versions.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
@@ -895,14 +900,19 @@ the modifiers on one side of a tag or on both sides:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% filter spaceless %}
|
||||
{% apply spaceless %}
|
||||
<div>
|
||||
<strong>foo bar</strong>
|
||||
</div>
|
||||
{% endfilter %}
|
||||
{% endapply %}
|
||||
|
||||
{# output will be <div><strong>foo bar</strong></div> #}
|
||||
|
||||
.. note::
|
||||
|
||||
The ``apply`` tag was introduced in Twig 1.40; use the ``filter`` tag with
|
||||
previous versions.
|
||||
|
||||
Extensions
|
||||
----------
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Twig\Extension {
|
||||
use Twig\ExpressionParser;
|
||||
use Twig\TokenParser\ApplyTokenParser;
|
||||
use Twig\TokenParser\BlockTokenParser;
|
||||
use Twig\TokenParser\DeprecatedTokenParser;
|
||||
use Twig\TokenParser\DoTokenParser;
|
||||
@@ -139,6 +140,7 @@ class CoreExtension extends AbstractExtension
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return [
|
||||
new ApplyTokenParser(),
|
||||
new ForTokenParser(),
|
||||
new IfTokenParser(),
|
||||
new ExtendsTokenParser(),
|
||||
|
||||
@@ -111,6 +111,7 @@ class OptimizerNodeVisitor extends AbstractNodeVisitor
|
||||
if (!$expression && 'Twig_Node' !== \get_class($node) && $prependedNodes = array_shift($this->prependedNodes)) {
|
||||
$nodes = [];
|
||||
foreach (array_unique($prependedNodes) as $name) {
|
||||
die();
|
||||
$nodes[] = new SetTempNode($name, $node->getTemplateLine());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\TokenParser;
|
||||
|
||||
use Twig\Node\Expression\TempNameExpression;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\PrintNode;
|
||||
use Twig\Node\SetNode;
|
||||
use Twig\Token;
|
||||
|
||||
/**
|
||||
* Applies filters on a section of a template.
|
||||
*
|
||||
* {% apply upper %}
|
||||
* This text becomes uppercase
|
||||
* {% endapplys %}
|
||||
*/
|
||||
final class ApplyTokenParser extends AbstractTokenParser
|
||||
{
|
||||
public function parse(Token $token)
|
||||
{
|
||||
$lineno = $token->getLine();
|
||||
$name = $this->parser->getVarName();
|
||||
|
||||
$ref = new TempNameExpression($name, $lineno);
|
||||
$ref->setAttribute('always_defined', true);
|
||||
|
||||
$filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
|
||||
|
||||
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
|
||||
$body = $this->parser->subparse([$this, 'decideApplyEnd'], true);
|
||||
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
|
||||
|
||||
return new Node([
|
||||
new SetNode(true, $ref, $body, $lineno, $this->getTag()),
|
||||
new PrintNode($filter, $lineno, $this->getTag()),
|
||||
]);
|
||||
}
|
||||
|
||||
public function decideApplyEnd(Token $token)
|
||||
{
|
||||
return $token->test('endapply');
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return 'apply';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
"apply" tag applies a filter on its children
|
||||
--TEMPLATE--
|
||||
{% apply upper %}
|
||||
Some text with a {{ var }}
|
||||
{% endapply %}
|
||||
--DATA--
|
||||
return ['var' => 'var']
|
||||
--EXPECT--
|
||||
SOME TEXT WITH A VAR
|
||||
@@ -0,0 +1,8 @@
|
||||
--TEST--
|
||||
"apply" tag applies a filter on its children
|
||||
--TEMPLATE--
|
||||
{% apply json_encode|raw %}test{% endapply %}
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
"test"
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
"apply" tags accept multiple chained filters
|
||||
--TEMPLATE--
|
||||
{% apply lower|title %}
|
||||
{{ var }}
|
||||
{% endapply %}
|
||||
--DATA--
|
||||
return ['var' => 'VAR']
|
||||
--EXPECT--
|
||||
Var
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
"apply" tags can be nested at will
|
||||
--TEMPLATE--
|
||||
{% apply lower|title %}
|
||||
{{ var }}
|
||||
{% apply upper %}
|
||||
{{ var }}
|
||||
{% endapply %}
|
||||
{{ var }}
|
||||
{% endapply %}
|
||||
--DATA--
|
||||
return ['var' => 'var']
|
||||
--EXPECT--
|
||||
Var
|
||||
Var
|
||||
Var
|
||||
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
"apply" tag does not create a new scope
|
||||
--TEMPLATE--
|
||||
{% set foo = 'baz' %}
|
||||
{% apply spaceless %}
|
||||
{% set foo = 'foo' %}
|
||||
{% set bar = 'bar' %}
|
||||
{% endapply %}
|
||||
{{ 'foo' == foo ? 'OK ' ~ foo : 'KO' }}
|
||||
{{ 'bar' == bar ? 'OK ' ~ bar : 'KO' }}
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
OK foo
|
||||
OK bar
|
||||
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
"apply" tag applies the filter on "for" tags
|
||||
--TEMPLATE--
|
||||
{% apply upper %}
|
||||
{% for item in items %}
|
||||
{{ item }}
|
||||
{% endfor %}
|
||||
{% endapply %}
|
||||
--DATA--
|
||||
return ['items' => ['a', 'b']]
|
||||
--EXPECT--
|
||||
A
|
||||
B
|
||||
@@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
"apply" tag applies the filter on "if" tags
|
||||
--TEMPLATE--
|
||||
{% apply upper %}
|
||||
{% if items %}
|
||||
{{ items|join(', ') }}
|
||||
{% endif %}
|
||||
|
||||
{% if items.3 is defined %}
|
||||
FOO
|
||||
{% else %}
|
||||
{{ items.1 }}
|
||||
{% endif %}
|
||||
|
||||
{% if items.3 is defined %}
|
||||
FOO
|
||||
{% elseif items.1 %}
|
||||
{{ items.0 }}
|
||||
{% endif %}
|
||||
|
||||
{% endapply %}
|
||||
--DATA--
|
||||
return ['items' => ['a', 'b']]
|
||||
--EXPECT--
|
||||
A, B
|
||||
|
||||
B
|
||||
|
||||
A
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
"scope" tag creates a new scope
|
||||
--TEMPLATE--
|
||||
{% filter spaceless %}
|
||||
{% set item = 'foo' %}
|
||||
{% endfilter %}
|
||||
{{ item }}
|
||||
--DATA--
|
||||
return []
|
||||
--EXCEPTION--
|
||||
Twig\Error\RuntimeError: Variable "item" does not exist in "index.twig" at line 5.
|
||||
Reference in New Issue
Block a user