dbfdg 3 Gg6@sdZddlZddlZddlZddlZddlmZddlmZm Z ddl m Z ddl m Z mZmZmZmZmZmZddlmZddlmZdd lmZmZmZmZmZejd ejZ ejd ejZ!d d Z"ddZ#ddZ$ddZ%dddZ&ddZ'ddZ(e#dddZ)ddZ*ddZ+ejd ej,d!Z-e#dd#d$Z.d%d&Z/d'd(Z0dd+d,Z1e$dd-d.Z2e$dd/d0Z3d1d2Z4e$dd3d4Z5e$dd5d6Z6dd8d9Z7e#dd:d;Z8dd=d>Z9e$d?d@Z:e$dAdBZ;e"dCdDZe#ddIdJZ?ddLdMZ@e$ddPdQZAe$ddSdTZBdUdVZCddXdYZDdd[d\ZEd]d^ZFd_d`ZGdadbZHddcddZIddedfZJddhdiZKe djdkdlgZLeMjNeL_NeMjOeL_Oe$dmdnZPe$ddodpZQdqdrZRdsdtZSdudvZTdwdxZUe$dydzZVe"d{d|ZWe"d}d~ZXe"ddZYe"ddZZe"ddZ[e#dddZ\ddZ]ddZ^ddZ_e`eVeJe/e9eae7e7e1eee=e:eEe'eFePe@eDe8e;eaeRe+eWe5e6e>eHsz#make_attrgetter...cs.xD]}j||}qWdk r*|}|S)N)getitem)itempart) attribute environment postprocessrr attrgetterLs  z#make_attrgetter..attrgetter)rrsplit)r(r'r)r*r)r'r(r)rmake_attrgetter?s  r,cCst|dr|j}tt|S)zCEnforce HTML escaping. This will probably double escape variables.__html__)hasattrr-rr)rrrrdo_forceescapeXs r/c Cshd}t|trt|}n,t|tsDy t|}Wntk rBYnX|dkrTt|Sdjdd|DS)zEscape strings for use in URLs (uses UTF-8 encoding). It accepts both dictionaries and regular strings as well as pairwise iterables. .. versionadded:: 2.7 N&css*|]"\}}t|dt|ddVqdS)=T)Zfor_qsN)r )r kvrrr oszdo_urlencode..)rdictrriter TypeErrorr join)rZitemiterrrr do_urlencode_s     r9cCst|dkr d}|js,t|jt|t||St|dsLt|drVt|d rVt|}nt|}|jt|t||S)aReturn a copy of the value with all occurrences of a substring replaced with a new one. The first argument is the substring that should be replaced, the second is the replacement string. If the optional third argument ``count`` is given, only the first ``count`` occurrences are replaced: .. sourcecode:: jinja {{ "Hello World"|replace("Hello", "Goodbye") }} -> Goodbye World {{ "aaaaargh"|replace("a", "d'oh, ", 2) }} -> d'oh, d'oh, aaargh Nr-) autoescaperreplacer.rr )eval_ctxsoldnewcountrrr do_replacets  rCcCs t|jS)zConvert a value to uppercase.)r upper)r?rrrdo_uppersrEcCs t|jS)zConvert a value to lowercase.)r r)r?rrrdo_lowersrFz[\s/>=])flagsTcCsg}xb|jD]V\}}|dkst|tr*qtj|dk rFtd||jt|dt|dqWdj|}|r|rd|}|j rt |}|S)aCreate an SGML/XML attribute string based on the items in a dict. **Values** that are neither ``none`` nor ``undefined`` are automatically escaped, safely allowing untrusted user input. User input should not be used as **keys** to this filter. If any key contains a space, ``/`` solidus, ``>`` greater-than sign, or ``=`` equals sign, this fails with a ``ValueError``. Regardless of this, user input should never be used as keys to this filter, or must be separately validated first. .. sourcecode:: html+jinja ... Results in something like this: .. sourcecode:: html
    ...
As you can see it automatically prepends a space in front of the item if the filter returned something unless the second parameter is false. Nz%Invalid character in attribute name: z="" ) itemsrr _attr_key_research ValueErrorappendrr8r<r)Z _eval_ctxdZ autospacerJkeyrrvrrr do_xmlattrs" rRcCs t|jS)zYCapitalize a value. The first character will be uppercase, all others lowercase. )r capitalize)r?rrr do_capitalizesrTcCsdjddtjt|DS)zReturn a titlecased version of the value. I.e. words will start with uppercase letters, all remaining characters are lowercase. cSs,g|]$}|r|dj|ddjqS)rr:N)rDr)r r%rrrr"szdo_title..)r8_word_beginning_split_rer+r )r?rrrdo_titlesrWFrPcsD|dkrdn|dkrdntdfdd}t|j||dS) afSort a dict and yield (key, value) pairs. Because python dicts are unsorted you may want to use this function to order them by either key or value: .. sourcecode:: jinja {% for item in mydict|dictsort %} sort the dict by key, case insensitive {% for item in mydict|dictsort(reverse=true) %} sort the dict by key, case insensitive, reverse order {% for item in mydict|dictsort(true) %} sort the dict by key, case sensitive {% for item in mydict|dictsort(false, 'value') %} sort the dict by value, case insensitive rPrrr:z,You can only sort by either "key" or "value"cs|}st|}|S)N)r)r%r)case_sensitiveposrr sort_funcszdo_dictsort..sort_func)rPreverse)rsortedrJ)rrXZbyr[rZr)rXrYr do_dictsortsr]cCs$t|||stndd}t|||dS)aSort an iterable. Per default it sorts ascending, if you pass it true as first argument it will reverse the sorting. If the iterable is made of strings the third parameter can be used to control the case sensitiveness of the comparison which is disabled by default. .. sourcecode:: jinja {% for item in iterable|sort %} ... {% endfor %} It is also possible to sort by an attribute (for example to sort by the date of an object) by specifying the `attribute` parameter: .. sourcecode:: jinja {% for item in iterable|sort(attribute='date') %} ... {% endfor %} .. versionchanged:: 2.6 The `attribute` parameter was added. N)r))rPr[)r,rr\)r(rr[rXr'key_funcrrrdo_sort sr_ccsNt|||stndd}t}x,|D]$}||}||kr"|j||Vq"WdS)aReturns a list of unique items from the the given iterable. .. sourcecode:: jinja {{ ['foo', 'bar', 'foobar', 'FooBar']|unique }} -> ['foo', 'bar', 'foobar'] The unique items are yielded in the same order as their first occurrence in the iterable passed to the filter. :param case_sensitive: Treat upper and lower case strings as distinct. :param attribute: Filter objects with unique values for this attribute. N)r))r,rsetadd)r(rrXr'getterseenr%rPrrr do_unique.s  rdc CsXt|}y t|}Wntk r.|jdSXt|||s>tnd}|t|g||dS)Nz'No aggregated item, sequence was empty.)rP)r6next StopIteration undefinedr,rr)r(rfuncrXr'itfirstr^rrr _min_or_maxKs  rkcCst||t||S)aReturn the smallest item from the sequence. .. sourcecode:: jinja {{ [1, 2, 3]|min }} -> 1 :param case_sensitive: Treat upper and lower case strings as distinct. :param attribute: Get the object with the max value of this attribute. )rkmin)r(rrXr'rrrdo_minZs rmcCst||t||S)aReturn the largest item from the sequence. .. sourcecode:: jinja {{ [1, 2, 3]|max }} -> 3 :param case_sensitive: Treat upper and lower case strings as distinct. :param attribute: Get the object with the max value of this attribute. )rkmax)r(rrXr'rrrdo_maxis rorUcCst|ts|r| r|S|S)aIf the value is undefined it will return the passed default value, otherwise the value of the variable: .. sourcecode:: jinja {{ my_variable|default('my_variable is not defined') }} This will output the value of ``my_variable`` if the variable was defined, otherwise ``'my_variable is not defined'``. If you want to use default with variables that evaluate to false you have to set the second parameter to `true`: .. sourcecode:: jinja {{ ''|default('the string was empty', true) }} )rr )rZ default_valueZbooleanrrr do_defaultxsrpcCs|dk rtt|j||}|js4t|jtt|St|dst|}d}x0t|D]$\}}t|drld}qTt|||<qTW|rt |}nt|}|j|St |jtt |S)a#Return a string which is the concatenation of the strings in the sequence. The separator between elements is an empty string per default, you can define it with the optional parameter: .. sourcecode:: jinja {{ [1, 2, 3]|join('|') }} -> 1|2|3 {{ [1, 2, 3]|join }} -> 123 It is also possible to join certain attributes of an object: .. sourcecode:: jinja {{ users|join(', ', attribute='username') }} .. versionadded:: 2.6 The `attribute` parameter was added. Nr-FT) rr,r(r<rr8r.list enumeraterr )r>rrOr'Z do_escapeidxr%rrrdo_joins     rtPcCst|j|S)z.Centers the value in a field of a given width.)rcenter)rwidthrrr do_centersrxc Cs,y tt|Stk r&|jdSXdS)z$Return the first item of a sequence.z"No first item, sequence was empty.N)rer6rfrg)r(seqrrrdo_firsts rzc Cs0yttt|Stk r*|jdSXdS)z#Return the last item of a sequence.z!No last item, sequence was empty.N)rer6reversedrfrg)r(ryrrrdo_lastsr|c Cs,y tj|Stk r&|jjdSXdS)z'Return a random item from the sequence.z#No random item, sequence was empty.N)randomZchoice IndexErrorr(rg)contextryrrr do_randoms rcCst|}|rdpd}|rdpd|r&dp(d|r0dp2d|r:d p`` tag: .. sourcecode:: jinja {{ mytext|urlize(40, target='_blank') }} .. versionchanged:: 2.8+ The *target* parameter was added. rUnofollowz urlize.relNz urlize.targetrI)reltarget) r(policiesr`r+raupdater8r\r r<r)r>rZtrim_url_limitrrrrrQrrr do_urlizes rcs|dk rtjtddd|}|d7}d||rFdj|j}n6|j}|jd}|r||ddjfdd |D7}|r|}|S) aReturn a copy of the string with each line indented by 4 spaces. The first line and blank lines are not indented by default. :param width: Number of spaces to indent by. :param first: Don't skip indenting the first line. :param blank: Don't skip indenting empty lines. .. versionchanged:: 2.10 Blank lines are not indented by default. Rename the ``indentfirst`` argument to ``first``. Nz1The "indentfirst" argument is renamed to "first".r) stacklevel rIrc3s|]}|r|n|VqdS)Nr)r line) indentionrrr4Mszdo_indent..)warningswarnDeprecationWarningr8 splitlinespop)r?rwrjZblankZ indentfirstrQlinesr)rr do_indent-s" r...cCs|dkr|jd}|t|ks2tdt||f|dksFtd|t|||krZ|S|rv|d|t||S|d|t|jddd}||S)aReturn a truncated copy of the string. The length is specified with the first parameter which defaults to ``255``. If the second parameter is ``true`` the filter will cut the text at length. Otherwise it will discard the last word. If the text was in fact truncated it will append an ellipsis sign (``"..."``). If you want a different ellipsis sign than ``"..."`` you can specify it using the third parameter. Strings that only exceed the length by the tolerance margin given in the fourth parameter will not be truncated. .. sourcecode:: jinja {{ "foo bar baz qux"|truncate(9) }} -> "foo..." {{ "foo bar baz qux"|truncate(9, True) }} -> "foo ba..." {{ "foo bar baz qux"|truncate(11) }} -> "foo bar baz qux" {{ "foo bar baz qux"|truncate(11, False, '...', 0) }} -> "foo bar..." The default leeway on newer Jinja2 versions is 5 and was 0 before but can be reconfigured globally. Nztruncate.leewayzexpected length >= %s, got %srzexpected leeway >= 0, got %srIr:)rlenAssertionErrorrsplit)envr?lengthZ killwordsendZleewayresultrrr do_truncateVs   rOcCs,|s |j}ddl}|j|j||dd|dS)a Return a copy of the string passed to the filter wrapped after ``79`` characters. You can override this default using the first parameter. If you set the second parameter to `false` Jinja will not split words apart if they are longer than `width`. By default, the newlines will be the default newlines for the environment, but this can be changed using the wrapstring keyword argument. .. versionadded:: 2.7 Added support for the `wrapstring` parameter. rNF)rwZ expand_tabsZreplace_whitespacebreak_long_words)Znewline_sequencetextwrapr8Zwrap)r(r?rwrZ wrapstringrrrr do_wordwrap{s rcCsttj|S)zCount the words in that string.)r_word_refindall)r?rrr do_wordcountsr cCs`yt|trt||St|Sttfk rZy tt|Sttfk rT|SXYnXdS)aConvert the value into an integer. If the conversion doesn't work it will return ``0``. You can override this default using the first parameter. You can also override the default base (10) in the second parameter, which handles input with prefixes such as 0b, 0o and 0x for bases 2, 8 and 16 respectively. The base is ignored for decimal numbers and non-string values. N)rrrr7rMr)rdefaultrrrrdo_ints    rc Cs&yt|Sttfk r |SXdS)zConvert the value into a floating point number. If the conversion doesn't work it will return ``0.0``. You can override this default using the first parameter. N)rr7rM)rrrrrdo_floatsrcOs |r|rtdt||p|S)z Apply python string formatting on an object: .. sourcecode:: jinja {{ "%s - %s"|format("Hello?", "Foo!") }} -> Hello? - Foo! z>can't handle positional and keyword arguments at the same time)rr )rargskwargsrrr do_formats rcCs t|jS)z&Strip leading and trailing whitespace.)r strip)rrrrdo_trimsrcCs"t|dr|j}tt|jS)zFStrip SGML/XML tags and replace adjacent whitespace by one space. r-)r.r-rr striptags)rrrr do_striptagss rc cst|}t|}||}||}d}xht|D]\}|||} ||krN|d7}||d|} || | } |dk r||kr| j|| Vq.WdS)aESlice an iterator and return a list of lists containing those items. Useful if you want to create a div containing three ul tags that represent columns: .. sourcecode:: html+jinja
{%- for column in items|slice(3) %}
    {%- for item in column %}
  • {{ item }}
  • {%- endfor %}
{%- endfor %}
If you pass it a second argument it's used to fill missing values on the last iteration. rr:N)rqrrangerN) rZslices fill_withryrZitems_per_sliceZslices_with_extraoffsetZ slice_numberstartrtmprrrdo_slices   rccsjg}x,|D]$}t||kr$|Vg}|j|q W|rf|dk r`t||kr`||g|t|7}|VdS)a  A filter that batches items. It works pretty much like `slice` just the other way round. It returns a list of lists with the given number of items. If you provide a second parameter this is used to fill up missing items. See this example: .. sourcecode:: html+jinja {%- for row in items|batch(3, ' ') %} {%- for column in row %} {%- endfor %} {%- endfor %}
{{ column }}
N)rrN)rZ linecountrrr%rrrdo_batchs  rcommoncCsD|dkrtd|dkr"t||Stt|}||d|d|S)aRound the number to a given precision. The first parameter specifies the precision (default is ``0``), the second the rounding method: - ``'common'`` rounds either up or down - ``'ceil'`` always rounds up - ``'floor'`` always rounds down If you don't specify a method ``'common'`` is used. .. sourcecode:: jinja {{ 42.55|round }} -> 43.0 {{ 42.55|round(1, 'floor') }} -> 42.5 Note that even if rounded to 0 precision, a float is returned. If you need a real integer, pipe it through `int`: .. sourcecode:: jinja {{ 42.55|round|int }} -> 43 rceilfloorz$method must be common, ceil or floorr)rrr)rroundgetattrmath)rZ precisionmethodrhrrrdo_rounds   r _GroupTupleZgrouperrqcCs&t||}ddtt||d|DS)aGroup a sequence of objects by a common attribute. If you for example have a list of dicts or objects that represent persons with `gender`, `first_name` and `last_name` attributes and you want to group all users by genders you can do something like the following snippet: .. sourcecode:: html+jinja
    {% for group in persons|groupby('gender') %}
  • {{ group.grouper }}
      {% for person in group.list %}
    • {{ person.first_name }} {{ person.last_name }}
    • {% endfor %}
  • {% endfor %}
Additionally it's possible to use tuple unpacking for the grouper and list: .. sourcecode:: html+jinja
    {% for grouper, list in persons|groupby('gender') %} ... {% endfor %}
As you can see the item we're grouping by is stored in the `grouper` attribute and the `list` contains all the objects that have this grouper in common. .. versionchanged:: 2.6 It's now possible to use dotted notation to group by the child attribute of another attribute. cSsg|]\}}t|t|qSr)rrq)r rPvaluesrrrr"hszdo_groupby..)rP)r,rr\)r(rr'exprrrr do_groupby@s' rcCs"|dk rtt|||}t||S)aReturns the sum of a sequence of numbers plus the value of parameter 'start' (which defaults to 0). When the sequence is empty it returns start. It is also possible to sum up only certain attributes: .. sourcecode:: jinja Total: {{ items|sum(attribute='price') }} .. versionchanged:: 2.6 The `attribute` parameter was added to allow suming up over attributes. Also the `start` parameter was moved on to the right. N)rr,sum)r(iterabler'rrrrdo_sumlsrcCst|S)zkConvert the value into a list. If it was a string the returned list will be a list of characters. )rq)rrrrdo_listsrcCst|S)zMark the value as safe which means that in an environment with automatic escaping enabled this variable will not be escaped. )r)rrrr do_mark_safesrcCst|S)zHMark a value as unsafe. This is the reverse operation for :func:`safe`.)r)rrrrdo_mark_unsafesrcCslt|tr|dddSyt|Stk rfyt|}|j|Stk r`tdYnXYnXdS)z\Reverse the object or return an iterator that iterates over it the other way round. Nr:zargument must be iterabler;)rrr{r7rqr[r)rrQrrr do_reverses rc CsHyt||Wn,tk r:t||s6|j||dSYnX|j||S)a Get an attribute of an object. ``foo|attr("bar")`` works like ``foo.bar``, but returns undefined instead of falling back to ``foo["bar"]`` if the attribute doesn't exist. See :ref:`Notes on subscriptions ` for more details. )objname)rAttributeErrorr.rgr)r(rrrrrdo_attrs  rcos.t||\}}|r*x|D]}||VqWdS)aApplies a filter on a sequence of objects or looks up an attribute. This is useful when dealing with lists of objects but you are really only interested in a certain value of it. The basic usage is mapping on an attribute. Imagine you have a list of users but you are only interested in a list of usernames: .. sourcecode:: jinja Users on this page: {{ users|map(attribute='username')|join(', ') }} Alternatively you can let it invoke a filter by passing the name of the filter and the arguments afterwards. A good example would be applying a text conversion filter on a sequence: .. sourcecode:: jinja Users on this page: {{ titles|map('lower')|join(', ') }} .. versionadded:: 2.7 N) prepare_map)rrryrhr%rrrdo_maps rcOst||dddS)aFilters a sequence of objects by applying a test to each object, and only selecting the objects with the test succeeding. If no test is specified, each object will be evaluated as a boolean. Example usage: .. sourcecode:: jinja {{ numbers|select("odd") }} {{ numbers|select("odd") }} {{ numbers|select("divisibleby", 3) }} {{ numbers|select("lessthan", 42) }} {{ strings|select("equalto", "mystring") }} .. versionadded:: 2.7 cSs|S)Nr)r!rrrszdo_select..F)select_or_reject)rrrrr do_selectsrcOst||dddS)a6Filters a sequence of objects by applying a test to each object, and rejecting the objects with the test succeeding. If no test is specified, each object will be evaluated as a boolean. Example usage: .. sourcecode:: jinja {{ numbers|reject("odd") }} .. versionadded:: 2.7 cSs| S)Nr)r!rrrrszdo_reject..F)r)rrrrr do_rejectsrcOst||dddS)aFilters a sequence of objects by applying a test to the specified attribute of each object, and only selecting the objects with the test succeeding. If no test is specified, the attribute's value will be evaluated as a boolean. Example usage: .. sourcecode:: jinja {{ users|selectattr("is_active") }} {{ users|selectattr("email", "none") }} .. versionadded:: 2.7 cSs|S)Nr)r!rrrrszdo_selectattr..T)r)rrrrr do_selectattrsrcOst||dddS)aFilters a sequence of objects by applying a test to the specified attribute of each object, and rejecting the objects with the test succeeding. If no test is specified, the attribute's value will be evaluated as a boolean. .. sourcecode:: jinja {{ users|rejectattr("is_active") }} {{ users|rejectattr("email", "none") }} .. versionadded:: 2.7 cSs| S)Nr)r!rrrr!szdo_rejectattr..T)r)rrrrr do_rejectattrsrcCsD|jj}|d}|d}|dk r0t|}||d<t|fd|i|S)aDumps a structure to JSON so that it's safe to use in ``