1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project# -*- coding: utf-8 -*- 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project""" 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project jinja2.filters 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ~~~~~~~~~~~~~~ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Bundled jinja filters. 7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project :copyright: (c) 2010 by the Jinja Team. 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project :license: BSD, see LICENSE for more details. 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project""" 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectimport re 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectimport math 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectfrom random import choice 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectfrom operator import itemgetter 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectfrom itertools import groupby 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectfrom jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \ 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unicode_urlencode 19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectfrom jinja2.runtime import Undefined 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectfrom jinja2.exceptions import FilterArgumentError 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectfrom jinja2._compat import next, imap, string_types, text_type, iteritems 22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project_word_re = re.compile(r'\w+(?u)') 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef contextfilter(f): 28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Decorator for marking context dependent filters. The current 29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project :class:`Context` will be passed as first argument. 30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project f.contextfilter = True 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return f 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef evalcontextfilter(f): 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Decorator for marking eval-context dependent filters. An eval 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project context object is passed as first argument. For more information 38295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner about the eval context, see :ref:`eval-context`. 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.4 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project f.evalcontextfilter = True 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return f 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef environmentfilter(f): 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Decorator for marking evironment dependent filters. The current 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project :class:`Environment` is passed to the filter as first argument. 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project f.environmentfilter = True 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return f 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef make_attrgetter(environment, attribute): 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Returns a callable that looks up the given attribute from a 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project passed object with the rules of the environment. Dots are allowed 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project to access attributes of attributes. Integer parts in paths are 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project looked up as integers. 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if not isinstance(attribute, string_types) \ 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project or ('.' not in attribute and not attribute.isdigit()): 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return lambda x: environment.getitem(x, attribute) 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project attribute = attribute.split('.') 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project def attrgetter(item): 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for part in attribute: 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if part.isdigit(): 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project part = int(part) 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project item = environment.getitem(item, part) 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return item 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return attrgetter 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_forceescape(value): 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Enforce HTML escaping. This will probably double escape variables.""" 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if hasattr(value, '__html__'): 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project value = value.__html__() 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return escape(text_type(value)) 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_urlencode(value): 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Escape strings for use in URLs (uses UTF-8 encoding). It accepts both 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dictionaries and regular strings as well as pairwise iterables. 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.7 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project itemiter = None 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if isinstance(value, dict): 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project itemiter = iteritems(value) 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project elif not isinstance(value, string_types): 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project itemiter = iter(value) 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except TypeError: 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pass 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if itemiter is None: 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return unicode_urlencode(value) 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return u'&'.join(unicode_urlencode(k) + '=' + 97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unicode_urlencode(v) for k, v in itemiter) 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@evalcontextfilter 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_replace(eval_ctx, s, old, new, count=None): 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Return a copy of the value with all occurrences of a substring 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project replaced with a new one. The first argument is the substring 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project that should be replaced, the second is the replacement string. 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project If the optional third argument ``count`` is given, only the first 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ``count`` occurrences are replaced: 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ "Hello World"|replace("Hello", "Goodbye") }} 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> Goodbye World 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ "aaaaargh"|replace("a", "d'oh, ", 2) }} 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> d'oh, d'oh, aaargh 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if count is None: 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = -1 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if not eval_ctx.autoescape: 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return text_type(s).replace(text_type(old), text_type(new), count) 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if hasattr(old, '__html__') or hasattr(new, '__html__') and \ 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project not hasattr(s, '__html__'): 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project s = escape(s) 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project s = soft_unicode(s) 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return s.replace(soft_unicode(old), soft_unicode(new), count) 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_upper(s): 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Convert a value to uppercase.""" 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return soft_unicode(s).upper() 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_lower(s): 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Convert a value to lowercase.""" 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return soft_unicode(s).lower() 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@evalcontextfilter 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_xmlattr(_eval_ctx, d, autospace=True): 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Create an SGML/XML attribute string based on the items in a dict. 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project All values that are neither `none` nor `undefined` are automatically 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project escaped: 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: html+jinja 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <ul{{ {'class': 'my_list', 'missing': none, 147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'id': 'list-%d'|format(variable)}|xmlattr }}> 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ... 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </ul> 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Results in something like this: 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: html 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <ul class="my_list" id="list-42"> 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ... 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </ul> 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project As you can see it automatically prepends a space in front of the item 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if the filter returned something unless the second parameter is false. 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = u' '.join( 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project u'%s="%s"' % (escape(key), escape(value)) 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for key, value in iteritems(d) 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if value is not None and not isinstance(value, Undefined) 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ) 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if autospace and rv: 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = u' ' + rv 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if _eval_ctx.autoescape: 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = Markup(rv) 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return rv 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_capitalize(s): 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Capitalize a value. The first character will be uppercase, all others 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lowercase. 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return soft_unicode(s).capitalize() 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_title(s): 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Return a titlecased version of the value. I.e. words will start with 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project uppercase letters, all remaining characters are lowercase. 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = [] 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for item in re.compile(r'([-\s]+)(?u)').split(s): 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if not item: 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv.append(item[0].upper() + item[1:].lower()) 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ''.join(rv) 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_dictsort(value, case_sensitive=False, by='key'): 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Sort a dict and yield (key, value) pairs. Because python dicts are 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsorted you may want to use this function to order them by either 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project key or value: 1970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% for item in mydict|dictsort %} 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sort the dict by key, case insensitive 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% for item in mydict|dictsort(true) %} 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sort the dict by key, case sensitive 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% for item in mydict|dictsort(false, 'value') %} 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sort the dict by key, case insensitive, sorted 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project normally and ordered by value. 209a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang """ 210295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if by == 'key': 211295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner pos = 0 212a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang elif by == 'value': 213a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang pos = 1 214a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang else: 215a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang raise FilterArgumentError('You can only sort by either ' 216a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang '"key" or "value"') 217a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang def sort_func(item): 218a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang value = item[pos] 219a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if isinstance(value, string_types) and not case_sensitive: 220a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang value = value.lower() 221a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return value 222a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 223a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return sorted(value.items(), key=sort_func) 224a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 225a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 226a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang@environmentfilter 227a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wangdef do_sort(environment, value, reverse=False, case_sensitive=False, 228a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang attribute=None): 229a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang """Sort an iterable. Per default it sorts ascending, if you pass it 230a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang true as first argument it will reverse the sorting. 231a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 232a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang If the iterable is made of strings the third parameter can be used to 233a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang control the case sensitiveness of the comparison which is disabled by 234a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang default. 235a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 236a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang .. sourcecode:: jinja 237a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 238a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang {% for item in iterable|sort %} 239a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ... 240295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner {% endfor %} 241a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 242295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner It is also possible to sort by an attribute (for example to sort 243295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner by the date of an object) by specifying the `attribute` parameter: 244a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 245a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang .. sourcecode:: jinja 246a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 247a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang {% for item in iterable|sort(attribute='date') %} 248a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang ... 249a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang {% endfor %} 250a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 251a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang .. versionchanged:: 2.6 252a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang The `attribute` parameter was added. 253a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang """ 254a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if not case_sensitive: 255a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang def sort_func(item): 256a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if isinstance(item, string_types): 257a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang item = item.lower() 258a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return item 259a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang else: 260a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sort_func = None 261a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if attribute is not None: 262a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang getter = make_attrgetter(environment, attribute) 263a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang def sort_func(item, processor=sort_func or (lambda x: x)): 264a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return processor(getter(item)) 265a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return sorted(value, key=sort_func, reverse=reverse) 266a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 267a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 268a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wangdef do_default(value, default_value=u'', boolean=False): 269a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang """If the value is undefined it will return the passed default value, 270a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang otherwise the value of the variable: 271a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 272a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang .. sourcecode:: jinja 273a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 274a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang {{ my_variable|default('my_variable is not defined') }} 275a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 276a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang This will output the value of ``my_variable`` if the variable was 277e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang defined, otherwise ``'my_variable is not defined'``. If you want 278a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang to use default with variables that evaluate to false you have to 279295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner set the second parameter to `true`: 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 281a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang .. sourcecode:: jinja 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ ''|default('the string was empty', true) }} 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if isinstance(value, Undefined) or (boolean and not value): 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return default_value 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return value 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@evalcontextfilter 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_join(eval_ctx, value, d=u'', attribute=None): 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Return a string which is the concatenation of the strings in the 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sequence. The separator between elements is an empty string per 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project default, you can define it with the optional parameter: 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ [1, 2, 3]|join('|') }} 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> 1|2|3 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ [1, 2, 3]|join }} 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> 123 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project It is also possible to join certain attributes of an object: 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 306a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang .. sourcecode:: jinja 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ users|join(', ', attribute='username') }} 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.6 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project The `attribute` parameter was added. 312a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang """ 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if attribute is not None: 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project value = imap(make_attrgetter(eval_ctx.environment, attribute), value) 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project # no automatic escaping? joining is a lot eaiser then 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if not eval_ctx.autoescape: 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return text_type(d).join(imap(text_type, value)) 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project # if the delimiter doesn't have an html representation we check 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project # if any of the items has. If yes we do a coercion to Markup 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if not hasattr(d, '__html__'): 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project value = list(value) 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do_escape = False 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for idx, item in enumerate(value): 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if hasattr(item, '__html__'): 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do_escape = True 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project value[idx] = text_type(item) 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if do_escape: 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project d = escape(d) 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project d = text_type(d) 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return d.join(value) 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project # no html involved, to normal joining 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return soft_unicode(d).join(imap(soft_unicode, value)) 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_center(value, width=80): 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Centers the value in a field of a given width.""" 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return text_type(value).center(width) 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@environmentfilter 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_first(environment, seq): 347aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich """Return the first item of a sequence.""" 348aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich try: 349aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich return next(iter(seq)) 350aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich except StopIteration: 351aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich return environment.undefined('No first item, sequence was empty.') 352aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@environmentfilter 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_last(environment, seq): 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Return the last item of a sequence.""" 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return next(iter(reversed(seq))) 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except StopIteration: 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return environment.undefined('No last item, sequence was empty.') 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@environmentfilter 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_random(environment, seq): 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Return a random item from the sequence.""" 366aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich try: 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return choice(seq) 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except IndexError: 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return environment.undefined('No random item, sequence was empty.') 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_filesizeformat(value, binary=False): 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Format the value like a 'human-readable' file size (i.e. 13 kB, 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 4.1 MB, 102 Bytes, etc). Per default decimal prefixes are used (Mega, 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Giga, etc.), if the second parameter is set to `True` the binary 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prefixes are used (Mebi, Gibi). 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bytes = float(value) 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project base = binary and 1024 or 1000 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prefixes = [ 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'KiB' or 'kB'), 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'MiB' or 'MB'), 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'GiB' or 'GB'), 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'TiB' or 'TB'), 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'PiB' or 'PB'), 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'EiB' or 'EB'), 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'ZiB' or 'ZB'), 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (binary and 'YiB' or 'YB') 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ] 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if bytes == 1: 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return '1 Byte' 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project elif bytes < base: 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return '%d Bytes' % bytes 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for i, prefix in enumerate(prefixes): 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unit = base ** (i + 2) 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if bytes < unit: 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return '%.1f %s' % ((base * bytes / unit), prefix) 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return '%.1f %s' % ((base * bytes / unit), prefix) 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_pprint(value, verbose=False): 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Pretty print a variable. Useful for debugging. 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project With Jinja 1.2 onwards you can pass it a parameter. If this parameter 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project is truthy the output will be more verbose (this requires `pretty`) 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return pformat(value, verbose=verbose) 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@evalcontextfilter 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_urlize(eval_ctx, value, trim_url_limit=None, nofollow=False): 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Converts URLs in plain text into clickable links. 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project If you pass the filter an additional integer it will shorten the urls 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project to that number. Also a third argument exists that makes the urls 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project "nofollow": 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ mytext|urlize(40, true) }} 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project links are shortened to 40 chars and defined with rel="nofollow" 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = urlize(value, trim_url_limit, nofollow) 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if eval_ctx.autoescape: 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = Markup(rv) 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return rv 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_indent(s, width=4, indentfirst=False): 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Return a copy of the passed string, each line indented by 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 4 spaces. The first line is not indented. If you want to 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project change the number of spaces or indent the first line too 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project you can pass additional parameters to the filter: 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ mytext|indent(2, true) }} 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project indent by two spaces and indent the first line too. 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project indention = u' ' * width 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = (u'\n' + indention).join(s.splitlines()) 443a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if indentfirst: 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = indention + rv 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return rv 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_truncate(s, length=255, killwords=False, end='...'): 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Return a truncated copy of the string. The length is specified 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project with the first parameter which defaults to ``255``. If the second 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project parameter is ``true`` the filter will cut the text at length. Otherwise 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project it will discard the last word. If the text was in fact 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project truncated it will append an ellipsis sign (``"..."``). If you want a 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project different ellipsis sign than ``"..."`` you can specify it using the 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project third parameter. 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ "foo bar"|truncate(5) }} 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> "foo ..." 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ "foo bar"|truncate(5, True) }} 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> "foo b..." 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if len(s) <= length: 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return s 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project elif killwords: 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return s[:length] + end 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project words = s.split(' ') 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = [] 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project m = 0 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for word in words: 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project m += len(word) + 1 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if m > length: 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result.append(word) 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result.append(end) 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return u' '.join(result) 478e3b631da8034f7c6ecc6d809cd9e46d306215c32Xianzhu Wang 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@environmentfilter 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_wordwrap(environment, s, width=79, break_long_words=True, 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project wrapstring=None): 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Return a copy of the string passed to the filter wrapped after 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ``79`` characters. You can override this default using the first 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project parameter. If you set the second parameter to `false` Jinja will not 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project split words apart if they are longer than `width`. By default, the newlines 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project will be the default newlines for the environment, but this can be changed 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project using the wrapstring keyword argument. 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.7 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Added support for the `wrapstring` parameter. 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if not wrapstring: 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project wrapstring = environment.newline_sequence 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project import textwrap 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return wrapstring.join(textwrap.wrap(s, width=width, expand_tabs=False, 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project replace_whitespace=False, 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break_long_words=break_long_words)) 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_wordcount(s): 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Count the words in that string.""" 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return len(_word_re.findall(s)) 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_int(value, default=0): 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Convert the value into an integer. If the 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project conversion doesn't work it will return ``0``. You can 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project override this default using the first parameter. 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return int(value) 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except (TypeError, ValueError): 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project # this quirk is necessary so that "42.23"|int gives 42. 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return int(float(value)) 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except (TypeError, ValueError): 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return default 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_float(value, default=0.0): 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Convert the value into a floating point number. If the 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project conversion doesn't work it will return ``0.0``. You can 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project override this default using the first parameter. 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return float(value) 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except (TypeError, ValueError): 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return default 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_format(value, *args, **kwargs): 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Apply python string formatting on an object: 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 536a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang .. sourcecode:: jinja 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ "%s - %s"|format("Hello?", "Foo!") }} 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> Hello? - Foo! 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if args and kwargs: 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project raise FilterArgumentError('can\'t handle positional and keyword ' 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'arguments at the same time') 544a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return soft_unicode(value) % (kwargs or args) 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_trim(value): 548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Strip leading and trailing whitespace.""" 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return soft_unicode(value).strip() 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_striptags(value): 553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Strip SGML/XML tags and replace adjacent whitespace by one space. 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if hasattr(value, '__html__'): 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project value = value.__html__() 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Markup(text_type(value)).striptags() 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_slice(value, slices, fill_with=None): 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Slice an iterator and return a list of lists containing 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project those items. Useful if you want to create a div containing 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project three ul tags that represent columns: 564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: html+jinja 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <div class="columwrapper"> 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- for column in items|slice(3) %} 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <ul class="column-{{ loop.index }}"> 570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- for item in column %} 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <li>{{ item }}</li> 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- endfor %} 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </ul> 574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- endfor %} 575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </div> 576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project If you pass it a second argument it's used to fill missing 578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project values on the last iteration. 579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project seq = list(value) 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = len(seq) 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project items_per_slice = length // slices 583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project slices_with_extra = length % slices 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = 0 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for slice_number in range(slices): 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = offset + slice_number * items_per_slice 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if slice_number < slices_with_extra: 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset += 1 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = offset + (slice_number + 1) * items_per_slice 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tmp = seq[start:end] 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if fill_with is not None and slice_number >= slices_with_extra: 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tmp.append(fill_with) 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project yield tmp 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_batch(value, linecount, fill_with=None): 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project A filter that batches items. It works pretty much like `slice` 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project just the other way round. It returns a list of lists with the 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project given number of items. If you provide a second parameter this 601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project is used to fill up missing items. See this example: 602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: html+jinja 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <table> 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- for row in items|batch(3, ' ') %} 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <tr> 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- for column in row %} 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <td>{{ column }}</td> 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- endfor %} 611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </tr> 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {%- endfor %} 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </table> 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = [] 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tmp = [] 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for item in value: 618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if len(tmp) == linecount: 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project yield tmp 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tmp = [] 621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tmp.append(item) 622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if tmp: 623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if fill_with is not None and len(tmp) < linecount: 624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tmp += [fill_with] * (linecount - len(tmp)) 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project yield tmp 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_round(value, precision=0, method='common'): 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Round the number to a given precision. The first 630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project parameter specifies the precision (default is ``0``), the 631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project second the rounding method: 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project - ``'common'`` rounds either up or down 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project - ``'ceil'`` always rounds up 635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project - ``'floor'`` always rounds down 636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project If you don't specify a method ``'common'`` is used. 638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ 42.55|round }} 642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> 43.0 643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ 42.55|round(1, 'floor') }} 644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> 42.5 645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Note that even if rounded to 0 precision, a float is returned. If 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project you need a real integer, pipe it through `int`: 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ 42.55|round|int }} 652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project -> 43 653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if not method in ('common', 'ceil', 'floor'): 655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project raise FilterArgumentError('method must be common, ceil or floor') 656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if method == 'common': 657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return round(value, precision) 658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project func = getattr(math, method) 659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return func(value * (10 ** precision)) / (10 ** precision) 660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@environmentfilter 663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_groupby(environment, value, attribute): 664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Group a sequence of objects by a common attribute. 665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project If you for example have a list of dicts or objects that represent persons 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project with `gender`, `first_name` and `last_name` attributes and you want to 668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project group all users by genders you can do something like the following 669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project snippet: 670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: html+jinja 672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <ul> 674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% for group in persons|groupby('gender') %} 675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <li>{{ group.grouper }}<ul> 676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% for person in group.list %} 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <li>{{ person.first_name }} {{ person.last_name }}</li> 678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% endfor %}</ul></li> 679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% endfor %} 680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </ul> 681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Additionally it's possible to use tuple unpacking for the grouper and 683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project list: 684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: html+jinja 686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project <ul> 688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% for grouper, list in persons|groupby('gender') %} 689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ... 690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {% endfor %} 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project </ul> 692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project As you can see the item we're grouping by is stored in the `grouper` 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project attribute and the `list` contains all the objects that have this grouper 695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project in common. 696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionchanged:: 2.6 698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project It's now possible to use dotted notation to group by the child 699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project attribute of another attribute. 700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project expr = make_attrgetter(environment, attribute) 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return sorted(map(_GroupTuple, groupby(sorted(value, key=expr), expr))) 703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass _GroupTuple(tuple): 706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project __slots__ = () 707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project grouper = property(itemgetter(0)) 708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project list = property(itemgetter(1)) 709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project def __new__(cls, xxx_todo_changeme): 711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (key, value) = xxx_todo_changeme 712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tuple.__new__(cls, (key, list(value))) 713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@environmentfilter 716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_sum(environment, iterable, attribute=None, start=0): 717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Returns the sum of a sequence of numbers plus the value of parameter 718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'start' (which defaults to 0). When the sequence is empty it returns 719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start. 720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project It is also possible to sum up only certain attributes: 722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Total: {{ items|sum(attribute='price') }} 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionchanged:: 2.6 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project The `attribute` parameter was added to allow suming up over 729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project attributes. Also the `start` parameter was moved on to the right. 730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if attribute is not None: 732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterable = imap(make_attrgetter(environment, attribute), iterable) 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return sum(iterable, start) 734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_list(value): 737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Convert the value into a list. If it was a string the returned list 738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project will be a list of characters. 739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return list(value) 741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_mark_safe(value): 744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Mark the value as safe which means that in an environment with automatic 745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project escaping enabled this variable will not be escaped. 746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Markup(value) 748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_mark_unsafe(value): 751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Mark a value as unsafe. This is the reverse operation for :func:`safe`.""" 752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return text_type(value) 753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_reverse(value): 756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Reverse the object or return an iterator the iterates over it the other 757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project way round. 758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if isinstance(value, string_types): 760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return value[::-1] 761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return reversed(value) 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except TypeError: 764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv = list(value) 766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project rv.reverse() 767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return rv 768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except TypeError: 769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project raise FilterArgumentError('argument must be iterable') 770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@environmentfilter 773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_attr(environment, obj, name): 774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Get an attribute of an object. ``foo|attr("bar")`` works like 775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ``foo["bar"]`` just that always an attribute is returned and items are not 776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project looked up. 777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project See :ref:`Notes on subscriptions <notes-on-subscriptions>` for more details. 779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project name = str(name) 782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except UnicodeError: 783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pass 784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project value = getattr(obj, name) 787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except AttributeError: 788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pass 789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if environment.sandboxed and not \ 791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project environment.is_safe_attribute(obj, name, value): 792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return environment.unsafe_undefined(obj, name) 793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return value 794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return environment.undefined(obj=obj, name=name) 795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@contextfilter 798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_map(*args, **kwargs): 799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Applies a filter on a sequence of objects or looks up an attribute. 800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project This is useful when dealing with lists of objects but you are really 801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project only interested in a certain value of it. 802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project The basic usage is mapping on an attribute. Imagine you have a list 804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project of users but you are only interested in a list of usernames: 805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Users on this page: {{ users|map(attribute='username')|join(', ') }} 809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Alternatively you can let it invoke a filter by passing the name of the 811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project filter and the arguments afterwards. A good example would be applying a 812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project text conversion filter on a sequence: 813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Users on this page: {{ titles|map('lower')|join(', ') }} 817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.7 819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project context = args[0] 821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project seq = args[1] 822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if len(args) == 2 and 'attribute' in kwargs: 824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project attribute = kwargs.pop('attribute') 825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if kwargs: 826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project raise FilterArgumentError('Unexpected keyword argument %r' % 827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next(iter(kwargs))) 828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project func = make_attrgetter(context.environment, attribute) 829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project name = args[2] 832aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich args = args[3:] 833aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich except LookupError: 834aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich raise FilterArgumentError('map requires a filter argument') 835aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich func = lambda item: context.environment.call_filter( 836aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich name, item, args, kwargs, context=context) 837aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 838aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich if seq: 839aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich for item in seq: 840aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich yield func(item) 841aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 842aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 843aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich@contextfilter 844295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turnerdef do_select(*args, **kwargs): 845295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner """Filters a sequence of objects by appying a test to either the object 846295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner or the attribute and only selecting the ones with the test succeeding. 847aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 848aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich Example usage: 849aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 850aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich .. sourcecode:: jinja 851aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 852aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich {{ numbers|select("odd") }} 853aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.7 855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return _select_or_reject(args, kwargs, lambda x: x, False) 857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@contextfilter 860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_reject(*args, **kwargs): 861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Filters a sequence of objects by appying a test to either the object 862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project or the attribute and rejecting the ones with the test succeeding. 863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Example usage: 865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ numbers|reject("odd") }} 869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.7 871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return _select_or_reject(args, kwargs, lambda x: not x, False) 873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@contextfilter 876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_selectattr(*args, **kwargs): 877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Filters a sequence of objects by appying a test to either the object 878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project or the attribute and only selecting the ones with the test succeeding. 879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Example usage: 881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 882295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner .. sourcecode:: jinja 883295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 884295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner {{ users|selectattr("is_active") }} 885295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner {{ users|selectattr("email", "none") }} 886aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 887aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich .. versionadded:: 2.7 888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return _select_or_reject(args, kwargs, lambda x: x, True) 890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project@contextfilter 893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef do_rejectattr(*args, **kwargs): 894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """Filters a sequence of objects by appying a test to either the object 895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project or the attribute and rejecting the ones with the test succeeding. 896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. sourcecode:: jinja 898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ users|rejectattr("is_active") }} 900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project {{ users|rejectattr("email", "none") }} 901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project .. versionadded:: 2.7 903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project """ 904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return _select_or_reject(args, kwargs, lambda x: not x, True) 905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectdef _select_or_reject(args, kwargs, modfunc, lookup_attr): 908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project context = args[0] 909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project seq = args[1] 910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if lookup_attr: 911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project attr = args[2] 913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except LookupError: 914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project raise FilterArgumentError('Missing parameter for attribute name') 915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project transfunc = make_attrgetter(context.environment, attr) 916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project off = 1 917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else: 918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project off = 0 919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project transfunc = lambda x: x 920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project try: 922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project name = args[2 + off] 923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project args = args[3 + off:] 924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project func = lambda item: context.environment.call_test( 925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project name, item, args, kwargs) 926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project except LookupError: 927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project func = bool 928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if seq: 930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for item in seq: 931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if modfunc(func(transfunc(item))): 932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project yield item 933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source ProjectFILTERS = { 936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'attr': do_attr, 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'replace': do_replace, 938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'upper': do_upper, 939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'lower': do_lower, 940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'escape': escape, 941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'e': escape, 942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'forceescape': do_forceescape, 943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'capitalize': do_capitalize, 944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'title': do_title, 945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'default': do_default, 946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'd': do_default, 947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'join': do_join, 948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'count': len, 949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'dictsort': do_dictsort, 950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'sort': do_sort, 951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'length': len, 952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'reverse': do_reverse, 953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'center': do_center, 954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'indent': do_indent, 955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'title': do_title, 956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'capitalize': do_capitalize, 957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'first': do_first, 958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 'last': do_last, 959a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 'map': do_map, 960295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'random': do_random, 961295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'reject': do_reject, 962295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'rejectattr': do_rejectattr, 963295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'filesizeformat': do_filesizeformat, 964295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'pprint': do_pprint, 965a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 'truncate': do_truncate, 966295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'wordwrap': do_wordwrap, 967295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'wordcount': do_wordcount, 968295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'int': do_int, 969295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'float': do_float, 970295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'string': soft_unicode, 971295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'list': do_list, 972295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'urlize': do_urlize, 973a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 'format': do_format, 974a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 'trim': do_trim, 975a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 'striptags': do_striptags, 976295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'select': do_select, 977295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'selectattr': do_selectattr, 978295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'slice': do_slice, 979295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'batch': do_batch, 980295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'sum': do_sum, 981295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'abs': abs, 982295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'round': do_round, 983295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'groupby': do_groupby, 984a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 'safe': do_mark_safe, 985295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'xmlattr': do_xmlattr, 986295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 'urlencode': do_urlencode 987295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner} 988295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner