added the first and last filters (closes #951)
authorFabien Potencier <fabien.potencier@gmail.com>
Sat, 26 Jan 2013 15:59:11 +0000 (16:59 +0100)
committerFabien Potencier <fabien.potencier@gmail.com>
Sat, 26 Jan 2013 15:59:11 +0000 (16:59 +0100)
CHANGELOG
doc/filters/first.rst [new file with mode: 0644]
doc/filters/index.rst
doc/filters/last.rst [new file with mode: 0644]
lib/Twig/Extension/Core.php
test/Twig/Tests/Fixtures/filters/first.test [new file with mode: 0644]
test/Twig/Tests/Fixtures/filters/last.test [new file with mode: 0644]

index 961f836..aba90a2 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,6 @@
 * 1.12.2 (2013-XX-XX)
 
- * n/a
+ * added the first and last filter
 
 * 1.12.1 (2013-01-15)
 
diff --git a/doc/filters/first.rst b/doc/filters/first.rst
new file mode 100644 (file)
index 0000000..4295e83
--- /dev/null
@@ -0,0 +1,25 @@
+``first``
+=========
+
+.. versionadded:: 1.12.2
+    The first filter was added in Twig 1.12.2.
+
+The ``first`` filter returns the first "element" of a sequence, a mapping, or
+a string:
+
+.. code-block:: jinja
+
+    {{ [1, 2, 3, 4]|first }}
+    {# outputs 1 #}
+
+    {{ { a: 1, b: 2, c: 3, d: 4 }|first }}
+    {# outputs 1 #}
+
+    {{ '1234'|first }}
+    {# outputs 1 #}
+
+.. note::
+
+    It also works with objects implementing the `Traversable`_ interface.
+
+.. _`Traversable`: http://php.net/manual/en/class.traversable.php
index e29e3ae..888693e 100644 (file)
@@ -30,4 +30,6 @@ Filters
     raw
     merge
     slice
+    first
+    last
     trim
diff --git a/doc/filters/last.rst b/doc/filters/last.rst
new file mode 100644 (file)
index 0000000..723c0b5
--- /dev/null
@@ -0,0 +1,25 @@
+``last``
+========
+
+.. versionadded:: 1.12.2
+    The last filter was added in Twig 1.12.2.
+
+The ``last`` filter returns the last "element" of a sequence, a mapping, or
+a string:
+
+.. code-block:: jinja
+
+    {{ [1, 2, 3, 4]|last }}
+    {# outputs 4 #}
+
+    {{ { a: 1, b: 2, c: 3, d: 4 }|last }}
+    {# outputs 4 #}
+
+    {{ '1234'|last }}
+    {# outputs 4 #}
+
+.. note::
+
+    It also works with objects implementing the `Traversable`_ interface.
+
+.. _`Traversable`: http://php.net/manual/en/class.traversable.php
index fdd6c23..b777e36 100644 (file)
@@ -157,6 +157,8 @@ class Twig_Extension_Core extends Twig_Extension
             new Twig_SimpleFilter('reverse', 'twig_reverse_filter', array('needs_environment' => true)),
             new Twig_SimpleFilter('length', 'twig_length_filter', array('needs_environment' => true)),
             new Twig_SimpleFilter('slice', 'twig_slice', array('needs_environment' => true)),
+            new Twig_SimpleFilter('first', 'twig_first', array('needs_environment' => true)),
+            new Twig_SimpleFilter('last', 'twig_last', array('needs_environment' => true)),
 
             // iteration and runtime
             new Twig_SimpleFilter('default', '_twig_default_filter', array('node_class' => 'Twig_Node_Expression_Filter_Default')),
@@ -629,6 +631,36 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese
 }
 
 /**
+ * Returns the first element of the item.
+ *
+ * @param Twig_Environment $env  A Twig_Environment instance
+ * @param mixed            $item A variable
+ *
+ * @return mixed The first element of the item
+ */
+function twig_first(Twig_Environment $env, $item)
+{
+    $elements = twig_slice($env, $item, 0, 1, false);
+
+    return is_string($elements) ? $elements[0] : current($elements);
+}
+
+/**
+ * Returns the last element of the item.
+ *
+ * @param Twig_Environment $env  A Twig_Environment instance
+ * @param mixed            $item A variable
+ *
+ * @return mixed The last element of the item
+ */
+function twig_last(Twig_Environment $env, $item)
+{
+    $elements = twig_slice($env, $item, -1, 1, false);
+
+    return is_string($elements) ? $elements[0] : current($elements);
+}
+
+/**
  * Joins the values to a string.
  *
  * The separator between elements is an empty string per default, you can define it with the optional parameter.
diff --git a/test/Twig/Tests/Fixtures/filters/first.test b/test/Twig/Tests/Fixtures/filters/first.test
new file mode 100644 (file)
index 0000000..853465b
--- /dev/null
@@ -0,0 +1,14 @@
+--TEST--
+"first" filter
+--TEMPLATE--
+{{ [1, 2, 3, 4]|first }}
+{{ {a: 1, b: 2, c: 3, d: 4}|first }}
+{{ '1234'|first }}
+{{ arr|first }}
+--DATA--
+return array('arr' => new ArrayObject(array(1, 2, 3, 4)))
+--EXPECT--
+1
+1
+1
+1
diff --git a/test/Twig/Tests/Fixtures/filters/last.test b/test/Twig/Tests/Fixtures/filters/last.test
new file mode 100644 (file)
index 0000000..ca3ac0c
--- /dev/null
@@ -0,0 +1,14 @@
+--TEST--
+"last" filter
+--TEMPLATE--
+{{ [1, 2, 3, 4]|last }}
+{{ {a: 1, b: 2, c: 3, d: 4}|last }}
+{{ '1234'|last }}
+{{ arr|last }}
+--DATA--
+return array('arr' => new ArrayObject(array(1, 2, 3, 4)))
+--EXPECT--
+4
+4
+4
+4