From: Armin Ronacher Date: Fri, 13 Apr 2007 20:32:11 +0000 (+0200) Subject: [svn] added `|batch` and `|slice` jinja filters X-Git-Tag: 2.0rc1~361 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=d071f9587646501ec9d68c7aa1d24a21cfe0664a;p=jinja2.git [svn] added `|batch` and `|slice` jinja filters --HG-- branch : trunk --- diff --git a/CHANGES b/CHANGES index 18545e5..ed38941 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,10 @@ Version 1.1 - fixed severe memcaching bug. Formerly it wasn't possible to use memcaching without enabling disk cache. +- fixed a bug that allowed users to override the special names `_`, `true` etc. + +- added `batch` and `slice` filters + Version 1.0 ----------- diff --git a/docs/src/index.txt b/docs/src/index.txt index 6253ec8..9e9ad4c 100644 --- a/docs/src/index.txt +++ b/docs/src/index.txt @@ -30,7 +30,7 @@ Welcome in the Jinja documentation. - `Internationalization `_ - - `Recipies `_ + - `Developer Recipies `_ - Template Designer Documentation: @@ -38,6 +38,6 @@ Welcome in the Jinja documentation. - `Differences To Django `_ - - `Recipies `_ + - `Designer Recipies `_ There is also support via IRC on the ``#pocoo`` channel on `irc.freenode.net`. diff --git a/jinja/filters.py b/jinja/filters.py index f54aaa1..e77b891 100644 --- a/jinja/filters.py +++ b/jinja/filters.py @@ -618,6 +618,83 @@ def do_capture(name='captured', clean=False): return wrapped +def do_slice(slices, fill_with=None): + """ + Slice an iterator and return a list of lists containing + those items. Useful if you want to create a div containing + three div tags that represent columns: + + .. sourcecode:: jinja + +
+ {%- for column in items|slice(3) %} +
    + {%- for item in column %} +
  • {{ item }}
  • + {%- endfor %} +
+ {%- endfor %} +
+ + *New in Jinja 1.1* + """ + def wrapped(env, context, value): + result = [] + seq = list(value) + length = len(seq) + items_per_slice = length // slices + slices_with_extra = length % slices + offset = 0 + for slice_number in xrange(slices): + start = offset + slice_number * items_per_slice + if slice_number < slices_with_extra: + offset += 1 + end = offset + (slice_number + 1) * items_per_slice + tmp = seq[start:end] + if fill_with is not None and slice_number >= slices_with_extra: + tmp.append(fill_with) + result.append(tmp) + return result + return wrapped + + +def do_batch(linecount, fill_with=None): + """ + A filter that batches items. It works pretty much like `slice` + just the other way round. It returns a list of lists with the + given number of items. If you provide a second parameter this + is used to fill missing items. See this example: + + .. sourcecode:: jinja + + + {%- for row in items|batch(3, ' ') %} + + {%- for column in row %} + {{ column }} + {%- endfor %} + + {%- endfor %} +
+ + *New in Jinja 1.1* + """ + def wrapped(env, context, value): + result = [] + tmp = [] + for item in value: + if len(tmp) == linecount: + result.append(tmp) + tmp = [] + tmp.append(item) + if tmp: + if fill_with is not None and len(tmp) < linecount: + tmp += [fill_with] * (linecount - len(tmp)) + result.append(tmp) + return result + return wrapped + + FILTERS = { 'replace': do_replace, 'upper': do_upper, @@ -655,5 +732,7 @@ FILTERS = { 'urlize': do_urlize, 'format': do_format, 'capture': do_capture, - 'trim': do_trim + 'trim': do_trim, + 'slice': do_slice, + 'batch': do_batch } diff --git a/tests/runtime/columntest.py b/tests/runtime/columntest.py new file mode 100644 index 0000000..ebb00fc --- /dev/null +++ b/tests/runtime/columntest.py @@ -0,0 +1,57 @@ +import jdebug +from jinja import from_string + + +template = from_string(u'''\ +

Unfilled

+
+ {%- for column in items|slice(3) %} +
+
    + {%- for item in column %} +
  • {{ item }}
  • + {%- endfor %} +
+
+ {%- endfor %} +
+ +

Filled

+
+ {%- for column in items|slice(3, 'missing') %} +
+
    + {%- for item in column %} +
  • {{ item }}
  • + {%- endfor %} +
+
+ {%- endfor %} +
+ +

Filled Table

+ + {%- for row in items|batch(3, ' ') %} + + {%- for column in row %} + + {%- endfor %} + + {%- endfor %} +
{{ column }}
+ +

Unfilled Table

+ + {%- for row in items|batch(3) %} + + {%- for column in row %} + + {%- endfor %} + {%- if row|length < 3 %} + + {%- endif %} + + {%- endfor %} +
{{ column }} 
''') + +print template.render(items=range(16))