merged branch Seldaek/isarray (PR #700)

Commits
-------

c88f8e5 Micro-optimizations
70cca66 Simplify code
d78ed66 Add traversable test
5fd2f98 Add docs
b2e1675 Add is array test

Discussion
----------

is array/traversable tests

It's sometimes necessary to display arbitrary data to be able to know if we should recurse or not.

---------------------------------------------------------------------------

by stof at 2012-04-13T12:13:11Z

I'm not sure about the need for ``is array``. All Twig functions related to arrays also support traversable objects

---------------------------------------------------------------------------

by Seldaek at 2012-04-13T12:23:32Z

Well, I like to have both for explicitness and also because I would try is array without looking at the docs, and I don't think it's right to make is array return true for traversables.

---------------------------------------------------------------------------

by fabpot at 2012-04-20T09:38:33Z

One of the main goal of Twig is to abstract the "real" type of the variables. We have already discussed the introduction of many tests like these ones and I have always rejected them.

As many people seems to have a need for them (especially for arrays), I would consider adding the `traversable` test. But as @stof said, Twig tries to blur the difference between traversable objects and arrays, so I'm -1 for adding another test for arrays.

`traversable` is probably not the best name for web designers but I don't know what else we can use here.

---------------------------------------------------------------------------

by stof at 2012-04-20T09:41:05Z

In Jinja, there is a built-in test for this using ``iterable``: http://jinja.pocoo.org/docs/templates/#builtin-tests

---------------------------------------------------------------------------

by Seldaek at 2012-04-20T09:41:32Z

Ok. I can live with dropping the array test. Now for the name,  `is forloopable`? I am kind of at a loss as well apart from traversable. I think if it's clearly mentioned in the docs it's ok.

---------------------------------------------------------------------------

by Seldaek at 2012-04-20T09:52:12Z

iterable sounds ok to me, but just as confusing as traversable I guess to the unknowing. A sidenote, if I update the PR, any objection to adding the "undefined" test as well?

---------------------------------------------------------------------------

by fabpot at 2012-04-20T10:01:27Z

Let's use `iterable` as this is what Jinja already uses. Why would you want an `undefined` test as we already have `defined`? (`if foo is not defined` works well enough)

---------------------------------------------------------------------------

by Seldaek at 2012-04-20T11:16:26Z

I just saw jinja had it on that page, and I thought why not add it too? Still not a huge fan of the "not" for negation.

---------------------------------------------------------------------------

by fabpot at 2012-04-20T12:18:17Z

Well, let's first finish the `iterable` test first and let's discuss `undefined` in another PR or issue.

---------------------------------------------------------------------------

by fabpot at 2012-04-20T17:10:28Z

I can finish the PR is you want.

---------------------------------------------------------------------------

by Seldaek at 2012-04-20T17:13:11Z

If you like sure, it's mostly deleting code anyway. I just have to finish some work stuff now..
This commit is contained in:
Fabien Potencier
2012-04-20 20:09:05 +02:00
5 changed files with 81 additions and 3 deletions
+11
View File
@@ -0,0 +1,11 @@
``array``
=========
``array`` checks if a variable is an array:
.. code-block:: jinja
{# evaluates to true if the foo variable is an array #}
{% if foo is array %}
...
{% endif %}
+11
View File
@@ -0,0 +1,11 @@
``traversable``
=========
``traversable`` checks if a variable is an array or a traversable object:
.. code-block:: jinja
{# evaluates to true if the foo variable is traversable #}
{% if foo is traversable %}
...
{% endif %}
+24 -3
View File
@@ -202,6 +202,8 @@ class Twig_Extension_Core extends Twig_Extension
'divisibleby' => new Twig_Test_Node('Twig_Node_Expression_Test_Divisibleby'),
'constant' => new Twig_Test_Node('Twig_Node_Expression_Test_Constant'),
'empty' => new Twig_Test_Function('twig_test_empty'),
'array' => new Twig_Test_Function('is_array'),
'traversable' => new Twig_Test_Function('twig_test_traversable'),
);
}
@@ -984,11 +986,11 @@ else
/* used internally */
function twig_ensure_traversable($seq)
{
if (is_array($seq) || (is_object($seq) && $seq instanceof Traversable)) {
if ($seq instanceof Traversable || is_array($seq)) {
return $seq;
} else {
return array();
}
return array();
}
/**
@@ -1013,3 +1015,22 @@ function twig_test_empty($value)
return false === $value || (empty($value) && '0' != $value);
}
/**
* Checks if a variable is traversable.
*
* <pre>
* {# evaluates to true if the foo variable is an array or a traversable object #}
* {% if foo is traversable %}
* {# ... #}
* {% endif %}
* </pre>
*
* @param mixed $value A variable
*
* @return Boolean true if the value is traversable
*/
function twig_test_traversable($value)
{
return $value instanceof Traversable || is_array($value);
}
@@ -0,0 +1,16 @@
--TEST--
"is_array" test
--TEMPLATE--
{{ foo is array ? 'ok' : 'ko' }}
{{ obj is array ? 'ok' : 'ko' }}
{{ val is array ? 'ok' : 'ko' }}
--DATA--
return array(
'foo' => array(),
'obj' => new stdClass(),
'val' => 'test',
);
--EXPECT--
ok
ko
ko
@@ -0,0 +1,19 @@
--TEST--
"traversable" test
--TEMPLATE--
{{ foo is traversable ? 'ok' : 'ko' }}
{{ traversable is traversable ? 'ok' : 'ko' }}
{{ obj is traversable ? 'ok' : 'ko' }}
{{ val is traversable ? 'ok' : 'ko' }}
--DATA--
return array(
'foo' => array(),
'traversable' => new ArrayIterator(array()),
'obj' => new stdClass(),
'val' => 'test',
);
--EXPECT--
ok
ok
ko
ko