Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit c67f2da19f91342a2fe24e9b5fd781c297759af9 0 parents
@dcramer authored
Showing with 18,253 additions and 0 deletions.
  1. +10 −0 .gitignore
  2. +8 −0 AUTHORS
  3. +226 −0 CHANGES
  4. +30 −0 LICENSE
  5. +4 −0 MANIFEST.in
  6. +24 −0 Makefile
  7. +12 −0 THANKS
  8. +27 −0 TODO
  9. +111 −0 artwork/jinjalogo.svg
  10. +325 −0 docs/generate.py
  11. BIN  docs/html/jinjabanner.png
  12. BIN  docs/html/jinjalogo.png
  13. +196 −0 docs/html/style.css
  14. BIN  docs/html/watermark.png
  15. +109 −0 docs/src/altsyntax.txt
  16. +315 −0 docs/src/api.txt
  17. +228 −0 docs/src/builtins.txt
  18. +1 −0  docs/src/changelog.txt
  19. +32 −0 docs/src/debugging.txt
  20. +565 −0 docs/src/designerdoc.txt
  21. +190 −0 docs/src/devintro.txt
  22. +139 −0 docs/src/devrecipies.txt
  23. +71 −0 docs/src/escaping.txt
  24. +73 −0 docs/src/filters.txt
  25. +247 −0 docs/src/frameworks.txt
  26. +108 −0 docs/src/fromdjango.txt
  27. +113 −0 docs/src/i18n.txt
  28. +74 −0 docs/src/index.txt
  29. +186 −0 docs/src/inheritance.txt
  30. +89 −0 docs/src/installation.txt
  31. +245 −0 docs/src/loaders.txt
  32. +154 −0 docs/src/objects.txt
  33. +184 −0 docs/src/recipies.txt
  34. +186 −0 docs/src/scopes.txt
  35. +74 −0 docs/src/streaming.txt
  36. +83 −0 docs/src/templatei18n.txt
  37. +30 −0 docs/src/tests.txt
  38. +10 −0 docs/src/translators.txt
  39. +32 −0 ext/Jinja.tmbundle/Commands/Help.tmCommand
  40. +59 −0 ext/Jinja.tmbundle/Commands/Validate Syntax.tmCommand
  41. +26 −0 ext/Jinja.tmbundle/Commands/Wrap in Tag.tmCommand
  42. +26 −0 ext/Jinja.tmbundle/Commands/Wrap in Variable Tag.tmCommand
  43. +19 −0 ext/Jinja.tmbundle/Preferences/Symbol List: Blocks.tmPreferences
  44. +16 −0 ext/Jinja.tmbundle/Snippets/abs.tmSnippet
  45. +16 −0 ext/Jinja.tmbundle/Snippets/batch.tmSnippet
  46. +18 −0 ext/Jinja.tmbundle/Snippets/block.tmSnippet
  47. +16 −0 ext/Jinja.tmbundle/Snippets/capitalize.tmSnippet
  48. +16 −0 ext/Jinja.tmbundle/Snippets/capture.tmSnippet
  49. +16 −0 ext/Jinja.tmbundle/Snippets/center.tmSnippet
  50. +16 −0 ext/Jinja.tmbundle/Snippets/default.tmSnippet
  51. +16 −0 ext/Jinja.tmbundle/Snippets/dformat.tmSnippet
  52. +16 −0 ext/Jinja.tmbundle/Snippets/dictsort.tmSnippet
  53. +16 −0 ext/Jinja.tmbundle/Snippets/escape.tmSnippet
  54. +16 −0 ext/Jinja.tmbundle/Snippets/extends.tmSnippet
  55. +16 −0 ext/Jinja.tmbundle/Snippets/filesizeformat.tmSnippet
  56. +18 −0 ext/Jinja.tmbundle/Snippets/filter.tmSnippet
  57. +16 −0 ext/Jinja.tmbundle/Snippets/first.tmSnippet
  58. +16 −0 ext/Jinja.tmbundle/Snippets/float.tmSnippet
  59. +18 −0 ext/Jinja.tmbundle/Snippets/for ___ in ___.tmSnippet
  60. +16 −0 ext/Jinja.tmbundle/Snippets/format.tmSnippet
  61. +18 −0 ext/Jinja.tmbundle/Snippets/if.tmSnippet
  62. +16 −0 ext/Jinja.tmbundle/Snippets/indent.tmSnippet
  63. +16 −0 ext/Jinja.tmbundle/Snippets/int.tmSnippet
  64. +16 −0 ext/Jinja.tmbundle/Snippets/join.tmSnippet
  65. +16 −0 ext/Jinja.tmbundle/Snippets/jsonencode.tmSnippet
  66. +16 −0 ext/Jinja.tmbundle/Snippets/last.tmSnippet
  67. +16 −0 ext/Jinja.tmbundle/Snippets/length.tmSnippet
  68. +16 −0 ext/Jinja.tmbundle/Snippets/lower.tmSnippet
  69. +18 −0 ext/Jinja.tmbundle/Snippets/macro.tmSnippet
  70. +16 −0 ext/Jinja.tmbundle/Snippets/markdown.tmSnippet
  71. +16 −0 ext/Jinja.tmbundle/Snippets/pprint.tmSnippet
  72. +16 −0 ext/Jinja.tmbundle/Snippets/random.tmSnippet
  73. +18 −0 ext/Jinja.tmbundle/Snippets/raw.tmSnippet
  74. +16 −0 ext/Jinja.tmbundle/Snippets/replace.tmSnippet
  75. +16 −0 ext/Jinja.tmbundle/Snippets/reverse.tmSnippet
  76. +16 −0 ext/Jinja.tmbundle/Snippets/round.tmSnippet
  77. +16 −0 ext/Jinja.tmbundle/Snippets/rst.tmSnippet
  78. +16 −0 ext/Jinja.tmbundle/Snippets/slice.tmSnippet
  79. +16 −0 ext/Jinja.tmbundle/Snippets/sort.tmSnippet
  80. +16 −0 ext/Jinja.tmbundle/Snippets/string.tmSnippet
  81. +16 −0 ext/Jinja.tmbundle/Snippets/striptags.tmSnippet
  82. +16 −0 ext/Jinja.tmbundle/Snippets/sum.tmSnippet
  83. +16 −0 ext/Jinja.tmbundle/Snippets/textile.tmSnippet
  84. +16 −0 ext/Jinja.tmbundle/Snippets/title.tmSnippet
  85. +16 −0 ext/Jinja.tmbundle/Snippets/trim.tmSnippet
  86. +16 −0 ext/Jinja.tmbundle/Snippets/truncate.tmSnippet
  87. +16 −0 ext/Jinja.tmbundle/Snippets/upper.tmSnippet
  88. +16 −0 ext/Jinja.tmbundle/Snippets/urlencode.tmSnippet
  89. +16 −0 ext/Jinja.tmbundle/Snippets/urlize.tmSnippet
  90. +16 −0 ext/Jinja.tmbundle/Snippets/wordcount.tmSnippet
  91. +16 −0 ext/Jinja.tmbundle/Snippets/wordwrap.tmSnippet
  92. +16 −0 ext/Jinja.tmbundle/Snippets/xmlattr.tmSnippet
  93. +29 −0 ext/Jinja.tmbundle/Syntaxes/HTML (Jinja Templates).tmLanguage
  94. +518 −0 ext/Jinja.tmbundle/Syntaxes/Jinja Templates.tmLanguage
  95. +148 −0 ext/Jinja.tmbundle/info.plist
  96. +228 −0 ez_setup.py
  97. +70 −0 jdebug.py
  98. +76 −0 jinja/__init__.py
  99. +65 −0 jinja/_debugger.c
  100. +85 −0 jinja/_native.py
  101. +499 −0 jinja/_speedups.c
  102. +32 −0 jinja/constants.py
  103. +11 −0 jinja/contrib/__init__.py
  104. +301 −0 jinja/contrib/_djangosupport.py
  105. +33 −0 jinja/contrib/djangosupport.py
  106. +708 −0 jinja/datastructure.py
  107. +213 −0 jinja/debugger.py
  108. +16 −0 jinja/defaults.py
  109. +404 −0 jinja/environment.py
  110. +91 −0 jinja/exceptions.py
  111. +989 −0 jinja/filters.py
  112. +518 −0 jinja/lexer.py
  113. +825 −0 jinja/loaders.py
  114. +792 −0 jinja/nodes.py
  115. +1,187 −0 jinja/parser.py
  116. +166 −0 jinja/plugin.py
  117. +143 −0 jinja/tests.py
  118. +29 −0 jinja/translators/__init__.py
  119. +1,114 −0 jinja/translators/python.py
  120. +637 −0 jinja/utils.py
  121. +301 −0 scripts/pylintrc
  122. +6 −0 setup.cfg
  123. +158 −0 setup.py
  124. +132 −0 tests/conftest.py
  125. 0  tests/loaderres/__init__.py
  126. +1 −0  tests/loaderres/templates/brokenimport.html
  127. +1 −0  tests/loaderres/templates/foo/test.html
  128. +1 −0  tests/loaderres/templates/test.html
  129. +88 −0 tests/runtime/bigbench.py
  130. +190 −0 tests/runtime/bigtable.py
  131. +57 −0 tests/runtime/columntest.py
  132. +113 −0 tests/runtime/exception.py
  133. +8 −0 tests/runtime/inheritance.py
  134. +13 −0 tests/runtime/layout.py
  135. +37 −0 tests/runtime/modglobals.py
  136. +57 −0 tests/runtime/strange.py
  137. +12 −0 tests/runtime/super.py
  138. +12 −0 tests/runtime/templates/a.html
  139. +8 −0 tests/runtime/templates/b.html
  140. +6 −0 tests/runtime/templates/c.html
  141. +2 −0  tests/runtime/templates/included_error.html
  142. +13 −0 tests/runtime/templates/index.html
  143. +23 −0 tests/runtime/templates/layout.html
  144. +303 −0 tests/test_filters.py
  145. +81 −0 tests/test_forloop.py
  146. +94 −0 tests/test_i18n.py
  147. +33 −0 tests/test_ifcondition.py
  148. +124 −0 tests/test_inheritance.py
  149. +60 −0 tests/test_lexer.py
  150. +178 −0 tests/test_loaders.py
  151. +114 −0 tests/test_macros.py
  152. +93 −0 tests/test_parser.py
  153. +67 −0 tests/test_security.py
  154. +51 −0 tests/test_streaming.py
  155. +198 −0 tests/test_syntax.py
  156. +74 −0 tests/test_tests.py
  157. +67 −0 tests/test_undefined.py
  158. +113 −0 tests/test_various.py
10 .gitignore
@@ -0,0 +1,10 @@
+instance/
+^jinja/.*\.so$
+build/
+dist/
+Jinja.egg-info/
+jinja/*.so
+^(build|dist|Jinja\.egg-info)/
+.DS_Store
+*.pyc
+*.pyo
8 AUTHORS
@@ -0,0 +1,8 @@
+Jinja is written and maintained by Armin Ronacher <armin.ronacher@active-4.com>.
+
+Other contributors (as mentionend in :copyright:s) are:
+
+- Armin Ronacher <armin.ronacher@active-4.com>
+- Georg Brandl
+- Lawrence Journal-World.
+- Bryan McLemore
226 CHANGES
@@ -0,0 +1,226 @@
+Jinja Changelog
+===============
+
+Version 1.33373907
+------------------
+(codename: bago, release June 2007)
+
+- various small improvements in Jinja itself
+
+- fixed a bug that causes '<generator object at 0xdeadbeef>' to show up
+ if ``super()`` was used with empty parent blocks.
+
+Version 1.2
+-----------
+(codename: hatsuyuki, released Nov 17th 2007)
+
+.. admonition:: Backwards Incompatible Changes
+
+ - `call` is a keyword now
+ - the internal parser AST changed
+ - `extends` must be the first tag in a template
+ - the tuple literal yields tuples now, instead of lists.
+
+- environments now have a `translator_factory` parameter that allows
+ to change the translator without subclassing the environment.
+
+- fixed bug in buffet plugin regarding the package loader
+
+- once again improved debugger.
+
+- added `groupby` filter.
+
+- added `sameas` test function.
+
+- standalone parser. Jinja does not use the python parser any more and will
+ continue having the same semantics in any future python versions. This
+ was done in order to simplify updating Jinja to 2.6 and 3.0 and to support
+ non python syntax.
+
+- added support for ``expr1 if test else expr2`` (conditional expressions)
+
+- ``foo.0`` as alias for ``foo[0]`` is possible now. This is mainly for
+ django compatibility.
+
+- the filter operators has a much higher priority now which makes it
+ possible to do ``foo|filter + bar|filter``.
+
+- new AST. the return value of `Environment.parse` is now a Jinja AST and not
+ a Jinja-Python AST. This is also the only backwards incompatible change but
+ should not affect many users because this feature is more or less
+ undocumented and has few use cases.
+
+- tuple syntax returns tuples now and not lists any more.
+
+- the print directive and ``{{ variable }}`` syntax now accepts and implicit
+ tuple like the `for` and `cycle` tags. (``{{ 1, 2 }}`` is an implicit alias
+ for ``{{ (1, 2) }}` like ``{% for a, b in seq %}`` is for
+ ``{% for (a, b) in seq %}``.
+
+- tests called with *one* parameter don't need parentheses. This gives a more
+ natural syntax for the `sameas` test and some others:
+ ``{{ foo is sameas bar }}`` instead of ``{{ foo is sameas(bar) }}``. If you
+ however want to pass more than one argument you have to use parentheses
+ because ``{{ foo is sometest bar, baz }}`` is handled as
+ ``{{ (foo is sometest(bar), baz) }}``, so as tuple expression.
+
+- removed support for octal character definitions in strings such as
+ ``'\14'``, use ``'\x0c'`` now.
+
+- added regular expression literal. ``@/expr/flags`` equals
+ ``re.compile(r'(?flags)expr')``. This is useful for the `matching` test and
+ probably some others.
+
+- added set literal. We do not use python3's {1, 2} syntax because
+ this conflicts with the dict literal. To be compatible with the regex
+ literal we use ``@(1, 2)`` instead.
+
+- fixed bug in `get_attribute` that disallowed retreiving attributes of objects
+ without a `__class__` such as `_sre.SRE_Pattern`.
+
+- addded `django.contrib.jinja` which provides advanced support for django.
+ (thanks Bryan McLemore)
+
+- debugger is now able to rewrite the whole traceback, not only the first
+ frame. (requires the optional debugger c module which is compiled
+ automatically on installation if possible)
+
+- if the set that is postfixed with a bang (!) it acts like the python 3
+ "nonlocal" keyword. This means that you can now override variables
+ defined in the outer scope from within a loop.
+
+- ``foo ~ bar`` is now a simpler alternative to ``foo|string + bar|string``
+
+- `PackageLoader` can now work without pkg_resources too
+
+- added `getattribute` and `getitem` filter.
+
+- added support for the `pretty` library.
+
+- changed the way the `MemcachedLoaderMixin` creates the class so that it's
+ possible to hook your own client in.
+
+
+Version 1.1
+-----------
+(codename: sinka, released Jun 1, 2007)
+
+- blocks now support ``{{ super() }}`` to render the parent output.
+
+- debugging system improved, smaller filesize for the cached files.
+ Debugging works now well for any module using linecache.
+
+- ``{{ debug() }}`` can now be used to get a list of filters and
+ tags.
+
+- the template lexer keeps not track of brace, parenthesis and
+ bracket balance in order to not break variable tags apart if they
+ are configured to look like this: ``${expr}``. This also fixes
+ the problem with nested dicts in variable expressions.
+
+- it's now possible to configure the variable blocks to look the
+ same as the block delimiters. Thus you can set the syntax to something
+ like ``{ / }`` for both blocks and variables.
+
+- added whitespace management system for the template designer.
+
+- some small bugfixes.
+
+- improved security system regarding function calls and variable
+ assignment in for loops.
+
+- added `lipsum` function to generate random text.
+
+- strings without unicode characters are processed as binary strings now
+ to workaround problems with `datetime.strftime` which only accepts
+ binary strings.
+
+- it's now possible to use newlines in string literals
+
+- developer friendly traceback is now toggleable
+
+- the variable failure is now pluggable by replacing the undefined
+ singleton for an environment instance
+
+- fixed issue with old-style classes not implementing `__getitem__`
+ (thanks to Axel Böhm for discovering that bug)
+
+- added a bunch of new docstrings to the Jinja classes. Makes fun now to
+ use pydoc :-)
+
+- fixed severe memcaching bug. Formerly it wasn't possible to use memcaching
+ without enabling disk cache.
+
+- fixed a bug that allowed users to override the special names `_`, `true` etc.
+
+- added `batch` and `slice` filters for batching or slicing sequences
+
+- added `sum`, `abs`, `round` and `sort` filters. This fixes #238
+
+- added `striptags` and `xmlattr` filters for easier SGML/XML processing
+
+- the trans tag does not need explicit naming for variables with the same
+ name any more. You can now use ``{% trans foo %}`` instead of the verbose
+ version ``{% trans foo=foo %}``.
+
+- reimplemented Buffet plugin so that it works at least for pylons
+
+- added `Environment.get_translations_for_string`
+
+- fixed a bug in the parser that didn't unescape keyword arguments. (thanks
+ to Alexey Melchakov for reporting)
+
+- You can now use the environment to just tokenize a template. This can
+ be useful for syntax highlighting or other purposes.
+
+- added optional C-implementation of the context baseclass.
+
+- you can now use optional parentheses around macro defintions. Thus it's
+ possible to write ``{% macro foo(a, b, c) %}`` instead of ``{% macro
+ foo a, b, c %}``.
+
+- additional macro arguments now end up in `varargs`.
+
+- implemented the `{% call %}` block. `call` and `endcall` can still be used
+ as identifiers until Jinja 1.3
+
+- it's now possible to stream templates.
+
+- fixed a corner case when defining a block inside of a condition
+
+- the cached loader mixin is now able to cache multiple templates from
+ different loaders in the same cache folder.
+
+- Translatable strings returned by ``_()`` will leave their string formatting
+ signs untouched. Thanks to Stefan Ebner for reporting.
+
+- ``{% block name "data" %}`` is now an alias for
+ ``{% block name %}data{% endblock %}``. Note that the second argument can
+ be an expression. As soon as you specify an expression as second argument
+ the closing tag has to be omitted.
+
+- It's now possible to iterate over iterators additionally to sequences.
+ If the iterator is inifite it will crash however, so makes sure you don't
+ pass something like that to a template!
+
+- added `rendetemplate` to render included templates in an isolated
+ environment and get the outout back.
+
+- added `simplefilter` decorator.
+
+- improved ChoiceLoader error reporting (thanks to Bryan McLemore)
+
+- fixed extended slicing
+
+- reworked loader layer. All the cached loaders now have "private" non cached
+ baseclasses so that you can easily mix your own caching layers in.
+
+- added `MemcachedLoaderMixin` and `MemcachedFileSystemLoader` contributed
+ by Bryan McLemore.
+
+
+Version 1.0
+-----------
+(codename: siyutusan, released Mar 23, 2007)
+
+- Initial release
30 LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2006 by the respective authors (see AUTHORS file).
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * The names of the contributors may not be used to endorse or
+ promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4 MANIFEST.in
@@ -0,0 +1,4 @@
+include Makefile CHANGES LICENSE AUTHORS TODO ez_setup.py
+include docs/html/*
+include docs/src/*.txt
+recursive-include tests *
24 Makefile
@@ -0,0 +1,24 @@
+#
+# Jinja Makefile
+# ~~~~~~~~~~~~~~
+#
+# Shortcuts for various tasks.
+#
+# :copyright: 2007 by Armin Ronacher.
+# :license: BSD, see LICENSE for more details.
+#
+
+test:
+ @(cd tests; py.test $(TESTS))
+
+test-coverage:
+ @(cd tests; py.test -C $(TESTS))
+
+documentation:
+ @(cd docs; ./generate.py)
+
+webpage:
+ @(cd ../www; ./generate.py)
+
+pylint:
+ @pylint --rcfile scripts/pylintrc jinja
12 THANKS
@@ -0,0 +1,12 @@
+Thanks To
+=========
+
+All the people listed here helped improving Jinja a lot, provided
+patches, helped working out solutions etc. Thanks to all of you!
+
+- Ronny Pfannschmidt
+- Axel Böhm
+- Alexey Melchakov
+- Stefan Ebner
+- Bryan McLemore
+- David Cramer
27 TODO
@@ -0,0 +1,27 @@
+===================
+TODO List for Jinja
+===================
+
+1.1:
+
+ - Improve the context lookup (maybe with an optional C extension) [DONE]
+ - make Undefined exchangeable [DONE]
+ - implement block.super [DONE]
+ - Implement a `IntrospectionPrinter` that works like pprint but it outputs
+ either plain text or html. It would also have to cover changing names of
+ the special builtins True, False etc to lowercase in order to not
+ confuse people.
+ - decide on `{% call %}`
+ - speed up jinja import
+ - add optional zlib compression of template bytecode
+ - write more unittests!!!!
+ - release it and update this todo list
+
+1.2:
+
+ - `include` and `extends` should work with dynamic data too. In order to
+ support this the blocks should be stored as importable functions in the
+ generated source.
+ - add support for `{% include myfile = 'myfile.html' %}` and give the
+ template designer to access variables and macros defined in the template
+ root or requirements namespace.
111 artwork/jinjalogo.svg
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="300"
+ height="120"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.44"
+ version="1.0"
+ sodipodi:docbase="/home/blackbird/Development/jinja/trunk/artwork"
+ sodipodi:docname="jinjalogo.svg"
+ inkscape:export-filename="/home/blackbird/Development/jinja/www/static/jinjabanner.png"
+ inkscape:export-xdpi="60"
+ inkscape:export-ydpi="60">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient6558">
+ <stop
+ style="stop-color:#585858;stop-opacity:1;"
+ offset="0"
+ id="stop6560" />
+ <stop
+ style="stop-color:#4a4a4a;stop-opacity:1;"
+ offset="1"
+ id="stop6562" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6558"
+ id="radialGradient6564"
+ cx="61.297766"
+ cy="60.910986"
+ fx="61.297766"
+ fy="60.910986"
+ r="44.688254"
+ gradientTransform="matrix(1,0,0,0.945104,0,3.343747)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6558"
+ id="radialGradient6580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.945104,0.355158,3.334402)"
+ cx="61.297766"
+ cy="60.910986"
+ fx="61.297766"
+ fy="60.910986"
+ r="44.688254" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.959798"
+ inkscape:cx="145.89672"
+ inkscape:cy="59.43346"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="300px"
+ height="120px"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1396"
+ inkscape:window-height="975"
+ inkscape:window-x="0"
+ inkscape:window-y="24" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ style="font-size:12px;font-style:normal;font-weight:normal;fill:#dcdcdc;fill-opacity:1;stroke:#cbcbcb;stroke-width:0.3;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;font-family:Bitstream Vera Sans;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 165.36463,80.874808 L 165.36463,80.874808 L 153.32556,80.874808 L 153.32556,81.8344 L 147.64994,81.8344 L 147.64994,36.035583 L 165.36463,36.035583 L 165.36463,20.333129 C 170.58154,21.031083 173.07533,22.077914 172.84609,23.473621 C 172.78871,24.055258 172.21545,24.549594 171.12624,24.956624 L 171.12624,36.035583 L 189.09895,36.035583 L 189.09895,82.532286 L 183.33733,82.532286 L 183.33733,80.874808 L 171.12624,80.874808 L 171.12624,102.94548 L 165.36463,102.94548 L 165.36463,80.874808 M 153.32556,55.489173 L 153.32556,55.489173 L 165.36463,55.489173 L 165.36463,41.793146 L 153.32556,41.793146 L 153.32556,55.489173 M 171.12624,55.489173 L 171.12624,55.489173 L 183.33733,55.489173 L 183.33733,41.793146 L 171.12624,41.793146 L 171.12624,55.489173 M 183.33733,61.333977 L 183.33733,61.333977 L 171.12624,61.333977 L 171.12624,75.030006 L 183.33733,75.030006 L 183.33733,61.333977 M 165.36463,61.333977 L 165.36463,61.333977 L 153.32556,61.333977 L 153.32556,75.030006 L 165.36463,75.030006 L 165.36463,61.333977 M 132.85897,59.414792 C 137.33069,63.136883 140.99969,67.934848 143.86618,73.808701 L 139.13654,77.385372 C 137.24467,72.965445 134.6362,69.12707 131.31114,65.87024 L 131.31114,102.94548 L 125.63554,102.94548 L 125.63554,68.57455 C 122.31042,71.947693 118.52671,74.913707 114.28436,77.47261 L 109.64069,73.372526 C 121.50782,67.091566 130.62312,55.489212 136.98668,38.565417 L 116.26221,38.565417 L 116.26221,32.720615 L 125.80754,32.720615 L 125.80754,20.333129 C 130.85245,21.031083 133.31761,22.048838 133.20299,23.386383 C 133.14561,24.026183 132.57235,24.549594 131.48307,24.956624 L 131.48307,32.720615 L 140.77043,32.720615 L 143.60824,36.733469 C 140.68444,45.51526 137.10137,53.075692 132.85897,59.414792 M 254.11016,49.469901 L 254.11016,49.469901 L 254.11016,20.333129 C 259.21243,21.031083 261.67755,22.048838 261.50562,23.386383 C 261.44823,23.909869 261.04699,24.346044 260.30172,24.694917 C 260.30164,24.694986 260.30164,24.694986 260.30172,24.694917 L 260.30172,24.694917 L 259.78578,24.956624 L 259.78578,49.469901 L 277.15652,49.469901 L 277.15652,55.227471 L 259.78578,55.227471 L 259.78578,93.785712 L 281.45616,93.785712 L 281.45616,99.63051 L 232.35378,99.63051 L 232.35378,93.785712 L 254.11016,93.785712 L 254.11016,55.227471 L 236.22346,55.227471 L 236.22346,49.469901 L 254.11016,49.469901 M 225.5603,59.327554 C 231.12111,63.107798 235.62145,67.876693 239.06127,73.634235 L 234.76157,77.647079 C 231.60845,72.180322 227.82475,67.934848 223.41044,64.910648 L 223.41044,102.94548 L 217.73484,102.94548 L 217.73484,67.44049 C 212.91919,71.627831 207.70222,75.030021 202.084,77.647079 L 197.87027,73.198053 C 212.66118,66.917101 224.01239,55.372897 231.92377,38.565417 L 205.35172,38.565417 L 205.35172,32.720615 L 217.99283,32.720615 L 217.99283,20.333129 C 223.03774,21.031083 225.50291,22.048838 225.38829,23.386383 C 225.33089,24.026183 224.75765,24.549594 223.66837,24.956624 L 223.66837,32.720615 L 236.22346,32.720615 L 238.80326,36.733469 C 235.13421,45.51526 230.71987,53.046611 225.5603,59.327554"
+ id="text4761" />
+ <path
+ style="font-size:44.09793472px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#b41717;fill-opacity:1;stroke:#7f2828;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Candara;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 149.14708,37.774469 C 148.97807,41.117899 148.84526,44.824225 148.74871,48.893456 C 148.67626,52.962754 148.3818,70.641328 148.38184,75.524422 C 148.3818,79.065795 148.05588,81.991266 147.40406,84.300835 C 146.75219,86.610422 145.72612,88.557071 144.32585,90.140779 C 142.94969,91.724494 141.17522,92.901283 139.00239,93.671139 C 136.82953,94.440996 134.22211,94.825935 131.18014,94.825935 C 128.83828,94.825935 126.73787,94.59498 124.87889,94.133049 L 125.4221,89.31593 C 127.13623,90.0418 128.92278,90.404734 130.78177,90.404733 C 132.85805,90.404734 134.66875,90.140782 136.2139,89.612876 C 137.78315,89.062981 139.02651,88.216133 139.94396,87.072335 C 140.8855,85.928548 141.54942,84.520804 141.93572,82.8491 C 142.34613,81.177412 142.55134,78.988811 142.55136,76.283285 C 142.55134,66.297119 142.62852,44.659257 142.26641,37.774469 L 149.14708,37.774469 M 166.38498,80.732697 L 159.83024,80.732697 C 160.16821,76.333498 160.33723,71.307412 160.33723,65.654424 C 160.33723,59.2976 159.91471,53.963567 159.06973,49.652319 L 166.31257,48.761483 C 166.02284,53.358679 165.87799,58.98965 165.87799,65.654424 C 165.87799,70.933479 166.04699,75.959565 166.38498,80.732697 M 167.90601,39.490159 C 167.90598,40.611994 167.5076,41.590815 166.7109,42.42662 C 165.91418,43.240515 164.79155,43.647442 163.343,43.647399 C 162.11172,43.647442 161.146,43.295504 160.44588,42.591595 C 159.76988,41.865769 159.43188,40.996927 159.43188,39.98507 C 159.43188,38.885304 159.84231,37.928485 160.66315,37.114591 C 161.48399,36.30078 162.61869,35.893853 164.06727,35.893811 C 165.25023,35.893853 166.17975,36.256783 166.85575,36.982609 C 167.55588,37.686526 167.90598,38.522373 167.90601,39.490159 M 206.72748,80.732697 L 200.13651,80.732697 C 200.66763,74.947749 200.93319,68.634899 200.9332,61.794122 C 200.93319,58.406756 200.1727,56.097177 198.65174,54.865371 C 197.15487,53.61163 195.00619,52.984747 192.20564,52.984714 C 188.77731,52.984747 185.61465,54.117535 182.71753,56.383099 C 182.71753,63.883761 182.76583,72.000287 182.86238,80.732697 L 176.27142,80.732697 C 176.68182,73.254058 176.88707,67.843042 176.88707,64.499632 C 176.88707,59.352589 176.3559,54.359493 175.29363,49.520339 L 181.66734,48.695493 L 182.35539,52.720761 L 182.64511,52.720761 C 186.21823,49.773323 190.04483,48.299592 194.12499,48.299567 C 198.13265,48.299592 201.23499,49.113454 203.43201,50.741118 C 205.62895,52.346863 206.72747,55.217334 206.72748,59.352563 C 206.72747,59.770507 206.70331,60.595362 206.65507,61.827118 C 206.60675,63.058915 206.5826,63.883761 206.58262,64.30167 C 206.5826,67.975018 206.63088,73.452022 206.72748,80.732697 M 222.69791,48.695493 C 222.28747,55.514282 222.08225,62.355041 222.08225,69.21778 C 222.08225,71.043461 222.14262,73.463019 222.26332,76.476468 C 222.40822,79.467925 222.4806,81.502559 222.48063,82.580363 C 222.4806,89.685068 219.51105,93.996287 213.57195,95.514024 L 211.76124,93.006484 C 213.90995,91.356766 215.2378,89.597085 215.74478,87.727431 C 216.49321,85.043912 216.86743,79.324953 216.86743,70.570535 C 216.86743,61.178248 216.3846,54.16153 215.41887,49.520339 L 222.69791,48.695493 M 224.2551,39.490159 C 224.2551,40.611994 223.85673,41.590815 223.06006,42.42662 C 222.26332,43.240515 221.14069,43.647442 219.69213,43.647399 C 218.46084,43.647442 217.49515,43.295504 216.795,42.591595 C 216.119,41.865769 215.781,40.996927 215.781,39.98507 C 215.781,38.885304 216.19144,37.928485 217.01231,37.114591 C 217.83316,36.30078 218.96785,35.893853 220.4164,35.893811 C 221.5994,35.893853 222.52889,36.256783 223.20492,36.982609 C 223.90503,37.686526 224.2551,38.522373 224.2551,39.490159 M 259.60008,80.732697 L 253.91446,80.930661 C 253.62473,79.852857 253.47987,78.830045 253.4799,77.862216 L 253.11774,77.862216 C 250.14817,80.325772 246.10427,81.557546 240.98606,81.557547 C 238.20962,81.557546 235.8195,80.820682 233.81563,79.346948 C 231.81178,77.851221 230.80988,75.728607 230.80988,72.979099 C 230.80988,69.591724 232.37914,66.875216 235.51769,64.829574 C 238.65625,62.761967 244.48667,61.67316 253.00913,61.563165 C 253.08155,61.035275 253.11772,60.430386 253.11774,59.748497 C 253.11772,57.043003 252.32104,55.239336 250.72765,54.337474 C 249.15832,53.435661 246.76819,52.984747 243.55721,52.984714 C 239.76681,52.984747 236.03678,53.413668 232.3671,54.271484 L 232.9827,49.718301 C 236.60411,48.77251 240.76873,48.299592 245.47658,48.299567 C 249.77395,48.299592 253.09359,49.113454 255.43545,50.741118 C 257.77728,52.346863 258.94819,55.096363 258.94824,58.989625 C 258.94819,60.023469 258.88785,61.904117 258.76715,64.631608 C 258.67054,67.337133 258.62228,69.140806 258.6223,70.042632 C 258.62228,74.045913 258.94819,77.609265 259.60008,80.732697 M 253.19019,74.331856 C 253.06945,70.988469 253.00909,67.986016 253.00913,65.324484 C 248.47027,65.324498 245.01786,65.632443 242.65187,66.248318 C 238.69248,67.348131 236.71278,69.448748 236.71278,72.550177 C 236.71278,75.541643 239.03044,77.037371 243.66588,77.037366 C 247.64942,77.037371 250.82416,76.135534 253.19019,74.331856"
+ id="text3736"
+ sodipodi:nodetypes="ccsscssccscccsccccsccsccsscsssccccscscccsccccscsssccscscccscccsscsssccccccscsccscsccscscsccccssc" />
+ <path
+ style="fill:url(#radialGradient6564);fill-opacity:1.0;fill-rule:evenodd;stroke:#323232;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 105.45673,18.675923 C 105.45673,18.675923 88.211949,26.918461 74.172834,28.737898 C 60.133727,30.557333 33.360434,32.377571 28.045622,31.093256 C 22.730818,29.808941 18.915645,28.309196 18.915645,28.309196 L 20.021441,32.056583 L 16.609513,35.052471 L 17.2144,36.121726 L 18.61792,36.22764 L 22.92773,36.762252 L 23.532621,38.688909 L 25.937975,38.905784 L 27.143021,42.970927 C 27.143021,42.970927 32.254764,43.399628 33.758953,43.399628 C 35.263142,43.399628 38.271966,43.187802 38.271966,43.187802 L 38.371202,44.791657 L 39.477002,45.003495 L 39.477002,46.824227 L 37.066917,48.967759 L 37.671807,49.073671 L 37.671807,49.820127 C 37.671807,49.820127 32.255457,50.252157 30.049301,49.93109 C 27.843157,49.610006 27.440747,49.608286 27.440747,49.608286 L 27.242258,49.820127 L 27.143021,50.783455 L 27.643946,50.783455 L 27.84242,54.959544 L 38.976091,54.530844 L 38.172728,68.980747 L 38.073481,70.796442 L 28.645781,70.261816 L 28.546544,66.408513 L 30.649462,66.408513 L 30.852673,64.910557 L 32.757107,64.481857 L 33.059555,64.058192 L 25.937975,62.343374 L 20.522364,63.947229 L 21.42496,64.698732 L 22.327572,64.698732 L 22.426809,65.984848 L 24.331254,66.09076 L 24.331254,69.838147 L 22.228335,70.372777 L 22.630009,71.225146 L 23.130934,71.547931 L 23.130934,74.437917 L 24.435218,74.437917 L 24.435218,87.813529 L 22.327572,88.13632 L 22.630009,91.989617 L 23.929569,92.206492 L 23.731093,100.98236 L 29.449141,101.08826 L 28.244105,92.418334 L 36.868446,92.206492 L 36.268285,96.912181 L 35.464925,100.23086 L 44.188501,100.33677 L 44.287739,91.777793 L 50.303506,91.243181 L 50.005786,96.700351 L 49.802585,99.90807 L 54.920484,99.90807 L 54.717274,91.132217 L 55.421397,91.243181 L 55.619882,87.067076 L 54.816521,87.067076 L 54.518798,85.352258 L 54.017874,80.429702 L 54.216359,74.760706 L 55.31743,74.760706 L 55.31743,71.336105 L 53.913913,71.442015 L 54.117112,67.402096 L 55.747469,67.240708 L 55.823083,65.929374 L 56.749319,65.793192 L 57.699176,65.071956 L 51.985842,63.896802 L 46.31977,65.15265 L 46.872668,66.060507 L 47.47283,66.010066 L 48.172228,65.984848 L 48.299828,67.639144 L 49.878196,67.563497 L 49.906548,71.144447 L 43.111042,70.988097 L 43.337879,67.160002 L 43.559978,63.679927 L 43.559978,59.105378 L 43.763188,54.288748 L 57.373101,53.592733 L 73.567955,52.659674 L 73.71917,55.736265 L 73.142647,63.120082 L 72.892183,69.9945 L 66.928387,69.888585 L 66.900039,65.071956 L 69.106918,64.991267 L 69.206169,63.629486 L 70.108765,63.493308 L 70.061506,63.226006 L 70.964116,63.175568 L 71.465028,62.504773 L 64.721507,60.926122 L 58.001612,62.368592 L 58.4789,63.200785 L 59.230285,63.1453 L 59.230285,63.523577 L 60.156518,63.523577 L 60.156518,65.046738 L 62.136575,65.071956 L 62.112937,69.298485 L 60.109259,69.298485 L 60.080907,70.261816 L 60.785031,70.342507 L 60.70942,74.009202 L 62.188552,74.089909 L 62.013701,88.620507 L 60.057282,89.018952 L 60.080907,89.714967 L 60.761406,89.714967 L 60.761406,93.437137 L 61.886113,93.437137 L 61.588391,98.52109 L 61.210343,102.95945 L 68.331912,103.14605 L 68.105084,99.29275 L 67.580538,96.085028 L 67.476575,93.300955 L 73.520696,93.195041 L 73.345845,97.502272 L 73.317494,102.05159 L 76.729426,102.3189 L 81.3653,102.1323 L 82.820807,101.70358 L 82.017437,99.26753 L 81.818959,95.439438 L 81.440912,92.710853 L 87.206218,92.499027 L 86.955759,95.842931 L 86.932133,101.08826 L 89.238253,101.30009 L 91.520751,101.24965 L 92.621828,100.90165 L 91.969693,95.923633 L 91.747577,92.176239 L 92.725793,92.070324 L 92.749427,88.726422 L 93.02352,88.670945 L 92.976244,87.949712 L 91.846823,87.949712 L 91.619996,85.488427 L 91.520751,74.811143 L 92.371377,74.785924 L 92.371377,71.280616 L 92.725793,71.336105 L 92.725793,70.640088 L 91.468773,70.529127 L 91.497126,66.463987 L 93.600043,66.277382 L 93.477182,64.910557 L 94.403419,64.829863 L 94.351424,64.562549 L 95.580099,63.947229 L 89.337489,62.69138 L 82.995657,63.977495 L 83.39733,64.723951 L 84.375543,64.643256 L 84.427528,64.966046 L 85.254515,64.966046 L 85.301775,66.569901 L 87.357445,66.544681 L 87.532293,70.478688 L 80.264217,70.423216 L 79.413593,64.512124 L 78.733106,61.380041 L 78.184923,55.761484 L 78.510996,52.473053 L 92.999878,51.373557 L 93.047136,46.476221 L 93.774891,46.289613 L 93.727651,45.543159 L 93.174743,45.220372 C 93.174629,45.220372 85.252181,46.395266 82.745197,46.66284 C 82.0389,46.738209 82.09239,46.733258 81.516524,46.79397 L 81.440912,45.886118 L 78.444837,44.317564 L 78.482644,42.491786 L 79.512842,42.461518 L 79.588444,39.949808 C 79.588444,39.949808 85.728225,39.546834 88.009582,39.0117 C 90.290937,38.476559 93.524432,37.942456 93.524432,37.942456 L 95.055545,33.79662 L 98.089437,32.913987 L 98.339888,32.217972 L 105.20628,30.316548 L 105.98602,29.676006 L 103.37744,23.976741 L 103.62792,22.690624 L 104.95584,21.994611 L 105.91041,19.079404 L 105.45673,18.675923 z M 72.466874,40.403728 L 72.429067,42.476654 L 73.983813,42.542211 L 73.884576,44.509221 L 70.836515,46.506487 L 70.647496,47.081457 L 71.876167,47.091543 L 71.866712,47.575729 L 62.552432,48.029652 L 62.613863,46.652742 L 63.039175,45.966809 L 63.067524,45.528025 L 63.07698,44.579832 L 63.341609,43.949374 L 63.440849,43.439982 L 63.440849,43.076841 L 63.842533,41.47297 L 72.466874,40.403728 z M 52.987688,42.168984 L 52.760853,43.561027 L 53.488599,44.418431 L 53.441349,45.916386 L 54.117112,46.960408 L 53.942262,48.191039 L 54.443185,48.912273 L 44.939872,49.2855 L 44.916247,48.967759 L 46.017333,48.831579 L 46.069307,48.428097 L 43.66394,47.121797 L 43.536351,45.03375 L 44.689411,44.978276 L 44.788661,42.72883 L 52.987688,42.168984 z M 67.051262,74.276518 L 72.81657,74.649742 L 72.618099,82.411833 L 73.36947,88.776857 L 67.254465,88.565018 L 67.051262,74.276518 z M 28.44258,74.599304 L 37.671807,75.078442 L 36.868446,80.429702 L 36.868446,84.928593 L 37.520583,87.440302 L 28.494569,87.869006 L 28.44258,74.599304 z M 87.508658,74.649742 L 87.508658,87.924488 L 81.644113,88.353194 L 81.440912,81.342592 L 80.788764,74.811143 L 87.508658,74.649742 z M 43.087416,74.947312 L 49.906548,74.972531 L 49.977434,87.278902 L 43.611966,87.389863 L 43.285891,83.400379 L 43.262266,79.441156 L 43.087416,74.947312 z "
+ id="path4735" />
+ </g>
+</svg>
325 docs/generate.py
@@ -0,0 +1,325 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+ Generate Jinja Documentation
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Generates a bunch of html files containing the documentation.
+
+ :copyright: 2006-2007 by Armin Ronacher, Georg Brandl.
+ :license: BSD, see LICENSE for more details.
+"""
+import os
+import sys
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
+import re
+import inspect
+from datetime import datetime
+from cgi import escape
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.core import publish_parts
+from docutils.writers import html4css1
+
+from jinja import Environment
+
+from pygments import highlight
+from pygments.lexers import get_lexer_by_name
+from pygments.formatters import HtmlFormatter
+
+def generate_list_of_filters():
+ from jinja.filters import FILTERS
+ result = []
+
+ filters = {}
+ for name, f in FILTERS.iteritems():
+ if not f in filters:
+ filters[f] = ([name], inspect.getdoc(f))
+ else:
+ filters[f][0].append(name)
+ for names, _ in filters.itervalues():
+ names.sort(key=lambda x: -len(x))
+
+ for names, doc in sorted(filters.values(), key=lambda x: x[0][0].lower()):
+ name = names[0]
+ if len(names) > 1:
+ aliases = '\n\n :Aliases: %s\n' % ', '.join(names[1:])
+ else:
+ aliases = ''
+
+ doclines = []
+ for line in doc.splitlines():
+ doclines.append(' ' + line)
+ doc = '\n'.join(doclines)
+ result.append('`%s`\n%s%s' % (name, doc, aliases))
+
+ return '\n'.join(result)
+
+def generate_list_of_tests():
+ from jinja.tests import TESTS
+ result = []
+
+ tests = {}
+ for name, f in TESTS.iteritems():
+ if not f in tests:
+ tests[f] = ([name], inspect.getdoc(f))
+ else:
+ tests[f][0].append(name)
+ for names, _ in tests.itervalues():
+ names.sort(key=lambda x: -len(x))
+
+ for names, doc in sorted(tests.values(), key=lambda x: x[0][0].lower()):
+ name = names[0]
+ if len(names) > 1:
+ aliases = '\n\n :Aliases: %s\n' % ', '.join(names[1:])
+ else:
+ aliases = ''
+
+ doclines = []
+ for line in doc.splitlines():
+ doclines.append(' ' + line)
+ doc = '\n'.join(doclines)
+ result.append('`%s`\n%s%s' % (name, doc, aliases))
+
+ return '\n'.join(result)
+
+def generate_list_of_loaders():
+ from jinja import loaders as loader_module
+
+ result = []
+ loaders = []
+ for item in loader_module.__all__:
+ loaders.append(getattr(loader_module, item))
+ loaders.sort(key=lambda x: x.__name__.lower())
+
+ for loader in loaders:
+ doclines = []
+ for line in inspect.getdoc(loader).splitlines():
+ doclines.append(' ' + line)
+ result.append('`%s`\n%s' % (loader.__name__, '\n'.join(doclines)))
+
+ return '\n\n'.join(result)
+
+def generate_list_of_baseloaders():
+ from jinja import loaders as loader_module
+
+ result = []
+ loaders = []
+ for item in dir(loader_module):
+ obj = getattr(loader_module, item)
+ try:
+ if issubclass(obj, loader_module.BaseLoader) and \
+ obj.__name__ != 'BaseLoader' and \
+ obj.__name__ not in loader_module.__all__:
+ loaders.append(obj)
+ except TypeError:
+ pass
+ loaders.sort(key=lambda x: x.__name__.lower())
+
+ for loader in loaders:
+ doclines = []
+ for line in inspect.getdoc(loader).splitlines():
+ doclines.append(' ' + line)
+ result.append('`%s`\n%s' % (loader.__name__, '\n'.join(doclines)))
+
+ return '\n\n'.join(result)
+
+def generate_environment_doc():
+ from jinja.environment import Environment
+ return '%s\n\n%s' % (
+ inspect.getdoc(Environment),
+ inspect.getdoc(Environment.__init__)
+ )
+
+e = Environment()
+
+PYGMENTS_FORMATTER = HtmlFormatter(style='pastie', cssclass='syntax')
+
+LIST_OF_FILTERS = generate_list_of_filters()
+LIST_OF_TESTS = generate_list_of_tests()
+LIST_OF_LOADERS = generate_list_of_loaders()
+LIST_OF_BASELOADERS = generate_list_of_baseloaders()
+ENVIRONMENT_DOC = generate_environment_doc()
+CHANGELOG = file(os.path.join(os.path.dirname(__file__), os.pardir, 'CHANGES'))\
+ .read().decode('utf-8')
+
+FULL_TEMPLATE = e.from_string('''\
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+ <title>{{ title }} &mdash; Jinja Documentation</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <link rel="stylesheet" href="style.css" type="text/css">
+ <style type="text/css">
+ {{ style|e }}
+ </style>
+</head>
+<body>
+ <div id="content">
+ {% if file_id == 'index' %}
+ <div id="jinjalogo"></div>
+ <h2 class="subheading plain">{{ title }}</h2>
+ {% else %}
+ <h1 class="heading"><span>Jinja</span></h1>
+ <h2 class="subheading">{{ title }}</h2>
+ {% endif %}
+ {% if file_id != 'index' or toc %}
+ <div id="toc">
+ <h2>Navigation</h2>
+ <ul>
+ <li><a href="index.html">back to index</a></li>
+ </ul>
+ {% if toc %}
+ <h2>Contents</h2>
+ <ul class="contents">
+ {% for key, value in toc %}
+ <li><a href="{{ key }}">{{ value }}</a></li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ </div>
+ {% endif %}
+ <div id="contentwrapper">
+ {{ body }}
+ </div>
+ </div>
+</body>
+<!-- generated on: {{ generation_date }}
+ file id: {{ file_id }} -->
+</html>\
+''')
+
+PREPROC_TEMPLATE = e.from_string('''\
+<!-- TITLE -->{{ title }}<!-- ENDTITLE -->
+<!-- TOC -->{% for key, value in toc %}<li><a href="{{
+ key }}">{{ value }}</a></li>{% endfor %}<!-- ENDTOC -->
+<!-- BODY -->{{ body }}<!-- ENDBODY -->\
+''')
+
+def pygments_directive(name, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ try:
+ lexer = get_lexer_by_name(arguments[0])
+ except ValueError:
+ # no lexer found
+ lexer = get_lexer_by_name('text')
+ parsed = highlight(u'\n'.join(content), lexer, PYGMENTS_FORMATTER)
+ return [nodes.raw('', parsed, format="html")]
+pygments_directive.arguments = (1, 0, 1)
+pygments_directive.content = 1
+directives.register_directive('sourcecode', pygments_directive)
+
+
+def create_translator(link_style):
+ class Translator(html4css1.HTMLTranslator):
+ def visit_reference(self, node):
+ refuri = node.get('refuri')
+ if refuri is not None and '/' not in refuri and refuri.endswith('.txt'):
+ node['refuri'] = link_style(refuri[:-4])
+ html4css1.HTMLTranslator.visit_reference(self, node)
+ return Translator
+
+
+class DocumentationWriter(html4css1.Writer):
+
+ def __init__(self, link_style):
+ html4css1.Writer.__init__(self)
+ self.translator_class = create_translator(link_style)
+
+ def translate(self):
+ html4css1.Writer.translate(self)
+ # generate table of contents
+ contents = self.build_contents(self.document)
+ contents_doc = self.document.copy()
+ contents_doc.children = contents
+ contents_visitor = self.translator_class(contents_doc)
+ contents_doc.walkabout(contents_visitor)
+ self.parts['toc'] = self._generated_toc
+
+ def build_contents(self, node, level=0):
+ sections = []
+ i = len(node) - 1
+ while i >= 0 and isinstance(node[i], nodes.section):
+ sections.append(node[i])
+ i -= 1
+ sections.reverse()
+ toc = []
+ for section in sections:
+ try:
+ reference = nodes.reference('', '', refid=section['ids'][0], *section[0])
+ except IndexError:
+ continue
+ ref_id = reference['refid']
+ text = escape(reference.astext().encode('utf-8'))
+ toc.append((ref_id, text))
+
+ self._generated_toc = [('#%s' % href, caption) for href, caption in toc]
+ # no further processing
+ return []
+
+
+def generate_documentation(data, link_style):
+ writer = DocumentationWriter(link_style)
+ data = data.replace('[[list_of_filters]]', LIST_OF_FILTERS)\
+ .replace('[[list_of_tests]]', LIST_OF_TESTS)\
+ .replace('[[list_of_loaders]]', LIST_OF_LOADERS)\
+ .replace('[[list_of_baseloaders]]', LIST_OF_BASELOADERS)\
+ .replace('[[environment_doc]]', ENVIRONMENT_DOC)\
+ .replace('[[changelog]]', CHANGELOG)
+ parts = publish_parts(
+ data,
+ writer=writer,
+ settings_overrides={
+ 'initial_header_level': 2,
+ 'field_name_limit': 50,
+ }
+ )
+ return {
+ 'title': parts['title'].encode('utf-8'),
+ 'body': parts['body'].encode('utf-8'),
+ 'toc': parts['toc']
+ }
+
+
+def handle_file(filename, fp, dst, preproc):
+ now = datetime.now()
+ title = os.path.basename(filename)[:-4]
+ content = fp.read().decode('utf-8')
+ suffix = not preproc and '.html' or ''
+ parts = generate_documentation(content, (lambda x: './%s%s' % (x, suffix)))
+ result = file(os.path.join(dst, title + '.html'), 'w')
+ c = dict(parts)
+ c['style'] = PYGMENTS_FORMATTER.get_style_defs('.syntax')
+ c['generation_date'] = now
+ c['file_id'] = title
+ if preproc:
+ tmpl = PREPROC_TEMPLATE
+ else:
+ tmpl = FULL_TEMPLATE
+ result.write(tmpl.render(c).encode('utf-8'))
+ result.close()
+
+
+def run(dst, preproc, sources=(), handle_file=handle_file):
+ path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))
+ if not sources:
+ sources = [os.path.join(path, fn) for fn in os.listdir(path)]
+ for fn in sources:
+ if not os.path.isfile(fn):
+ continue
+ print 'Processing %s' % fn
+ f = open(fn)
+ try:
+ handle_file(fn, f, dst, preproc)
+ finally:
+ f.close()
+
+
+def main(dst='html/', preproc=False, *sources):
+ run(os.path.realpath(dst), str(preproc).lower() == 'true', sources)
+
+
+if __name__ == '__main__':
+ main(*sys.argv[1:])
BIN  docs/html/jinjabanner.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  docs/html/jinjalogo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
196 docs/html/style.css
@@ -0,0 +1,196 @@
+body {
+ background-color: #333;
+ margin: 0;
+ padding: 0;
+ font-family: 'Georgia', serif;
+ font-size: 15px;
+ color: #111;
+}
+
+#content {
+ background-color: white;
+ background-image: url(watermark.png);
+ padding: 10px;
+ margin: 25px;
+ border: 4px solid #ddd;
+}
+
+h1 {
+ margin: 0;
+ padding: 0;
+ height: 80px;
+ background-image: url(jinjabanner.png);
+ background-repeat: no-repeat;
+}
+
+h1 span {
+ display: none;
+}
+
+h2.subheading {
+ margin: -55px 0 35px 200px;
+ font-weight: normal;
+ font-size: 30px;
+ color: #444;
+}
+
+h2.plain {
+ margin: 0;
+}
+
+#jinjalogo {
+ background-image: url(jinjalogo.png);
+ background-repeat: no-repeat;
+ width: 400px;
+ height: 160px;
+}
+
+#contentwrapper {
+ max-width: 700px;
+ padding: 0 0 20px 18px;
+}
+
+#contentwrapper h3,
+#contentwrapper h3 a {
+ color: #b41717;
+ font-size: 26px;
+ margin: 20px 0 0 -5px;
+}
+
+#contentwrapper h4,
+#contentwrapper h4 a {
+ color: #b41717;
+ font-size: 20px;
+ margin: 20px 0 0 0;
+}
+
+table.docutils {
+ border-collapse: collapse;
+ border: 2px solid #aaa;
+ margin: 0.5em 1.5em 0.5em 1.5em;
+}
+
+table.docutils td {
+ padding: 2px;
+ border: 1px solid #ddd;
+}
+
+p, li, dd, dt, blockquote {
+ color: #333;
+}
+
+p {
+ line-height: 150%;
+ margin-bottom: 0;
+ margin-top: 10px;
+ text-align: justify;
+}
+
+hr {
+ border-top: 1px solid #ccc;
+ border-bottom: 0;
+ border-right: 0;
+ border-left: 0;
+ margin-bottom: 10px;
+ margin-top: 20px;
+}
+
+dl {
+ margin-left: 10px;
+}
+
+li, dt {
+ margin-top: 5px;
+}
+
+dt {
+ font-weight: bold;
+}
+
+th {
+ text-align: left;
+ padding: 3px;
+ background-color: #f2f2f2;
+}
+
+a {
+ color: #b41717;
+}
+
+a:hover {
+ color: #444;
+}
+
+pre {
+ background-color: #f9f9f9;
+ border-top: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ padding: 5px;
+ font-size: 13px;
+ font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+}
+
+tt {
+ font-size: 13px;
+ font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+ color: black;
+ padding: 1px 2px 1px 2px;
+ background-color: #f0f0f0;
+}
+
+cite {
+ /* abusing <cite>, it's generated by ReST for `x` */
+ font-size: 13px;
+ font-family: 'Bitstream Vera Sans Mono', 'Monaco', monospace;
+ font-weight: bold;
+ font-style: normal;
+}
+
+div.admonition {
+ margin: 10px 0 10px 0;
+ padding: 10px;
+ border: 1px solid #ccc;
+ background-color: #f8f8f8;
+}
+
+div.admonition p.admonition-title {
+ margin: -3px 0 5px 0;
+ font-weight: bold;
+ color: #b41717;
+ font-size: 16px;
+}
+
+div.admonition p {
+ margin: 0 0 0 40px;
+}
+
+#toc {
+ margin: 0 -10px 10px 15px;
+ padding: 10px;
+ width: 200px;
+ float: right;
+ background-color: #f8f8f8;
+ border: 1px solid #ccc;
+ border-right: none;
+}
+
+#toc h2 {
+ font-size: 20px;
+ margin: 0 0 10px 0;
+ padding: 0;
+ color: #444;
+}
+
+#toc ul {
+ margin: 0 0 0 30px;
+ padding: 0;
+}
+
+#toc ul + h2 {
+ margin-top: 10px;
+}
+
+#toc ul li {
+ padding: 0;
+ margin: 2px 0 2px 0;
+}
BIN  docs/html/watermark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
109 docs/src/altsyntax.txt
@@ -0,0 +1,109 @@
+==================
+Alternative Syntax
+==================
+
+Jinja allows some syntax customization for the block delimiters. Depending on
+the Jinja release more or less combinations are possible. The idea of an
+customizable syntax is that you can update existing templates from other
+template engines and programming languages easier and that you can replace
+the django like default delimiters which are not everybody's favorite.
+
+
+Configuring The Environment
+===========================
+
+For syntax configuration there are six arguments in the environment which
+are the first six for convenience. Thus those two snippets do the same:
+
+.. sourcecode:: python
+
+ env = Environment(
+ block_start_string='{%',
+ block_end_string='%}',
+ variable_start_string='{{',
+ variable_end_string='}}',
+ comment_start_string='{#',
+ comment_end_string='#}',
+ )
+
+ env = Environment('{%', '%}', '{{', '}}', '{#', '#]')
+
+
+Ruby Like Syntax
+----------------
+
+Here an example configuration for Ruby-like syntax:
+
+.. sourcecode:: python
+
+ env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>')
+
+An example template then looks like this:
+
+.. sourcecode:: rhtml
+
+ <%# example eruby like configuration for Jinja %>
+ <ul>
+ <% for item in seq %>
+ <li><%= item %></li>
+ <% end‭for %>
+ </ul>
+
+
+SGML Comment Syntax
+-------------------
+
+Here an example configuration that uses SGML comments to hide the
+processing instructions. This can be useful if you work with an WYSIWYG
+designer:
+
+.. sourcecode:: python
+
+ env = Environment('<!--', '-->', '${', '}', '<!--#', '-->')
+
+.. sourcecode:: html
+
+ <!--# example SGML comment configuration for Jinja -->
+ <ul>
+ <!-- for item in seq -->
+ <li>${item}</li>
+ <!-- endfor -->
+ </ul>
+
+
+Parenthesis Balancing
+---------------------
+
+Starting with Jinja 1.1 it's possible to use the block delimiter as a token
+in the expression. That means that you can use small delimiters like single
+braces or parenthesis. So if you want to have your variables to look like
+``${expr}`` and you still want to use dicts in such expressions you need
+Jinja 1.1 or higher.
+
+
+Block / Variable Tag Unification
+================================
+
+If variable end and start tags are `None` or look the same as block tags and
+you're running Jinja 1.1 or later the parser will switch into the
+`no_comment_block` mode. In that mode it will try to match something as block
+first and continue treating it as variable block if there is no known
+directive for that name. Example:
+
+.. sourcecode:: python
+
+ env = Environment('{', '}', None, None, '{*', '*}')
+
+This now allows smarty like templates:
+
+.. sourcecode:: smarty
+
+ {* example smarty-like configuration for Jinja *}
+ {if something == 42}
+ Something is the answer to all questions and stuff like that.
+ {else}
+ Something is {something}.
+ {endif}
+
+This feature however can cause strange looking templates because there is no
+visible difference between blocks and variables.
315 docs/src/api.txt
@@ -0,0 +1,315 @@
+=======================
+Context and Environment
+=======================
+
+The two central objects in Jinja are the `Environment` and `Context`. Both
+are designed to be subclassed by applications if they need to extend Jinja.
+
+Environment
+===========
+
+The initialization parameters are already covered in the `Quickstart`_ thus
+not repeated here.
+
+But beside those configurable instance variables there are some functions used
+in the template evaluation code you may want to override:
+
+**def** `parse` *(source, filename)*:
+
+ Parse the sourcecode and return the abstract syntax tree. This tree of
+ nodes is used by the `translators`_ to convert the template into
+ executable source- or bytecode.
+
+**def** `lex` *(source, filename)*:
+
+ Tokenize the given sourcecode and return a generator of tuples in the
+ form ``(lineno, token, value)``. The filename is just used in the
+ exceptions raised.
+
+ **New in Jinja 1.1**
+
+**def** `from_string` *(source)*:
+
+ Load and parse a template source and translate it into eval-able Python
+ code. This code is wrapped within a `Template` class that allows you to
+ render it.
+
+**def** `get_template` *(name)*:
+
+ Load a template from a loader. If the template does not exist, you will
+ get a `jinja.exceptions.TemplateNotFound` exception.
+
+**def** `to_unicode` *(self, value)*:
+
+ Called to convert variables to unicode. Per default this checks if the
+ value is already unicode. If not it's converted to unicode using the
+ charset defined on the environment.
+
+ Also `None` is converted into an empty string per default.
+
+**def** `get_translator` *(self, context)*:
+
+ Return the translator used for i18n. A translator is an object that
+ provides the two functions ``gettext(string)`` and
+ ``ngettext(singular, plural, n)``. Both of those functions have to
+ behave like the `ugettext` and `nugettext` functions described in the
+ python `gettext documentation`_.
+
+ If you don't provide a translator a default one is used to switch
+ between singular and plural forms.
+
+ Have a look at the `i18n`_ section for more information.
+
+**def** `get_translations` *(self, name)*:
+
+ Get the translations for the template `name`. Only works if a loader
+ is present. See the `i18n`_ section for more details.
+
+**def** `get_translations_for_string` *(self, string)*:
+
+ Get the translations for the string `string`. This works also if no
+ loader is present and can be used to lookup translation strings from
+ templates that are loaded from dynamic resources like databases.
+
+**def** `apply_filters` *(self, value, context, filters)*:
+
+ Now this function is a bit tricky and you usually don't have to override
+ it. It's used to apply filters on a value. The Jinja expression
+ ``{{ foo|escape|replace('a', 'b') }}`` calls the function with the
+ value of `foo` as first parameter, the current context as second and
+ a list of filters as third. The list looks like this:
+
+ .. sourcecode:: python
+
+ [('escape', ()), ('replace', (u'a', u'b'))]
+
+ As you can see the filter `escape` is called without arguments whereas
+ `replace` is called with the two literal strings ``a`` and ``b``, both
+ unicode. The filters for the names are stored on ``self.filters`` in a
+ dict. Missing filters should raise a `FilterNotFound` exception.
+
+ **Warning** this is a Jinja internal method. The actual implementation
+ and function signature might change.
+
+**def** `perform_test` *(self, context, testname, args, value, invert)*:
+
+ Like `apply_filters` you usually don't override this one. It's the
+ callback function for tests (``foo is bar`` / ``foo is not bar``).
+
+ The first parameter is the current contex, the second the name of
+ the test to perform. the third a tuple of arguments, the fourth is
+ the value to test. The last one is `True` if the test was performed
+ with the `is not` operator, `False` if with the `is` operator.
+
+ Missing tests should raise a `TestNotFound` exception.
+
+ **Warning** this is a Jinja internal method. The actual implementation
+ and function signature might change.
+
+**def** `get_attribute` *(self, obj, attribute)*:
+
+ Get `attribute` from the object provided. The default implementation
+ performs security tests.
+
+ **Warning** this is a Jinja internal method. The actual implementation
+ and function signature might change.
+
+**def** `get_attributes` *(self, obj, attributes)*:
+
+ Get some attributes from the object. If `attributes` is an empty
+ sequence the object itself is returned unchanged.
+
+**def** `call_function` *(self, f, context, args, kwargs, dyn_args, dyn_kwargs)*:
+
+ Call a function `f` with the arguments `args`, `kwargs`, `dyn_args` and
+ `dyn_kwargs` where `args` is a tuple and `kwargs` a dict. If `dyn_args`
+ is not `None` you have to add it to the arguments, if `dyn_kwargs` is
+ not `None` you have to update the `kwargs` with it.
+
+ The default implementation performs some security checks.
+
+ **Warning** this is a Jinja internal method. The actual implementation
+ and function signature might change.
+
+**def** `call_function_simple` *(self, f, context)*:
+
+ Like `call_function` but without arguments.
+
+ **Warning** this is a Jinja internal method. The actual implementation
+ and function signature might change.
+
+**def** `finish_var` *(self, value, ctx)*:
+
+ Postprocess a variable before it's sent to the template.
+
+ **Warning** this is a Jinja internal method. The actual implementation
+ and function signature might change.
+
+.. admonition:: Note
+
+ The Enviornment class is defined in `jinja.environment.Environment`
+ but imported into the `jinja` package because it's often used.
+
+Context
+=======
+
+Jinja wraps the variables passed to the template in a special class called a
+context. This context supports variables on multiple layers and lazy (deferred)
+objects. Often your application has a request object, database connection
+object or something similar you want to access in filters, functions etc.
+
+The default context object is defined in `jinja.datastructure`. If you want
+to provide your own context object always subclass the default one. This
+ensures that the class continues working after Jinja upgrades.
+
+Beacause of that you can easily subclass a context to add additional variables
+or to change the way it behaves.
+
+**def** `pop` *(self)*:
+
+ Pop the outermost layer and return it.
+
+**def** `push` *(self, data=None)*:
+
+ Push a dict to the stack or an empty layer.
+
+ Has to return the pushed object.
+
+**def** `to_dict` *(self)*:
+
+ Flatten the context and convert it into a dict.
+
+**def** `__getitem__` *(self, name)*:
+
+ Resolve an item. Per default this also resolves `Deferred` objects.
+
+**def** `__setitem__` *(self, name, value)*:
+
+ Set an item in the outermost layer.
+
+**def** `__delitem__` *(self, name)*:
+
+ Delete an item in the outermost layer. Do not raise exceptions if
+ the value does not exist.
+
+**def** `__contains__` *(self, name)*:
+
+ Return `True` if `name` exists in the context.
+
+**attribute** `cache`:
+
+ The cache is a dict which can be used by filters, test functions
+ and global objects to cache data. It's also used by the environment
+ to cache often used tests and filters.
+
+**attribute** `translate_func`:
+
+ This property is created on first access and returns a translation
+ function used by the rendering process to translate strings with the
+ translator defined on the environment.
+
+.. admonition:: Note
+
+ The context uses a stack of dicts internally to represent the
+ layers of variables. It contains at least 3 levels available on
+ the context with some attributes. Those are:
+
+ `globals`:
+
+ The reference to the global namespace of the environment.
+ It's the lowest namespace on the stack and thus immutable
+
+ `initial`:
+
+ The initial namespace. Contains the values passed to the
+ context in the render function. It also contains the resolved
+ deferred values for bot the `initial` and the `globals`
+ namespace.
+
+ `current`:
+
+ The reference to the current active namespace. When the
+ context is initialized this automatically points to an
+ empty namespace.
+
+ The number of layers on the stack are theoretically unlimited.
+ Some elements in the template language like loops, blocks,
+ macros and others push and pop the layer on entering and leaving
+ the section.
+
+ This is done in order to keep the namespace clean.
+
+ Note that since Jinja 1.1 the context object is a subclass of the
+ `BaseContext`, a much simpler class that just implements a stack
+ like namespace for python. If the `_speedups` extension was
+ compiled for jinja the base class will be
+ `jinja._speedups.BaseContext` otherwise `jinja._native.BaseContext`.
+
+ Since you cannot reproduce completely the same semantics in python
+ and the C API there are some things you should keep in mind:
+
+ - The `stack` attribute of the context maps to the real layers
+ on the stack, thus you can modify the items but the list as
+ such is meant to be read only.
+
+ - `globals`, `current` and `initial` are read only attributes that
+ map to layers on the stack which you can of course modify.
+
+
+Exceptions
+==========
+
+During parsing and evaluation Jinja raises a couple of Jinja specific
+exceptions. All of those exceptions are defined in the `jinja.exceptions`
+module and are subclasses of the `TemplateError` class defined there.
+
+Here a list of exceptions that could occur:
+
+`SecurityException`:
+
+ An exception that is raised if the template tried to access something
+ it should not access. In the default configuration this exception
+ will get caught in the Jinja rendering process and silenced.
+
+ If however the environment is configured to not silently fail it
+ could happen that this exception reaches the application.
+
+`FilterNotFound`:
+
+ Raised if the template tried to apply a filter that does not exist.
+ Since this exception is a subclass of `KeyError` too you can catch
+ it this way too.
+
+`FilterArgumentError`:
+
+ Raised if the filter received an argument that it couldn't handle.
+ It's a subclass of `TypeError` too so you can catch it this way too.
+
+`TestNotFound`:
+
+ Raised if the template tried to perform a test that does not exist.
+ Since this exception is a subclass of `KeyError` too you can catch
+ it this way too.
+
+`TestArgumentError`:
+
+ Raised if a test function received an argument that it couldn't handle.
+ It's a subclass of `TypeError` too so you can catch it this way too.
+
+`TemplateNotFound`:
+
+ Raised if a template does not exist. Subclass of `IOError` too.
+
+`TemplateSyntaxError`:
+
+ Subclass of `SyntaxError` and used to indicate an syntax error.
+
+`TemplateRuntimeError`:
+
+ Generic runtime error exception which can occour at various places.
+
+
+.. _i18n: i18n.txt
+.. _translators: translators.txt
+.. _Quickstart: devintro.txt
+.. _gettext documentation: http://docs.python.org/lib/module-gettext.html
228 docs/src/builtins.txt
@@ -0,0 +1,228 @@
+===================================
+Filters, Tests and Helper Functions
+===================================
+
+This part of the documentation lists the filter-, test- and helper functions
+you can use in templates.
+
+
+Filters
+=======
+
+In the examples above you might have noticed the pipe symbols. Pipe symbols tell
+the engine that it has to apply a filter on the variable. Here is a small example:
+
+.. sourcecode:: jinja
+
+ {{ variable|replace('foo', 'bar')|escape }}
+
+If you want, you can also put whitespace between the filters.
+
+This will look for a variable `variable`, pass it to the filter `replace`
+with the arguments ``'foo'`` and ``'bar'``, and pass the result to the filter
+`escape` that automatically XML-escapes the value. The `e` filter is an alias for
+`escape`. Here is the complete list of supported filters:
+
+[[list_of_filters]]
+
+.. admonition:: note
+
+ *Jinja 1.0 and 1.1 notice*
+
+ The filter operator has a pretty low priority in Jinja 1.0 and 1.1. If you
+ want to add fitered values you have to put them into parentheses. The same
+ applies if you want to access attributes or return values:
+
+ .. sourcecode:: jinja
+
+ correct:
+ {{ (foo|filter) + (bar|filter) }}
+ wrong:
+ {{ foo|filter + bar|filter }}
+
+ correct:
+ {{ (foo|filter).attribute }}
+ wrong:
+ {{ foo|filter.attribute }}
+
+ This changed in Jinja 1.2, from that version one the filter operator has
+ the highest priority so you can do ``foo|filter + bar|filter``.
+
+*new in Jinja 1.1*:
+
+Because the application can provide additional filters you can get a documentation
+of all the provided filters by calling ``debug.filters()``:
+
+.. sourcecode:: jinja
+
+ {{ debug.filters() }}
+ -> returns a plain text representation of all the filters
+
+ {{ debug.filters(False) }}
+ -> same as above but without the builtin ones.
+
+Tests
+=====
+
+You can use the `is` operator to perform tests on a value:
+
+.. sourcecode:: jinja
+
+ {{ 42 is numeric }} -> true
+ {{ "foobar" is numeric }} -> false
+ {{ 'FOO' is upper }} -> true
+
+These tests are especially useful when used in `if` conditions.
+
+[[list_of_tests]]
+
+*new in Jinja 1.1*:
+
+Because the application can provide additional tests you can get a documentation
+of all the provided tests by calling ``debug.tests()``:
+
+.. sourcecode:: jinja
+
+ {{ debug.tests() }}
+ -> returns a plain text representation of all the tests
+
+ {{ debug.tests(False) }}
+ -> same as above but without the builtin ones.
+
+*new in Jinja 1.2*:
+
+If a test function expects one or no argument you can leave out the parentheses.
+Previously this was only possible for text functions without arguments:
+
+.. sourcecode:: jinja
+
+ {{ foo is matching @/\s+/ }}
+ is the same as
+ {{ foo is matching(@/\s+/) }}
+
+
+Global Functions
+================
+
+Test functions and filter functions live in their own namespace. Global
+functions not. They behave like normal objects in the context. Beside the
+functions added by the application or framewhere there are two functions
+available per default:
+
+`range`
+
+ Works like the python `range function`_ just that it doesn't support
+ ranges greater than ``1000000``.
+
+`debug`
+
+ Function that outputs the contents of the context.
+
+`lipsum`
+
+ Generate some paragraphs of random text:
+
+ .. sourcecode:: jinja
+
+ {{ lipsum(5) }}
+ five html paragraphs
+
+ {{ lipsum(2, False) }}
+ two ascii only paragraphs
+
+ Per default a paragraph is between 20 and 100 words long. You can
+ override this default with the third and fourth parameter:
+
+ .. sourcecode:: jinja
+
+ {{ lipsum(10, True, 50, 200) }}
+ generate 10 HTML paragraphs between 50 and 200 words.
+
+ *new in Jinja 1.1*
+
+`watchchanges`
+
+ Jinja does not provide an django like ``{% ifchanged %}`` tag. As
+ replacement for this tag there is a special function in the namespace
+ called `watchchanges`.
+
+ You can use it like this:
+
+ .. sourcecode:: html+jinja
+
+ {% for changed, article in watchchanges(articles, 'date', 'day') %}
+ {% if changed %}<h3>{{ articles.date.day }}</h3>{% endif %}
+ <h4>{{ article.title|e }}</h4>
+ <p>{{ article.body|e }}</p>
+ {% endif %}
+
+ For each iteration `watchchanges` will check the given attribute. If it
+ changed to the former iteration the first yielded item (in this example
+ it's called `changed`) will be `true`, else `false`.
+
+ In this example `articles` is a list of articles for the template with
+ an attribute called `date.day` which represents the current day. To only
+ add a new day headline if the day has changed `watchchanges` is now told
+ to check `articles.date.days`.
+
+ If you want to observe more than one attribute you can provide pairs:
+
+ .. sourcecode:: html+jinja
+
+ {% for changed, item in watchchanges(foo, ('a', 'b'), ('a', 'c')) %}
+ ...
+ {% endfor %}
+
+ Note that if you want to watch two first level attributes you have to
+ either use the list syntax `[]` or add a colon:
+
+ .. sourcecode:: html+jinja
+
+ {% for changed, item in watchchanges(foo, ['a'], ('b',)) %}
+ ...
+ {% endfor %}
+
+ otherwise Jinja cannot differ between a pair of parentheses to group
+ expressions or the sequence syntax.
+
+ If you don't provide any arguments the value of the variable itself
+ is checked.
+
+ *new in Jinja 1.1*
+
+`rendertemplate`
+
+ Loads and renders a template with a copy of the current context. This works
+ in many situations like the ``{% include %}`` tag, just that it does not
+ include a template and merges it into the template structure but renders
+ it completely independent and returns the rendered data as string.
+
+ *new in Jinja 1.1*
+
+
+Global Constants
+================
+
+Jinja provides some special variables which cannot be overridden in templates.
+Those are not affected by the variable lookup:
+
+ `_`, `true`, `false`, `none`, `undefined`
+
+You cannot use those names for your own variables or macros. It's however no
+problem to have blocks with that name.
+
+**Notice** due to a bug in Jinja 1.0 it was possible to override `_`, `true`,
+`false`, `none` and `undefined` from the template by either using `{% set %}`
+or in a for loop. While overriding `true`, `false` etc just caused nothing
+overriding the translation marker `_` would crash the translation interface.
+If you want to use `_` for unpacking in for loops (eg. skipping items) you
+have to give it a proper name:
+
+.. sourcecode:: jinja
+
+ {% for key, ignore in mydict|dictsort %}
+ {{ key|e }}
+ {% endfor %}
+
+
+.. _range function: http://docs.python.org/tut/node6.html#SECTION006300000000000000000
1  docs/src/changelog.txt
@@ -0,0 +1 @@
+[[changelog]]
32 docs/src/debugging.txt
@@ -0,0 +1,32 @@
+===================
+Debugging Templates
+===================
+
+In order to keep templates debuggable you have to do some additional work on
+the application side. The traceback module that comes with python currently
+does not support the `__loader__` hook which is used by Jinja to provide
+templates. Although the import system was implemented three Python versions
+ago the default traceback system still doesn't support it.
+
+However most of the extended web development traceback modules have support
+for `__loader__`. Either directly or via the linecache module:
+
+- `Werkzeug Debugging Middleware`_
+- `Django`_
+- `cgitb`_
+- `EvalException`_
+
+To enable debugging you have to use one of those debugging systems or
+implement your own one with support for `__loader__`.
+
+The python implementation of the jinja debugger can only translate the first
+exception in a traceback which can lead to problematic results. If you have
+the extended debugger c extension compiled (default on unix systems but only
+available on Windows if you have a VisualStudio 2003 installation) all frames
+in the traceback will point to the correct linenumbers of the templates.
+
+
+.. _Werkzeug Debugging Middleware: http://werkzeug.pocoo.org/
+.. _Django: http://www.djangoproject.com/
+.. _cgitb: http://docs.python.org/lib/module-cgitb.html
+.. _EvalException: http://pythonpaste.org/module-paste.evalexception.html
565 docs/src/designerdoc.txt
@@ -0,0 +1,565 @@
+======================
+Designer Documentation
+======================
+
+This part of the Jinja documentaton is meant for template designers.
+
+Basics
+======
+
+The Jinja template language is designed to strike a balance between content
+and application logic. Nevertheless you can use a python like statement
+language. You don't have to know how Python works to create Jinja templates,
+but if you know it you can use some additional statements you may know from
+Python.
+
+Here is a small example template:
+
+.. sourcecode:: html+jinja
+
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+ <head>
+ <title>My Webpage</title>
+ </head>
+ <body>
+ <ul id="navigation">
+ {% for item in navigation %}
+ <li><a href="{{ item.href|e }}">{{ item.caption|e }}</a></li>
+ {% endfor %}
+ </ul>
+
+ <h1>My Webpage</h1>
+ {{ variable }}
+ </body>
+ </html>
+
+This covers the default settings. The application developer might have changed
+the syntax from ``{% foo %}`` to ``<% foo %>`` or something similar. This
+documentation just covers the default values.
+
+A variable looks like ``{{ foobar }}`` where foobar is the variable name. Inside
+of statements (``{% some content here %}``) variables are just normal names
+without the braces around it. In fact ``{{ foobar }}`` is just an alias for
+the statement ``{% print foobar %}``.
+
+Variables are coming from the context provided by the application. Normally there
+should be a documentation regarding the context contents but if you want to know
+the content of the current context, you can add this to your template:
+
+.. sourcecode:: html+jinja
+
+ <pre>{{ debug()|e }}</pre>
+
+A context isn't flat which means that each variable can has subvariables, as long
+as it is representable as python data structure. You can access attributes of
+a variable using the dot and bracket operators. The following examples show
+this:
+
+.. sourcecode:: jinja
+
+ {{ user.username }}
+ is the same as
+ {{ user['username'] }}
+ you can also use a variable to access an attribute:
+ {{ users[current_user].username }}
+ If you have numerical indices you have to use the [] syntax:
+ {{ users[0].username }}
+
+*new in Jinja 1.2*: You can now use django like attributes for integer
+indices. Thus ``{{ foo.0 }}`` is equivalent to ``{{ foo[0] }}``.
+
+
+Loops
+=====
+
+To iterate over a sequence, you can use the `for` loop. It basically looks like a
+normal Python `for` loop and works pretty much the same:
+
+.. sourcecode:: html+jinja
+
+ <h1>Members</h1>
+ <ul>
+ {% for user in users %}
+ <li>{{ loop.index }} / {{ loop.length }} - {{ user.username|escape }}</li>
+ {% else %}
+ <li><em>no users found</em></li>
+ {% endfor %}
+ </ul>
+
+*Important* Contrary to Python is the optional `else` block only
+executed if there was no iteration because the sequence was empty.
+
+Inside of a `for` loop block you can access some special variables:
+
++----------------------+----------------------------------------+
+| Variable | Description |
++======================+========================================+
+| `loop.index` | The current iteration of the loop. |
++----------------------+----------------------------------------+
+| `loop.index0` | The current iteration of the loop, |
+| | starting counting by 0. |
++----------------------+----------------------------------------+
+| `loop.revindex` | The number of iterations from the end |
+| | of the loop. |
++----------------------+----------------------------------------+
+| `loop.revindex0` | The number of iterations from the end |
+| | of the loop, starting counting by 0. |
++----------------------+----------------------------------------+
+| `loop.first` | True if first iteration. |
++----------------------+----------------------------------------+
+| `loop.last` | True if last iteration. |
++----------------------+----------------------------------------+
+| `loop.even` | True if current iteration is even. |
++----------------------+----------------------------------------+
+| `loop.odd` | True if current iteration is odd. |
++----------------------+----------------------------------------+
+| `loop.length` | Total number of items in the sequence. |
++----------------------+----------------------------------------+
+| `loop.parent` | The context of the parent loop. |
++----------------------+----------------------------------------+
+
+Loops also support recursion. Let's assume you have a sitemap where each item
+might have a number of child items. A template for that could look like this:
+
+.. sourcecode:: html+jinja
+
+ <h1>Sitemap
+ <ul id="sitemap">
+ {% for item in sitemap recursive %}
+ <li><a href="{{ item.url|e }}">{{ item.title|e }}</a>
+ {% if item.children %}<ul>{{ loop(item.children) }}</ul>{% endif %}</li>
+ {% endfor %}
+ </ul>
+
+What happens here? Basically the first thing that is different to a normal
+loop is the additional ``recursive`` modifier in the `for`-loop declaration.
+It tells the template engine that we want recursion. If recursion is enabled
+the special `loop` variable is callable. If you call it with a sequence it will
+automatically render the loop at that position with the new sequence as argument.
+
+Cycling
+=======
+
+Sometimes you might want to have different text snippets for each row in a list,
+for example to have alternating row colors. You can easily do this by using the
+``{% cycle %}`` tag:
+
+.. sourcecode:: html+jinja
+
+ <ul id="messages">
+ {% for message in messages %}
+ <li class="{% cycle 'row1', 'row2' %}">{{ message|e }}</li>
+ {% endfor %}
+ </ul>
+
+Each time Jinja encounters a `cycle` tag it will cycle through the list
+of given items and return the next one. If you pass it one item jinja assumes
+that this item is a sequence from the context and uses this:
+
+.. sourcecode:: html+jinja
+
+ <li style="color: {% cycle rowcolors %}">...</li>
+
+Conditions
+==========
+
+Jinja supports Python-like `if` / `elif` / `else` constructs:
+
+.. sourcecode:: jinja
+
+ {% if user.active %}
+ user {{ user.name|e }} is active.
+ {% elif user.deleted %}
+ user {{ user.name|e }} was deleted some time ago.
+ {% else %}
+ i don't know what's wrong with {{ user.username|e }}
+ {% endif %}
+
+If the user is active the first block is rendered. If not and the user was
+deleted the second one, in all other cases the third one.
+
+You can also use comparison operators:
+
+.. sourcecode:: html+jinja
+
+ {% if amount < 0 %}
+ <span style="color: red">{{ amount }}</span>
+ {% else %}
+ <span style="color: black">{{ amount }}</span>
+ {% endif %}
+
+.. admonition:: Note
+
+ Of course you can use `or` / `and` and parentheses to create more complex
+ conditions, but usually the logic is already handled in the application and
+ you don't have to create such complex constructs in the template code. However
+ in some situations it might be a good thing to have the abilities to create
+ them.
+
+Literals
+========
+
+For most of the builtin python types, literals exist in Jinja. The following
+table shows which syntax elements are supported:
+
+ ======================= ===================================================
+ ``"text" / 'text'`` work like python's unicode literals (u'text').
+ ``42`` integer literls.
+ ``42.0`` float literals (exponents are not supported and
+ before and after the dot digits must be present)
+ ``[1, 'two', none]`` list literal
+ ``(), (1,), (1, 2)`` tuple literals. (tuples work like lists but consume
+ less memory and are not modifyable.)
+ ``{'foo': 'bar'}`` dictionary literal
+ ``@/expr/flags`` regular expression literals. ``@/expr/flags`` is
+ equivalent to ``re.compile('(?flags)expr')`` in
+ python.
+ ``@(1, 2, 3)`` set literal. ``@(1, 2, 3)`` in Jinja is is equal to
+ ``set([1, 2, 3])`` in python.
+ ``true / false`` corresponds to `True` and `False` in python.
+ ``none`` corresponds to `None` in python.
+ ``undefined`` special Jinja undefined singleton.
+ ======================= ===================================================
+
+.. admonition:: Common Pitfalls
+
+ Keep in mind that Jinja literals, keywords and functions are all lowercase.
+ If you're used to Python you probably tried to write `True` which evaluates
+ to undefined because it simply does not exist. The correct name for the
+ true value is just `true` (lowercase).
+
+
+Operators
+=========
+
+Inside ``{{ variable }}`` blocks, `if` conditions and many other parts you can
+can use expressions. In expressions you can use any of the following operators:
+
+ ======= ===================================================================
+ ``+`` add the right operand to the left one.
+ ``{{ 1 + 2 }}`` would return ``3``.
+ ``-`` subtract the right operand from the left one.
+ ``{{ 1 - 1 }}`` would return ``0``.
+ ``/`` divide the left operand by the right one.
+ ``{{ 1 / 2 }}`` would return ``0.5``.
+ ``//`` divide the left operand by the right one and return a truncated
+ integer result: ``{{ 20 // 7 }}`` is ``2``.
+ *added in Jinja 1.1*
+ ``~`` string concatenate a value with another one. ``{{ foo ~ bar }}``
+ is equivalent to ``{{ foo|string + bar|string }}``. *added in
+ Jinja 1.1*
+ ``*`` multiply the left operand with the right one.
+ ``{{ 2 * 2 }}`` would return ``4``.
+ ``**`` raise the left operand to the power of the right
+ operand. ``{{ 2**3 }}`` would return ``8``.
+ ``%`` calculate the remainder of an integer division between the
+ left and right operand: ``{{ 11 % 7 }}`` is ``4``.
+ ``in`` perform sequence membership test. ``{{ 1 in [1,2,3] }}`` would
+ return true.
+ ``is`` perform a test on the value. See the section about
+ tests for more information.
+ ``|`` apply a filter on the value. See the section about
+ filters for more information.
+ ``and`` return true if the left and the right operand is true.
+ ``or`` return true if the left or the right operand is true.
+ ``not`` negate a statement (see below)
+ ``()`` call a callable: ``{{ user.get_username() }}``. Inside of the
+ parentheses you can use variables: ``{{ user.get(username) }}``.
+ ======= ===================================================================
+
+Note that there is no support for any bit operations or something similar.
+
+* special note regarding `not`: The `is` and `in` operators support negation
+ using an infix notation too: ``foo is not bar`` and ``foo not in bar``
+ instead of ``not foo is bar`` and ``not foo in bar``. All other expressions
+ require a prefix notation: ``not (foo and bar)``.
+
+
+With Jinja 1.2 onwards it's possible to replace basic if/else blocks with the
+inline `if` / `else` expression. The following two examples evaluate to the
+same:
+
+.. sourcecode:: jinja
+
+ {{ "something" if expr else "otherthing" }}
+
+ {% if expr %}something{% else %}otherthing{% endif %}
+
+
+Boolean Values
+==============
+
+In If-Conditions Jinja performs a boolean check. All empty values (eg: empty
+lists ``[]``, empty dicts ``{}`` etc) evaluate to `false`. Numbers that are
+equal to `0`/`0.00` are considered `false` too. The boolean value of other
+objects depends on the behavior the application developer gave it. Usually
+items are `true`.
+
+Here some examples that should explain it:
+
+.. sourcecode:: jinja
+
+ {% if [] %}
+ will always be false because it's an empty list
+
+ {% if {} %}
+ false too.
+
+ {% if ['foo'] %}
+ this is true. Because the list is not empty.
+
+ {% if "foobar" %}
+ this is also true because the string is not empty.
+
+Slicing
+=======
+
+Some objects support slicing operations. For example lists:
+
+.. sourcecode:: jinja
+
+ {% for item in items[:5] %}
+ This will only iterate over the first 5 items of the list
+
+ {% for item in items[5:10] %}
+ This will only iterate from item 5 to 10.
+
+ {% for item in items[:10:2] %}
+ This will only yield items from start to ten and only returing
+ even items.
+
+For more informations about slicing have a look at the `slicing chapter`_
+in the "Dive into Python" e-book.
+
+Macros
+======
+
+If you want to use a partial template in more than one place, you might want to
+create a macro from it:
+
+.. sourcecode:: html+jinja
+
+ {% macro show_user user %}
+ <h1>{{ user.name|e }}</h1>
+ <div class="text">
+ {{ user.description }}
+ </div>
+ {% endmacro %}
+
+Now you can use it from everywhere in the code by passing it an item:
+
+.. sourcecode:: jinja
+
+ {% for user in users %}
+ {{ show_user(user) }}
+ {% endfor %}
+
+You can also specify more than one value:
+
+.. sourcecode:: html+jinja
+
+ {% macro show_dialog title, text %}
+ <div class="dialog">
+ <h1>{{ title|e }}</h1>
+ <div class="text">{{ text|e }}</div>
+ </div>
+ {% endmacro %}
+
+ {{ show_dialog('Warning', 'something went wrong i guess') }}
+
+*Improvements in Jinja 1.1*:
+
+ Starting with Jinja 1.1 it's possible to use optional parentheses
+ around the macro arguments:
+
+ .. sourcecode:: html+jinja
+
+ {% macro foo(a, b) %}
+ ...
+ {% endmacro %}
+
+ Additionally extra arguments passed to the macro end up in the
+ special variable `varargs`. So you can have a macro like this:
+
+ .. sourcecode:: html+jinja
+
+ {% macro make_list() %}
+ {% if varargs %}
+ <ul>
+ {% for item in varargs %}
+ <li>{{ item|e }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ {% endmacro %}
+
+ {{ make_list("John", "Jane", "Marcus", "Heinrich") }}
+
+ If a macro parameter is called `varargs` the additional extra
+ arguments are not accessible.
+
+For information regarding the visibility of macros have a look at the
+`Scopes and Variable Behavior`_ section.
+
+
+Extended Macro Call
+===================
+
+*new in Jinja 1.1*
+
+Jinja 1.1 adds a new special tag that you can use to pass some evaluable
+template code to a macro. Here an example macro that uses the features of
+the ``{% call %}`` tag:
+
+.. sourcecode:: html+jinja
+
+ {% macro dialog title %}
+ <div class="dialog">
+ <h3>{{ title }}</h3>
+ <div class="text">
+ {{ caller() }}
+ </div>
+ </div>
+ {% endmacro %}
+
+Called the normal way `caller` will be undefined, but if you call it
+using the new `{% call %}` tag you can pass it some data:
+
+.. sourcecode:: html+jinja
+
+ {% call dialog('Hello World') %}
+ This is an example dialog
+ {% endcall %}
+
+Now the data wrapped will be inserted where you put the `caller` call.
+
+If you pass `caller()` some keyword arguments those are added to the
+namespace of the wrapped template data:
+
+.. sourcecode:: html+jinja
+
+ {% macro makelist items %}
+ <ul>
+ {%- for item in items %}
+ <li>{{ caller(item=item) }}</li>
+ {%- endfor %}
+ </ul>
+ {%- endmacro %}
+
+ {% call makelist([1, 2, 3, 4, 5, 6]) -%}
+ [[{{ item }}]]
+ {%- endcall %}
+
+This will then produce this output:
+
+.. sourcecode:: html
+
+ <ul>
+ <li>[[1]]</li>
+ <li>[[2]]</li>
+ <li>[[3]]</li>
+ <li>[[4]]</li>
+ <li>[[5]]</li>
+ <li>[[6]]</li>
+ </ul>
+
+
+Template Inclusion
+==================
+
+You can load another template at a given position using ``{% include %}``.
+Usually it's a better idea to use inheritance but if you for example want to
+load macros, `include` works better than `extends`:
+
+.. sourcecode:: jinja
+
+ {% include "myhelpers.html" %}
+ {{ my_helper("foo") }}
+
+If you define a macro called ``my_helper`` in ``myhelpers.html``, you can now
+use it from the template as shown above.
+
+Please keep in mind that include does not render the template indenpendently
+but includes the processing instructions into the current template. Thus if the
+included template contains a ``{% extends %}`` tag it also affects the current
+template.
+
+This is intended because it makes it possible to include macros from other
+templates.
+
+*new in Jinja 1.1* you can now render an included template to a string that is
+evaluated in an indepdendent environment by calling `rendertemplate`. See the
+documentation for this function in the `builtins`_ documentation.
+
+
+Filtering Blocks
+================
+
+Sometimes it could be a good idea to filter a complete block of text. For
+example, if you want to escape some html code:
+
+.. sourcecode:: jinja
+
+ {% filter escape %}
+ <html>
+ <code>goes here</code>
+ </html>
+ {% endfilter %}
+
+Of course you can chain filters too:
+
+.. sourcecode:: jinja
+
+ {% filter lower|escape %}
+ <B>SOME TEXT</B>
+ {% endfilter %}
+
+returns ``"&lt;b&gt;some text&lt;/b&gt;"``.
+
+
+Defining Variables
+==================
+
+You can also define variables in the namespace using the ``{% set %}`` tag:
+
+.. sourcecode:: jinja
+
+ {% set foo = 'foobar' %}
+ {{ foo }}
+
+This should ouput ``foobar``.
+
+For information regarding the visibility of variables have a look at the
+`Scopes and Variable Behavior`_ section.
+
+
+Reserved Keywords
+=================
+
+Jinja has some keywords you cannot use a variable names. This limitation
+exists to make templates look coherent. Syntax highlighters won't mess things
+up and you won't have the situation that some names work depending on the
+context.
+
+The following keywords exist and cannot be used as identifiers:
+
+ `and`, `block`, `cycle`, `elif`, `else`, `endblock`, `endfilter`,
+ `endfor`, `endif`, `endmacro`, `endraw`, `endtrans`, `extends`, `filter`,
+ `for`, `if`, `in`, `include`, `is`, `macro`, `not`, `or`, `pluralize`,
+ `print`, `raw`, `recursive`, `set`, `trans`, `call`, `endcall`
+
+If you want to use such a name you have to prefix or suffix it or use
+alternative names:
+
+.. sourcecode:: jinja
+
+ {% for macro_ in macros %}
+ {{ macro_('foo') }}
+ {% endfor %}
+
+
+.. _slicing chapter: http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
+.. _Scopes and Variable Behavior: scopes.txt
+.. _builtins: builtins.txt
190