^instance$
^instance/
^jinja2/.*\.so$
-^docs/_.*
+^docs/_build
^(build|dist|Jinja2\.egg-info)/
\.py[co]$
\.DS_Store$
-Jinja Changelog
+Jinja2 Changelog
===============
-Version 1.3
+Version 2.0
-----------
-(codename to be selected, release around February 2007)
+(codename to be selected, release around July 2008)
-Version 1.2
------------
-(codename to be 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
+- initial release of Jinja2
--- /dev/null
+body {
+ background-color: #333;
+ margin: 0;
+ padding: 0;
+ font-family: 'Georgia', serif;
+ font-size: 15px;
+ color: #eee;
+}
+
+div.footer {
+ padding: 5px;
+ text-align: center;
+}
+
+div.footer a {
+ color: #eee;
+}
+
+div.header {
+ background: url(headerbg.png) repeat-x;
+ border-top: 6px solid #D20000;
+ border-bottom: 1px solid #ACACAC;
+ margin: -10px -10px 0 -10px;
+}
+
+div.relnav {
+ border-top: 1px solid #F1F1F1;
+ border-bottom: 1px solid #ACACAC;
+ background-color: #ECECEC;
+ padding: 4px 20px 4px 28px;
+ margin: 0 -10px 10px -10px;
+ font-size: 13px;
+}
+
+#content {
+ background-color: white;
+ color: #111;
+ background-image: url(watermark.png);
+ padding: 10px;
+ margin: 0;
+}
+
+h1.heading {
+ margin: 0;
+ padding: 0;
+ height: 80px;
+ background-image: url(jinjabanner.png);
+ background-repeat: no-repeat;
+}
+
+h1.heading a {
+ display: block;
+ width: 200px;
+ height: 80px;
+}
+
+h1.heading 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: 20px -10px 10px 15px;
+ padding: 10px;
+ width: 200px;
+ float: right;
+ background-color: #f8f8f8;
+ border: 1px solid #ccc;
+ border-right: none;
+}
+
+#toc h3 {
+ font-size: 20px;
+ margin: 0 0 10px 0;
+ padding: 0;
+ color: #444;
+}
+
+#toc ul {
+ margin: 0 0 0 30px;
+ padding: 0;
+}
+
+#toc ul li {
+ padding: 0;
+ margin: 2px 0 2px 0;
+}
+
+a.headerlink {
+ color: #A70000;
+ font-size: 0.8em;
+ margin-left: 8px;
+ padding: 0 4px 0 4px;
+ text-decoration: none!important;
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+ visibility: visible;
+}
+
+a.headerlink:hover {
+ background-color: #A70000;
+ color: white!important;
+}
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ vertical-align: top;
+ width: 50%;
+}
--- /dev/null
+{% extends "layout.html" %}
+{% title = 'Index' %}
+{% block body %}
+
+ <h1 id="index">Index</h1>
+
+ {% for key, dummy in genindexentries -%}
+ <a href="#{{ key }}"><strong>{{ key }}</strong></a> {% if not loop.last %}| {% endif %}
+ {%- endfor %}
+
+ <hr />
+
+ {% for key, entries in genindexentries %}
+<h2 id="{{ key }}">{{ key }}</h2>
+<table class="indextable"><tr><td>
+<dl>
+{%- breakat = genindexcounts[loop.index0] // 2 %}
+{%- numcols = 1 %}
+{%- numitems = 0 %}
+{% for entryname, (links, subitems) in entries %}
+<dt>{%- if links -%}<a href="{{ links[0] }}">{{ entryname|e }}</a>
+ {%- for link in links[1:] %}, <a href="{{ link }}">[Link]</a>{% endfor -%}
+ {%- else -%}
+{{ entryname|e }}
+ {%- endif -%}</dt>
+ {%- if subitems %}
+ <dd><dl>
+ {%- for subentryname, subentrylinks in subitems %}
+ <dt><a href="{{ subentrylinks[0] }}">{{ subentryname|e }}</a>
+ {%- for link in subentrylinks[1:] %}, <a href="{{ link }}">[Link]</a>{% endfor -%}
+ </dt>
+ {%- endfor %}
+ </dl></dd>
+ {%- endif -%}
+{%- numitems = numitems + 1 + len(subitems) -%}
+{%- if numcols < 2 and numitems > breakat -%}
+{%- numcols = numcols+1 -%}
+</dl></td><td><dl>
+{%- endif -%}
+{%- endfor %}
+</dl></td></tr></table>
+{% endfor %}
+
+{% endblock %}
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <title>Jinja2 Documentation</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+ <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+ {%- if builder != 'htmlhelp' %}
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '{{ pathto("", 1) }}',
+ VERSION: '{{ release }}'
+ };
+ </script>
+ <script type="text/javascript" src="{{ pathto('_static/jquery.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/interface.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/doctools.js', 1) }}"></script>
+ {%- endif %}
+ {%- if use_opensearch and builder != 'htmlhelp' %}
+ <link rel="search" type="application/opensearchdescription+xml"
+ title="Search within {{ docstitle }}"
+ href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+ {%- endif %}
+ {%- if hasdoc('about') %}
+ <link rel="author" title="About these documents" href="{{ pathto('about') }}" />
+ {%- endif %}
+ <link rel="contents" title="Global table of contents" href="{{ pathto('contents') }}" />
+ <link rel="index" title="Global index" href="{{ pathto('genindex') }}" />
+ <link rel="search" title="Search" href="{{ pathto('search') }}" />
+ {%- if hasdoc('copyright') %}
+ <link rel="copyright" title="Copyright" href="{{ pathto('copyright') }}" />
+ {%- endif %}
+ <link rel="top" title="{{ docstitle }}" href="{{ pathto('index') }}" />
+ {%- if parents %}
+ <link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
+ {%- endif %}
+ {%- if next %}
+ <link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
+ {%- endif %}
+ {%- if prev %}
+ <link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
+ {%- endif %}
+ </head>
+ <body>
+ <div id="content">
+ <div class="header">
+ <h1 class="heading"><a href="{{ pathto('index') }}"><span>Jinja</span></a></h1>
+ </div>
+ <div class="relnav">
+ {%- if prev %}
+ <a href="{{ prev.link|e }}">« {{ prev.title }}</a> |
+ {%- endif %}
+ <a href="{{ pathto(current_page_name) if current_page_name else '#' }}">{{ title }}</a>
+ {%- if next %}
+ | <a href="{{ next.link|e }}">{{ next.title }} »</a>
+ {%- endif %}
+ </div>
+ {%- if display_toc %}
+ <div id="toc">
+ <h3>Table Of Contents</h3>
+ {{ toc }}
+ </div>
+ {%- endif %}
+ <div id="contentwrapper">
+ {% block body %}{% endblock %}
+ </div>
+ </div>
+ <div class="footer">
+ © Copyright 2008 by the <a href="http://pocoo.org/">Pocoo Team</a>.
+ </div>
+ </body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>{{ project }}</ShortName>
+ <Description>Search {{ docstitle }}</Description>
+ <InputEncoding>utf-8</InputEncoding>
+ <Url type="text/html" method="get"
+ template="{{ use_opensearch }}/{{ pathto('search') }}?q={searchTerms}&check_keywords=yes&area=default"/>
+ <LongName>{{ docstitle }}</LongName>
+</OpenSearchDescription>
--- /dev/null
+{% extends 'layout.html' %}
+{% block body %}
+ {{ body }}
+{% endblock %}
--- /dev/null
+{% extends "layout.html" %}
+{% title = 'Search' %}
+{% block extrahead %}
+ <script type="text/javascript" src="{{ pathto('_static/searchtools.js', 1) }}"></script>
+{% endblock %}
+{% block body %}
+ <h1 id="search-documentation">Search</h1>
+ <p>
+ From here you can search these documents. Enter your search
+ words into the box below and click "search". Note that the search
+ function will automatically search for all of the words. Pages
+ containing less words won't appear in the result list.
+ </p>
+ <form action="" method="get">
+ <input type="text" name="q" value="" />
+ <input type="submit" value="search" />
+ </form>
+ {% if search_performed %}
+ <h2>Search Results</h2>
+ {% if not search_results %}
+ <p>Your search did not match any results.</p>
+ {% endif %}
+ {% endif %}
+ <div id="search-results">
+ {% if search_results %}
+ <ul>
+ {% for href, caption, context in search_results %}
+ <li><a href="{{ pathto(item.href) }}">{{ caption }}</a>
+ <div class="context">{{ context|e }}</div>
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ </div>
+{% endblock %}
--- /dev/null
+Changelog
+=========
+
+.. jinjachangelog::
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
-html_style = 'default.css'
+html_style = 'style.css'
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# typographically correct entities.
#html_use_smartypants = True
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+# use jinja2 for templates
+template_bridge = 'jinjaext.Jinja2Bridge'
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_use_modindex = True
+# no modindex
+html_use_modindex = False
# If true, the reST sources are included in the HTML build as _sources/<name>.
#html_copy_source = True
-Welcome to Jinja2's documentation!
-==================================
+Jinja2 Documentation
+====================
-Contents:
+Welcome in the Jinja2 documentation.
.. toctree::
:maxdepth: 2
intro
api
templates
+
+ changelog
+
+* :ref:`genindex`
:copyright: Copyright 2008 by Armin Ronacher.
:license: BSD.
"""
+import os
import re
import inspect
+import jinja2
+from itertools import islice
from types import BuiltinFunctionType
from docutils import nodes
from docutils.statemachine import ViewList
from sphinx.ext.autodoc import prepare_docstring
-
-
+from sphinx.application import TemplateBridge
from pygments.style import Style
from pygments.token import Keyword, Name, Comment, String, Error, \
Number, Operator, Generic
+from jinja2 import Environment, FileSystemLoader
class JinjaStyle(Style):
Error: '#F00 bg:#FAA'
}
+
+class Jinja2Bridge(TemplateBridge):
+
+ def init(self, builder):
+ path = builder.config.templates_path
+ self.env = Environment(loader=FileSystemLoader(path))
+
+ def render(self, template, context):
+ return self.env.get_template(template).render(context)
+
+
_sig_re = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*(\(.*?\))')
return directive
+def jinja_changelog(dirname, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ doc = ViewList()
+ changelog = file(os.path.join(os.path.dirname(jinja2.__file__), '..',
+ 'CHANGES'))
+ try:
+ for line in islice(changelog, 3, None):
+ doc.append(line.rstrip(), '<jinjaext>')
+ finally:
+ changelog.close()
+ node = nodes.section()
+ # hack around title style bookkeeping
+ surrounding_title_styles = state.memo.title_styles
+ surrounding_section_level = state.memo.section_level
+ state.memo.title_styles = []
+ state.memo.section_level = 0
+ state.nested_parse(doc, content_offset, node, match_titles=1)
+ state.memo.title_styles = surrounding_title_styles
+ state.memo.section_level = surrounding_section_level
+ return node.children
+
+
from jinja2.defaults import DEFAULT_FILTERS, DEFAULT_TESTS
jinja_filters = dump_functions(DEFAULT_FILTERS)
jinja_tests = dump_functions(DEFAULT_TESTS)
def setup(app):
app.add_directive('jinjafilters', jinja_filters, 0, (0, 0, 0))
app.add_directive('jinjatests', jinja_tests, 0, (0, 0, 0))
+ app.add_directive('jinjachangelog', jinja_changelog, 0, (0, 0, 0))