mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-09 00:46:31 +00:00
added a slice filter
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
* 1.6.0-DEV
|
||||
|
||||
* added slice notation support for the [] operator (syntactic sugar for the slice operator)
|
||||
* added a slice filter
|
||||
* added string support for the reverse filter
|
||||
* fixed the empty test and the length filter for Twig_Markup instances
|
||||
* added a date function to ease date comparison
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
``slice``
|
||||
===========
|
||||
|
||||
.. versionadded:: 1.6
|
||||
The slice filter was added in Twig 1.6.
|
||||
|
||||
The ``slice`` filter extracts a slice of a sequence, a mapping, or a string:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% for i in [1, 2, 3, 4]|slice(1, 2) %}
|
||||
{# will iterate over 2 and 3 #}
|
||||
{% endfor %}
|
||||
|
||||
{{ '1234'|slice(1, 2) }}
|
||||
|
||||
{# outputs 23 #}
|
||||
|
||||
You can use any valid expression for both the start and the length:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% for i in [1, 2, 3, 4]|slice(start, length) %}
|
||||
{# ... #}
|
||||
{% endfor %}
|
||||
|
||||
As syntactic sugar, you can also use the ``[]`` notation:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% for i in [1, 2, 3, 4][start:length] %}
|
||||
{# ... #}
|
||||
{% endfor %}
|
||||
|
||||
{{ '1234'[1:2] }}
|
||||
|
||||
The ``slice`` filter works as the `array_slice`_ PHP function for arrays and
|
||||
`substr`_ for strings.
|
||||
|
||||
If the start is non-negative, the sequence will start at that start in the
|
||||
variable. If start is negative, the sequence will start that far from the end
|
||||
of the variable.
|
||||
|
||||
If length is given and is positive, then the sequence will have up to that
|
||||
many elements in it. If the variable is shorter than the length, then only the
|
||||
available variable elements will be present. If length is given and is
|
||||
negative then the sequence will stop that many elements from the end of the
|
||||
variable. If it is omitted, then the sequence will have everything from offset
|
||||
up until the end of the variable.
|
||||
|
||||
.. note::
|
||||
|
||||
It also works with objects implementing the `Traversable`_ interface.
|
||||
|
||||
.. _`Traversable`: http://php.net/manual/en/class.traversable.php
|
||||
.. _`array_slice`: http://php.net/array_slice
|
||||
.. _`substr`: http://php.net/substr
|
||||
@@ -320,12 +320,13 @@ class Twig_ExpressionParser
|
||||
|
||||
public function parseSubscriptExpression($node)
|
||||
{
|
||||
$token = $this->parser->getStream()->next();
|
||||
$stream = $this->parser->getStream();
|
||||
$token = $stream->next();
|
||||
$lineno = $token->getLine();
|
||||
$arguments = new Twig_Node();
|
||||
$type = Twig_TemplateInterface::ANY_CALL;
|
||||
if ($token->getValue() == '.') {
|
||||
$token = $this->parser->getStream()->next();
|
||||
$token = $stream->next();
|
||||
if (
|
||||
$token->getType() == Twig_Token::NAME_TYPE
|
||||
||
|
||||
@@ -335,7 +336,7 @@ class Twig_ExpressionParser
|
||||
) {
|
||||
$arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
|
||||
|
||||
if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$type = Twig_TemplateInterface::METHOD_CALL;
|
||||
$arguments = $this->parseArguments();
|
||||
} else {
|
||||
@@ -348,7 +349,21 @@ class Twig_ExpressionParser
|
||||
$type = Twig_TemplateInterface::ARRAY_CALL;
|
||||
|
||||
$arg = $this->parseExpression();
|
||||
$this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ']');
|
||||
|
||||
// slice?
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
|
||||
$stream->next();
|
||||
|
||||
$class = $this->getFilterNodeClass('slice');
|
||||
$arguments = new Twig_Node(array($arg, $this->parseExpression()));
|
||||
$filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());
|
||||
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
|
||||
|
||||
return $filter;
|
||||
}
|
||||
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
|
||||
|
||||
@@ -126,6 +126,7 @@ class Twig_Extension_Core extends Twig_Extension
|
||||
// string/array filters
|
||||
'reverse' => new Twig_Filter_Function('twig_reverse_filter', array('needs_environment' => true)),
|
||||
'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)),
|
||||
'slice' => new Twig_Filter_Function('twig_slice', array('needs_environment' => true)),
|
||||
|
||||
// iteration and runtime
|
||||
'default' => new Twig_Filter_Node('Twig_Node_Expression_Filter_Default'),
|
||||
@@ -494,6 +495,35 @@ function twig_array_merge($arr1, $arr2)
|
||||
return array_merge($arr1, $arr2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Slices a variable.
|
||||
*
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param mixed $item A variable
|
||||
* @param integer $start Start of the slice
|
||||
* @param integer $length Size of the slice
|
||||
*
|
||||
* @return mixed The sliced variable
|
||||
*/
|
||||
function twig_slice(Twig_Environment $env, $item, $start, $length = null)
|
||||
{
|
||||
if ($item instanceof Traversable) {
|
||||
$item = iterator_to_array($item, false);
|
||||
}
|
||||
|
||||
if (is_array($item)) {
|
||||
return array_slice($item, $start, $length);
|
||||
}
|
||||
|
||||
$item = (string) $item;
|
||||
|
||||
if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
|
||||
return mb_substr($item, $start, $length, $charset);
|
||||
}
|
||||
|
||||
return substr($item, $start, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the values to a string.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
"slice" filter
|
||||
--TEMPLATE--
|
||||
{{ [1, 2, 3, 4][1:2]|join('')}}
|
||||
{{ {a: 1, b: 2, c: 3, d: 4}[1:2]|join('') }}
|
||||
{{ [1, 2, 3, 4][start:length]|join('') }}
|
||||
{{ [1, 2, 3, 4]|slice(1, 2)|join('') }}
|
||||
{{ {a: 1, b: 2, c: 3, d: 4}|slice(1, 2)|join('') }}
|
||||
{{ '1234'|slice(1, 2) }}
|
||||
{{ '1234'[1:2] }}
|
||||
{{ arr|slice(1, 2)|join('') }}
|
||||
{{ arr[1:2]|join('') }}
|
||||
--DATA--
|
||||
return array('start' => 1, 'length' => 2, 'arr' => new ArrayObject(array(1, 2, 3, 4)))
|
||||
--EXPECT--
|
||||
23
|
||||
23
|
||||
23
|
||||
23
|
||||
23
|
||||
23
|
||||
23
|
||||
23
|
||||
23
|
||||
Reference in New Issue
Block a user