mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-16 12:26:30 +00:00
added the starts with, ends with, and matches operators
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
* 1.14.0 (2013-XX-XX)
|
* 1.14.0 (2013-XX-XX)
|
||||||
|
|
||||||
|
* added new operators: ends with, starts with, and matches
|
||||||
* fixed some compatibility issues with HHVM
|
* fixed some compatibility issues with HHVM
|
||||||
* added a way to add custom escaping strategies
|
* added a way to add custom escaping strategies
|
||||||
* fixed the C extension compilation on Windows
|
* fixed the C extension compilation on Windows
|
||||||
|
|||||||
+27
-5
@@ -586,9 +586,9 @@ even if you're not working with PHP you should feel comfortable with it.
|
|||||||
|
|
||||||
The operator precedence is as follows, with the lowest-precedence
|
The operator precedence is as follows, with the lowest-precedence
|
||||||
operators listed first: ``b-and``, ``b-xor``, ``b-or``, ``or``, ``and``,
|
operators listed first: ``b-and``, ``b-xor``, ``b-or``, ``or``, ``and``,
|
||||||
``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``, ``in``, ``..``, ``+``,
|
``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``, ``in``, ``matches``,
|
||||||
``-``, ``~``, ``*``, ``/``, ``//``, ``%``, ``is``, ``**``, ``|``, ``[]``,
|
``starts with``, ``ends with``, ``..``, ``+``, ``-``, ``~``, ``*``, ``/``,
|
||||||
and ``.``:
|
``//``, ``%``, ``is``, ``**``, ``|``, ``[]``, and ``.``:
|
||||||
|
|
||||||
.. code-block:: jinja
|
.. code-block:: jinja
|
||||||
|
|
||||||
@@ -707,6 +707,27 @@ Comparisons
|
|||||||
The following comparison operators are supported in any expression: ``==``,
|
The following comparison operators are supported in any expression: ``==``,
|
||||||
``!=``, ``<``, ``>``, ``>=``, and ``<=``.
|
``!=``, ``<``, ``>``, ``>=``, and ``<=``.
|
||||||
|
|
||||||
|
You can also check if a string ``starts with`` or ``ends with`` another
|
||||||
|
string:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% if 'Fabien' starts with 'F' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if 'Fabien' ends with 'n' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
For complex string comparisons, the ``matches`` operator allows you to use
|
||||||
|
`regular expressions`_:
|
||||||
|
|
||||||
|
.. code-block:: jinja
|
||||||
|
|
||||||
|
{% if phone matches '{^[\d\.]+$}' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
Containment Operator
|
Containment Operator
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@@ -794,8 +815,8 @@ categories:
|
|||||||
{{ foo ? 'yes' : 'no' }}
|
{{ foo ? 'yes' : 'no' }}
|
||||||
|
|
||||||
{# as of Twig 1.12.0 #}
|
{# as of Twig 1.12.0 #}
|
||||||
{{ foo ?: 'no' }} == {{ foo ? foo : 'no' }}
|
{{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }}
|
||||||
{{ foo ? 'yes' }} == {{ foo ? 'yes' : '' }}
|
{{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }}
|
||||||
|
|
||||||
String Interpolation
|
String Interpolation
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -882,3 +903,4 @@ Extension<creating_extensions>` chapter.
|
|||||||
.. _`other Twig syntax mode`: https://github.com/muxx/Twig-HTML.mode
|
.. _`other Twig syntax mode`: https://github.com/muxx/Twig-HTML.mode
|
||||||
.. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig
|
.. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig
|
||||||
.. _`web-mode.el`: http://web-mode.org/
|
.. _`web-mode.el`: http://web-mode.org/
|
||||||
|
.. _`regular expressions`: http://php.net/manual/en/pcre.pattern.php
|
||||||
|
|||||||
+27
-24
@@ -253,30 +253,33 @@ class Twig_Extension_Core extends Twig_Extension
|
|||||||
'+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'),
|
'+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'),
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'matches' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Matches', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'starts with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_StartsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'ends with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_EndsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
'//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
'**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
|
'%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
|
'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
|
'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
|
||||||
|
'**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Twig.
|
||||||
|
*
|
||||||
|
* (c) 2013 Fabien Potencier
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
|
||||||
|
{
|
||||||
|
public function compile(Twig_Compiler $compiler)
|
||||||
|
{
|
||||||
|
$compiler
|
||||||
|
->raw('(0 === substr_compare(')
|
||||||
|
->subcompile($this->getNode('left'))
|
||||||
|
->raw(', ')
|
||||||
|
->subcompile($this->getNode('right'))
|
||||||
|
->raw(', -strlen(')
|
||||||
|
->subcompile($this->getNode('right'))
|
||||||
|
->raw(')))')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function operator(Twig_Compiler $compiler)
|
||||||
|
{
|
||||||
|
return $compiler->raw('');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Twig.
|
||||||
|
*
|
||||||
|
* (c) 2013 Fabien Potencier
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
|
||||||
|
{
|
||||||
|
public function compile(Twig_Compiler $compiler)
|
||||||
|
{
|
||||||
|
$compiler
|
||||||
|
->raw('preg_match(')
|
||||||
|
->subcompile($this->getNode('right'))
|
||||||
|
->raw(', ')
|
||||||
|
->subcompile($this->getNode('left'))
|
||||||
|
->raw(')')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function operator(Twig_Compiler $compiler)
|
||||||
|
{
|
||||||
|
return $compiler->raw('');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Twig.
|
||||||
|
*
|
||||||
|
* (c) 2013 Fabien Potencier
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
|
||||||
|
{
|
||||||
|
public function compile(Twig_Compiler $compiler)
|
||||||
|
{
|
||||||
|
$compiler
|
||||||
|
->raw('(0 === strpos(')
|
||||||
|
->subcompile($this->getNode('left'))
|
||||||
|
->raw(', ')
|
||||||
|
->subcompile($this->getNode('right'))
|
||||||
|
->raw('))')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function operator(Twig_Compiler $compiler)
|
||||||
|
{
|
||||||
|
return $compiler->raw('');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
--TEST--
|
||||||
|
Twig supports the "ends with" operator
|
||||||
|
--TEMPLATE--
|
||||||
|
{{ 'foo' ends with 'o' ? 'OK' : 'KO' }}
|
||||||
|
{{ not ('foo' ends with 'f') ? 'OK' : 'KO' }}
|
||||||
|
{{ not ('foo' ends with 'foowaytoolong') ? 'OK' : 'KO' }}
|
||||||
|
--DATA--
|
||||||
|
return array()
|
||||||
|
--EXPECT--
|
||||||
|
OK
|
||||||
|
OK
|
||||||
|
OK
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
--TEST--
|
||||||
|
Twig supports the "matches" operator
|
||||||
|
--TEMPLATE--
|
||||||
|
{{ 'foo' matches '/o/' ? 'OK' : 'KO' }}
|
||||||
|
{{ 'foo' matches '/^fo/' ? 'OK' : 'KO' }}
|
||||||
|
{{ 'foo' matches '/O/i' ? 'OK' : 'KO' }}
|
||||||
|
--DATA--
|
||||||
|
return array()
|
||||||
|
--EXPECT--
|
||||||
|
OK
|
||||||
|
OK
|
||||||
|
OK
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
--TEST--
|
||||||
|
Twig supports the "starts with" operator
|
||||||
|
--TEMPLATE--
|
||||||
|
{{ 'foo' starts with 'f' ? 'OK' : 'KO' }}
|
||||||
|
{{ not ('foo' starts with 'oo') ? 'OK' : 'KO' }}
|
||||||
|
{{ not ('foo' starts with 'foowaytoolong') ? 'OK' : 'KO' }}
|
||||||
|
--DATA--
|
||||||
|
return array()
|
||||||
|
--EXPECT--
|
||||||
|
OK
|
||||||
|
OK
|
||||||
|
OK
|
||||||
Reference in New Issue
Block a user