added the cycle filter (closes #26)
authorFabien Potencier <fabien.potencier@gmail.com>
Sun, 28 Mar 2010 13:25:15 +0000 (15:25 +0200)
committerFabien Potencier <fabien.potencier@gmail.com>
Sun, 28 Mar 2010 13:25:15 +0000 (15:25 +0200)
CHANGELOG
doc/02-Twig-for-Template-Designers.markdown
lib/Twig/Extension/Core.php
test/fixtures/filters/cycle.test [new file with mode: 0644]

index 65d8c1e..c7d7143 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 * 0.9.6-DEV
 
+ * added the cycle filter
  * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
  * added a long-syntax for the set tag ({% set foo %}...{% endset %})
  * unit tests are now powered by PHPUnit
index 1c968e3..946dd6e 100644 (file)
@@ -914,6 +914,24 @@ otherwise:
     [twig]
     {{ var|odd ? 'odd' : 'even' }}
 
+### `cycle`
+
+The `cycle` filter can be used to cycle between an array of values:
+
+    [twig]
+    {% for i in 0..10 %}
+      {{ ['odd', 'even']|cycle(i) }}
+    {% endfor %}
+
+The array can contain any number of values:
+
+    [twig]
+    {% set fruits as ['apple', 'orange', 'citrus'] %}
+
+    {% for i in 0..10 %}
+      {{ fruits|cycle(i) }}
+    {% endfor %}
+
 ### `encoding`
 
 The `encoding` filter URL encode a given string.
index 6079025..3e9f908 100644 (file)
@@ -76,6 +76,7 @@ class Twig_Extension_Core extends Twig_Extension
       'sort'    => new Twig_Filter_Function('twig_sort_filter'),
       'in'      => new Twig_Filter_Function('twig_in_filter'),
       'range'   => new Twig_Filter_Function('twig_range_filter'),
+      'cycle'   => new Twig_Filter_Function('twig_cycle_filter'),
 
       // iteration and runtime
       'default' => new Twig_Filter_Function('twig_default_filter'),
@@ -202,6 +203,16 @@ function twig_range_filter($start, $end, $step = 1)
   return range($start, $end, $step);
 }
 
+function twig_cycle_filter($values, $i)
+{
+  if (!is_array($values) && !$values instanceof ArrayAccess)
+  {
+    return $values;
+  }
+
+  return $values[$i % count($values)];
+}
+
 /*
  * Each type specifies a way for applying a transformation to a string
  * The purpose is for the string to be "escaped" so it is suitable for
diff --git a/test/fixtures/filters/cycle.test b/test/fixtures/filters/cycle.test
new file mode 100644 (file)
index 0000000..d136833
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+"cycle" filter
+--TEMPLATE--
+{% for i in 0..6 %}
+{{ array1|cycle(i) }}-{{ array2|cycle(i) }}
+{% endfor %}
+--DATA--
+return array('array1' => array('odd', 'even'), 'array2' => array('apple', 'orange', 'citrus'))
+--EXPECT--
+odd-apple
+even-orange
+odd-citrus
+even-apple
+odd-orange
+even-citrus
+odd-apple