[svn] splitted jinja documentation into more files
authorArmin Ronacher <armin.ronacher@active-4.com>
Sun, 29 Apr 2007 16:21:13 +0000 (18:21 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Sun, 29 Apr 2007 16:21:13 +0000 (18:21 +0200)
--HG--
branch : trunk

docs/src/builtins.txt [new file with mode: 0644]
docs/src/designerdoc.txt
docs/src/escaping.txt [new file with mode: 0644]
docs/src/index.txt
docs/src/inheritance.txt [new file with mode: 0644]
docs/src/objects.txt
docs/src/scopes.txt [new file with mode: 0644]
docs/src/templatei18n.txt [new file with mode: 0644]

diff --git a/docs/src/builtins.txt b/docs/src/builtins.txt
new file mode 100644 (file)
index 0000000..7f460a4
--- /dev/null
@@ -0,0 +1,203 @@
+===================================
+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
+
+    The filter operator has a pretty low priority. 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 }}
+
+*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.
+
+
+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*
+
+
+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
index 6c6dbabf7f739528b355f069335e3b7aab62e87b..ba5de713daf07c02eef4e640b1dcba62ab08403d 100644 (file)
@@ -67,174 +67,6 @@ this:
         If you have numerical indices you have to use the [] syntax:
     {{ users[0].username }}
 
-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
-
-    The filter operator has a pretty low priority. 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 }}
-
-*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.
-
-
-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*
-
 Loops
 =====
 
@@ -252,7 +84,7 @@ normal Python `for` loop and works pretty much the same:
     {% endfor %}
     </ul>
 
-*Important* Contrary to Python is the optional ``else`` block only
+*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:
@@ -516,164 +348,8 @@ You can also specify more than one value:
     If a macro parameter is called `varargs` the additional extra
     arguments are not accessible.
 
-
-Inheritance
-===========
-
-The most powerful part of Jinja is template inheritance. Template inheritance
-allows you to build a base "skeleton" template that contains all the common
-elements of your site and defines **blocks** that child templates can override.
-
-Sounds complicated but is very basic. It's easiest to understand it by starting
-with an example.
-
-Base Template
--------------
-
-This template, which we'll call ``base.html``, defines a simple HTML skeleton
-document that you might use for a simple two-column page. It's the job of
-"child" templates to fill the empty blocks with content:
-
-.. 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">
-    <head>
-      <link rel="stylesheet" href="style.css" />
-      <title>{% block title %}{% endblock %} - My Webpage</title>
-      {% block html_head %}{% endblock %}
-    </head>
-    <body>
-      <div id="content">
-        {% block content %}{% endblock %}
-      </div>
-
-      <div id="footer">
-        {% block footer %}
-        &copy; Copyright 2006 by <a href="http://mydomain.tld">myself</a>.
-        {% endblock %}
-      </div>
-    </body>
-
-In this example, the ``{% block %}`` tags define four blocks that child templates
-can fill in. All the `block` tag does is to tell the template engine that a
-child template may override those portions of the template.
-
-Child Template
---------------
-
-A child template might look like this:
-
-.. sourcecode:: html+jinja
-
-    {% extends "base.html" %}
-    {% block title %}Index{% endblock %}
-
-    {% block html_head %}
-      <style type="text/css">
-        .important {
-          color: #336699;
-        }
-      </style>
-    {% endblock %}
-    
-    {% block content %}
-        <h1>Index</h1>
-        <p class="important">
-          Welcome on my awsome homepage.
-        </p>
-    {% endblock %}
-
-The ``{% extends %}`` tag is the key here. It tells the template engine that
-this template "extends" another template. When the template system evaluates
-this template, first it locates the parent.
-
-The filename of the template depends on the template loader. For example the
-``FileSystemLoader`` allows you to access other templates by giving the
-filename. You can access templates in subdirectories with an slash:
-
-.. sourcecode:: jinja
-
-    {% extends "layout/default.html" %}
-
-But this behavior can depend on the application using Jinja.
-
-Note that since the child template didn't define the ``footer`` block, the
-value from the parent template is used instead.
-
-.. admonition:: Note
-
-    You can't define multiple ``{% block %}`` tags with the same name in the
-    same template. This limitation exists because a block tag works in "both"
-    directions. That is, a block tag doesn't just provide a hole to fill - it
-    also defines the content that fills the hole in the *parent*. If there were
-    two similarly-named ``{% block %}`` tags in a template, that template's
-    parent wouldn't know which one of the blocks' content to use.
-
-How Inheritance Works Internally
---------------------------------
-
-Inheritance in Jinja is straighforward. If a template contains a
-``{% extends %}`` tag it's considered being a child template, otherwise it's
-a layout template. In a layout template you can place blocks basically
-everywhere. In a child template blocks can only be located either top level
-or inside of another block.
-
-Data outside of a block in a child template is executed before the layout
-template is rendered, thus you can use it to propagate data to the whole
-inheritance chain. Having a block in an invalid position you will receive
-an syntax error. Here some examples:
-
-**impossible**:
-
-    .. sourcecode:: jinja
-
-        {% extends 'master.html' %}
-        {% if some_condition %}
-          {% block body %}
-            ...
-          {% endblock %}
-        {% endif %}
-
-    This can't work because template inheritance works at translation /
-    compilation time not at template executation.
-
-**possible**:
-
-    .. sourcecode:: jinja
-
-        {% extends 'master.html' %}
-        {% block body %}
-          {% if some_condition %}
-            {% block myblock %}
-              ...
-            {% endblock %}
-          {% endblock %}
-        {% endblock %}
-
-    This can work although it probably makes no sense in this specific case.
-    However the condition is handled at runtime because it's in a valid block
-    and defines a new block subtemplates can override.
-
-Super Blocks
-============
-
-Starting with `Jinja 1.1` it's possible to render the contents of the parent
-block. By calling it you get the results of the parent block back. If you want
-to get the data of the parent you can give it an offset:
-
-.. sourcecode:: jinja
-
-    {{ super() }}
-        return the parent data
-
-    {{ super(1) }}
-        the same as above
-
-    {{ super(2) }}
-        return the data of the second parent block
-
+For information regarding the visibility of macros have a look at the
+`Scopes and Variable Behavior`_ section.
 
 Template Inclusion
 ==================
@@ -690,6 +366,8 @@ load macros, `include` works better than `extends`:
 If you define a macro called ``my_helper`` in ``myhelpers.html``, you can now
 use it from the template as shown above.
 
+Because of the
+
 Filtering Blocks
 ================
 
@@ -726,187 +404,8 @@ You can also define variables in the namespace using the ``{% set %}`` tag:
 
 This should ouput ``foobar``.
 
-Scopes
-======
-
-Jinja has multiple scopes. A scope is something like a new transparent foil on
-a stack of foils. You can only write to the outermost foil but read all of them
-since you can look through them. If you remove the top foil all data on that
-foil disappears. Some tags in Jinja add a new layer to the stack. Currently
-these are `block`, `for`, `macro` and `filter`. This means that variables and
-other elements defined inside a macro, loop or some of the other tags listed
-above will be only available in that block. Here an example:
-
-.. sourcecode:: jinja
-
-    {% macro angryhello name %}
-      {% set angryname = name|upper %}
-      Hello {{ name }}. Hello {{ name }}!
-      HELLO {{ angryname }}!!!!!!111
-    {% endmacro %}
-
-The variable ``angryname`` just exists inside the macro, not outside it.
-
-Defined macros appear on the context as variables. Because of this, they are
-affected by the scoping too. A macro defined inside of a macro is just available
-in those two macros (the macro itself and the macro it's defined in).
-
-Template Globals
-================
-
-A special threatment exists for template code outside of visible blocks in
-child templates. This code will be executed **before** the layout template
-code. Thus it can be used to propagate values back to the layout template or
-import macros from templates for rendering.
-
-Such code can output data but it won't appear in the final rendering. So no
-additional whitespace will pollute the template.
-
-Because this code is executed before the actual layout template code it's
-possible that the layout code overrides some of those variables. Usually
-this is not a problem because of different variable names but it can be
-a problem if you plan to specify default values.
-
-In that case you have to test if the variable is not defined before setting
-it:
-
-.. sourcecode:: jinja
-
-    {% if not page_title %}
-      {% set page_title = 'Default Page Title' %}
-    {% endif %}
-
-You can of course also use the `|default` filter.
-
-.. admonition:: Explanation
-
-    This template stored as `a.html`:
-
-    .. sourcecode:: html+jinja
-
-        <title>{{ title|default('Untitled') }}</title>
-        <body>{% block body %}{% endblock %}
-
-    ...and this child template stored as `b.html`:
-
-    .. sourcecode:: html+jinja
-
-        {% extends 'a.html' %}
-        {% include 'macros.tmpl' %}
-        {% set title = 'My Page' %}
-        {% block body %}{{ wrap(42) }}{% endblock %}
-
-    ...and this code in `macros.tmpl`:
-
-    .. sourcecode:: html+jinja
-
-        {% macro wrap(text) %}
-          [{{ text }}]
-        {% endmacro %}
-
-    ..will translate to something with the same semantics as this (just
-    that the value is not stored in a variable):
-
-    .. sourcecode:: html+jinja
-
-        {% filter capture('captured', true) %}
-          {% macro wrap(text) %}
-            [{{ text }}]
-          {% endmacro %}
-          {% set title='My Page' %}
-        {% endfilter %}
-        <title>{{ title|default('Untitled') }}</title>
-        <body>
-          {{ wrap(42) }}
-        </body>
-
-.. admonition:: Note
-
-    This implementation was improved in Jinja 1.1. In Jinja 1.0 blocks that
-    were not top-level were not propagated to the layout template. This made
-    it impossible to use conditional expressions for inclusion in non root
-    templates.
-
-
-Undefined Variables
-===================
-
-If you have already worked with python you probably know about the fact that
-undefined variables raise an exception. This is different in Jinja. There is a
-special value called `undefined` that represents values that do not exist.
-
-Depending on the configuration it will behave different.
-
-In order to check if a value is defined you can use the `defined` test:
-
-.. sourcecode:: jinja
-
-    {{ myvariable is not defined }}
-        will return true if the variable does not exist.
-
-`SilentUndefined`:
-
-    The silent `undefined` is the default behavior. The `undefined` object works
-    complete different from any variables you maybe know. If you print it
-    using ``{{ variable }}`` it will not appear because it's literally empty.
-    If you try to iterate over it, it will work. But no items are returned.
-
-    In order to check if a value is defined you can use the `defined` test:
-
-    There are also some additional rules regarding this special value. Any
-    mathematical operators (``+``, ``-``, ``*``, ``/``) return the operand
-    as result:
-
-    .. sourcecode:: jinja
-
-        {{ undefined + "foo" }}
-            returns "foo"
-
-        {{ undefined - 42 }}
-            returns 42. Note: not -42!
-
-    In any expression `undefined` evaluates to `false`. It has no length, all
-    attribute calls return undefined, calling too:
-
-    .. sourcecode:: jinja
-
-        {{ undefined.attribute().attribute_too[42] }}
-            still returns `undefined`.
-
-`ComplainingUndefined`:
-
-    Starting with Jinja 1.1 it's possible to replace the default undefined
-    object with different values. The other common undefined object which
-    comes with Jinja is the `ComplainingUndefined` object.
-
-    It raises exceptions as soon as you either render it or want to iterate
-    over it or try to access attributes etc.
-    
-
-Escaping
-========
-
-Sometimes you might want to add Jinja syntax elements into the template
-without executing them. In that case you have quite a few possibilities.
-
-For small parts this might be a good way:
-
-.. sourcecode:: jinja
-
-    {{ "{{ foo }} is variable syntax and {% foo %} is block syntax" }}
-
-When you have multiple elements you can use the ``raw`` block:
-
-.. sourcecode:: jinja
-
-    {% raw %}
-        Filtering blocks works like this in Jinja:
-        {% filter escape %}
-            <html>
-              <code>goes here</code>
-            </html>
-        {% endfilter %}
-    {% endraw %}
+For information regarding the visibility of variables have a look at the
+`Scopes and Variable Behavior`_ section.
 
 Reserved Keywords
 =================
@@ -936,141 +435,6 @@ means that they won't raise an error for several releases but yield warnings
 on the application side. But it's very unlikely that new keywords will be
 added.
 
-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 %}
-
-Whitespace
-==========
-
-If the Jinja environment was created with ``trim_blocks`` set to true the
-first newline after a template tag is removed automatically (php like
-processing).
-
-Starting with `Jinja 1.1` you can also handle some whitespace rules in the
-template. If you put an minus sign (`-`) to the start or end of an block
-(for example a `for` tag) or a comment, variable element you can remove
-the whitespaces after that block or before that block:
-
-.. sourcecode:: jinja
-
-    {% for item in seq -%}
-        {{ item }}
-    {%- endfor %}
-
-This will yield all elements without whitespace between them because they
-are automatically removed. This of course works for other tags too:
-
-.. sourcecode:: jinja
-
-    {% for user in userlist -%}
-        {{ user|e -}}
-        {% if not loop.last %},{% endif %}
-    {%- endfor %}
-
-Note that you must not use a whitespace between the tag and the minus sign:
-
-.. sourcecode:: jinja
-
-    valid:
-        {%- if foo -%}...{% endif %}
-
-    invalid:
-
-        {% - if foo - %}...{% endif %}
-
-Internationalization
-====================
-
-If the application is configured for i18n, you can define translatable blocks
-for translators using the `trans` tag or the special underscore function:
-
-.. sourcecode:: jinja
-
-    {% trans %}
-        this is a translatable block
-    {% endtrans %}
-
-    {% trans "This is a translatable string" %}
-
-    {{ _("This is a translatable string") }}
-
-The latter one is useful if you want translatable arguments for filters etc.
-
-If you want to have plural forms too, use the `pluralize` block:
-
-.. sourcecode:: jinja
-
-    {% trans users=users %}
-        One user found.
-    {% pluralize %}
-        {{ users }} users found.
-    {% endtrans %}
-
-    {% trans first=(users|first).username|escape, user=users|length %}
-        one user {{ first }} found.
-    {% pluralize users %}
-        {{ users }} users found, the first one is called {{ first }}.
-    {% endtrans %}
-
-If you have multiple arguments, the first one is assumed to be the indicator (the
-number that is used to determine the correct singular or plural form. If you
-don't have the indicator variable on position 1 you have to tell the `pluralize`
-tag the correct variable name.
-
-Inside translatable blocks you cannot use blocks or expressions (however you can
-still use the ``raw`` block which will work as expected). The variable
-print syntax (``{{ variablename }}``) is the only way to insert the variables
-defined in the ``trans`` header. Filters must be applied in the header.
-
-.. admonition:: note
-
-    Please make sure that you always use pluralize blocks where required.
-    Many languages have more complex plural forms than the English language.
-    
-    Never try to workaround that issue by using something like this:
-
-    .. sourcecode:: jinja
-
-        {% if count != 1 %}
-            {{ count }} users found.
-        {% else %}
-            one user found.
-        {% endif %}
-
-*New in Jinja 1.1*: It's now possible to use the marker name as implicit
-default:
-
-.. sourcecode:: jinja
-
-    instead of this version:
-
-        {% trans username=username %}Hello {{ username }}!{% endtrans %}
-
-    you can now write this:
-
-        {% trans username %}Hello {{ username }}!{% endtrans %}
-
 
 Bleeding Edge
 =============
@@ -1133,4 +497,4 @@ change.
         </ul>
 
 .. _slicing chapter: http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
-.. _range function: http://docs.python.org/tut/node6.html#SECTION006300000000000000000
+.. _Scopes and Variable Behavior: scopes.txt
diff --git a/docs/src/escaping.txt b/docs/src/escaping.txt
new file mode 100644 (file)
index 0000000..ab7e8d6
--- /dev/null
@@ -0,0 +1,71 @@
+=======================
+Whitespace and Escaping
+=======================
+
+This section of the documentation explains how to remove unused whitespace
+from the templates and embed raw Jinja syntax.
+
+Escaping
+========
+
+Sometimes you might want to add Jinja syntax elements into the template
+without executing them. In that case you have quite a few possibilities.
+
+For small parts this might be a good way:
+
+.. sourcecode:: jinja
+
+    {{ "{{ foo }} is variable syntax and {% foo %} is block syntax" }}
+
+When you have multiple elements you can use the ``raw`` block:
+
+.. sourcecode:: jinja
+
+    {% raw %}
+        Filtering blocks works like this in Jinja:
+        {% filter escape %}
+            <html>
+              <code>goes here</code>
+            </html>
+        {% endfilter %}
+    {% endraw %}
+
+
+Whitespace
+==========
+
+If the Jinja environment was created with ``trim_blocks`` set to true the
+first newline after a template tag is removed automatically (php like
+processing).
+
+Starting with `Jinja 1.1` you can also handle some whitespace rules in the
+template. If you put an minus sign (`-`) to the start or end of an block
+(for example a `for` tag) or a comment, variable element you can remove
+the whitespaces after that block or before that block:
+
+.. sourcecode:: jinja
+
+    {% for item in seq -%}
+        {{ item }}
+    {%- endfor %}
+
+This will yield all elements without whitespace between them because they
+are automatically removed. This of course works for other tags too:
+
+.. sourcecode:: jinja
+
+    {% for user in userlist -%}
+        {{ user|e -}}
+        {% if not loop.last %},{% endif %}
+    {%- endfor %}
+
+Note that you must not use a whitespace between the tag and the minus sign:
+
+.. sourcecode:: jinja
+
+    valid:
+        {%- if foo -%}...{% endif %}
+
+    invalid:
+
+        {% - if foo - %}...{% endif %}
index d591fd162d7b4f80c691c7d49cbdaa034e4dd8b2..ba1c4eb0afddaf32ed042ebb09ee28975187d0ee 100644 (file)
@@ -47,8 +47,22 @@ Welcome in the Jinja documentation.
 
 - **Template Designer Documentation**:
 
-  - `Syntax Reference <designerdoc.txt>`_ - the designer documentation. Put
-    this under your pillow.
+  - `Syntax Reference <designerdoc.txt>`_ - quick overview over the Jinja
+    syntax elements.
+
+  - `Template Inheritance <inheritance.txt>`_ - template inheritance howto.
+
+  - `Filters, Tests and Helper Functions <builtins.txt>`_ - list of filters
+    and test/helper functions.
+
+  - `Whitespace and Escaping <escaping.txt>`_ - how to escape markup and
+    control whitespace.
+
+  - `Scopes and Variable Behavior <scopes.txt>`_ - behavior of undefined
+    variables and scoping rules.
+
+  - `Template Internationalization <templatei18n.txt>`_ - how to internationalize
+    Jinja templates.
 
   - `Differences To Django <fromdjango.txt>`_ - coming from django? Then this
     document is for you.
diff --git a/docs/src/inheritance.txt b/docs/src/inheritance.txt
new file mode 100644 (file)
index 0000000..94bae87
--- /dev/null
@@ -0,0 +1,157 @@
+====================
+Template Inheritance
+====================
+
+The most powerful part of Jinja is template inheritance. Template inheritance
+allows you to build a base "skeleton" template that contains all the common
+elements of your site and defines **blocks** that child templates can override.
+
+Sounds complicated but is very basic. It's easiest to understand it by starting
+with an example.
+
+Base Template
+=============
+
+This template, which we'll call ``base.html``, defines a simple HTML skeleton
+document that you might use for a simple two-column page. It's the job of
+"child" templates to fill the empty blocks with content:
+
+.. 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">
+    <head>
+      <link rel="stylesheet" href="style.css" />
+      <title>{% block title %}{% endblock %} - My Webpage</title>
+      {% block html_head %}{% endblock %}
+    </head>
+    <body>
+      <div id="content">
+        {% block content %}{% endblock %}
+      </div>
+
+      <div id="footer">
+        {% block footer %}
+        &copy; Copyright 2006 by <a href="http://mydomain.tld">myself</a>.
+        {% endblock %}
+      </div>
+    </body>
+
+In this example, the ``{% block %}`` tags define four blocks that child templates
+can fill in. All the `block` tag does is to tell the template engine that a
+child template may override those portions of the template.
+
+Child Template
+==============
+
+A child template might look like this:
+
+.. sourcecode:: html+jinja
+
+    {% extends "base.html" %}
+    {% block title %}Index{% endblock %}
+
+    {% block html_head %}
+      <style type="text/css">
+        .important {
+          color: #336699;
+        }
+      </style>
+    {% endblock %}
+    
+    {% block content %}
+        <h1>Index</h1>
+        <p class="important">
+          Welcome on my awsome homepage.
+        </p>
+    {% endblock %}
+
+The ``{% extends %}`` tag is the key here. It tells the template engine that
+this template "extends" another template. When the template system evaluates
+this template, first it locates the parent.
+
+The filename of the template depends on the template loader. For example the
+``FileSystemLoader`` allows you to access other templates by giving the
+filename. You can access templates in subdirectories with an slash:
+
+.. sourcecode:: jinja
+
+    {% extends "layout/default.html" %}
+
+But this behavior can depend on the application using Jinja.
+
+Note that since the child template didn't define the ``footer`` block, the
+value from the parent template is used instead.
+
+.. admonition:: Note
+
+    You can't define multiple ``{% block %}`` tags with the same name in the
+    same template. This limitation exists because a block tag works in "both"
+    directions. That is, a block tag doesn't just provide a hole to fill - it
+    also defines the content that fills the hole in the *parent*. If there were
+    two similarly-named ``{% block %}`` tags in a template, that template's
+    parent wouldn't know which one of the blocks' content to use.
+
+How Inheritance Works Internally
+================================
+
+Inheritance in Jinja is straighforward. If a template contains a
+``{% extends %}`` tag it's considered being a child template, otherwise it's
+a layout template. In a layout template you can place blocks basically
+everywhere. In a child template blocks can only be located either top level
+or inside of another block.
+
+Data outside of a block in a child template is executed before the layout
+template is rendered, thus you can use it to propagate data to the whole
+inheritance chain. Having a block in an invalid position you will receive
+an syntax error. Here some examples:
+
+**impossible**:
+
+    .. sourcecode:: jinja
+
+        {% extends 'master.html' %}
+        {% if some_condition %}
+          {% block body %}
+            ...
+          {% endblock %}
+        {% endif %}
+
+    This can't work because template inheritance works at translation /
+    compilation time not at template executation.
+
+**possible**:
+
+    .. sourcecode:: jinja
+
+        {% extends 'master.html' %}
+        {% block body %}
+          {% if some_condition %}
+            {% block myblock %}
+              ...
+            {% endblock %}
+          {% endblock %}
+        {% endblock %}
+
+    This can work although it probably makes no sense in this specific case.
+    However the condition is handled at runtime because it's in a valid block
+    and defines a new block subtemplates can override.
+
+Super Blocks
+============
+
+Starting with `Jinja 1.1` it's possible to render the contents of the parent
+block. By calling it you get the results of the parent block back. If you want
+to get the data of the parent you can give it an offset:
+
+.. sourcecode:: jinja
+
+    {{ super() }}
+        return the parent data
+
+    {{ super(1) }}
+        the same as above
+
+    {{ super(2) }}
+        return the data of the second parent block
index 6d9add98d465eb5929edff129c16b91f7acd70fc..b1f86e4c410a615192b8161fcaf79ca452c5c0c7 100644 (file)
@@ -90,9 +90,8 @@ access. You can mark both attributes and methods as unsafe:
 
         # just give access to a and b. Default is all
         # note that this also disallows the functions from below.
-        # if you use jinja_allowed_attributes you don't have to
-        # do the code below because methods are threaded as attributes
-        # too.
+        # if you use jinja_allowed_attributes you don't have add the
+        # code below since methods are treated as attributes too.
         jinja_allowed_attributes = ['a', 'b']
 
         def __init__(self, ...):
diff --git a/docs/src/scopes.txt b/docs/src/scopes.txt
new file mode 100644 (file)
index 0000000..205c8b4
--- /dev/null
@@ -0,0 +1,161 @@
+============================
+Scopes and Variable Behavior
+============================
+
+This section of the documentation covers the Jinja behavior regarding
+variable visibility.
+
+Scopes
+======
+
+Jinja has multiple scopes. A scope is something like a new transparent foil on
+a stack of foils. You can only write to the outermost foil but read all of them
+since you can look through them. If you remove the top foil all data on that
+foil disappears. Some tags in Jinja add a new layer to the stack. Currently
+these are `block`, `for`, `macro` and `filter`. This means that variables and
+other elements defined inside a macro, loop or some of the other tags listed
+above will be only available in that block. Here an example:
+
+.. sourcecode:: jinja
+
+    {% macro angryhello name %}
+      {% set angryname = name|upper %}
+      Hello {{ name }}. Hello {{ name }}!
+      HELLO {{ angryname }}!!!!!!111
+    {% endmacro %}
+
+The variable ``angryname`` just exists inside the macro, not outside it.
+
+Defined macros appear on the context as variables. Because of this, they are
+affected by the scoping too. A macro defined inside of a macro is just available
+in those two macros (the macro itself and the macro it's defined in).
+
+Template Globals
+================
+
+A special threatment exists for template code outside of visible blocks in
+child templates. This code will be executed **before** the layout template
+code. Thus it can be used to propagate values back to the layout template or
+import macros from templates for rendering.
+
+Such code can output data but it won't appear in the final rendering. So no
+additional whitespace will pollute the template.
+
+Because this code is executed before the actual layout template code it's
+possible that the layout code overrides some of those variables. Usually
+this is not a problem because of different variable names but it can be
+a problem if you plan to specify default values.
+
+In that case you have to test if the variable is not defined before setting
+it:
+
+.. sourcecode:: jinja
+
+    {% if not page_title %}
+      {% set page_title = 'Default Page Title' %}
+    {% endif %}
+
+You can of course also use the `|default` filter.
+
+.. admonition:: Explanation
+
+    This template stored as `a.html`:
+
+    .. sourcecode:: html+jinja
+
+        <title>{{ title|default('Untitled') }}</title>
+        <body>{% block body %}{% endblock %}
+
+    ...and this child template stored as `b.html`:
+
+    .. sourcecode:: html+jinja
+
+        {% extends 'a.html' %}
+        {% include 'macros.tmpl' %}
+        {% set title = 'My Page' %}
+        {% block body %}{{ wrap(42) }}{% endblock %}
+
+    ...and this code in `macros.tmpl`:
+
+    .. sourcecode:: html+jinja
+
+        {% macro wrap(text) %}
+          [{{ text }}]
+        {% endmacro %}
+
+    ..will translate to something with the same semantics as this (just
+    that the value is not stored in a variable):
+
+    .. sourcecode:: html+jinja
+
+        {% filter capture('captured', true) %}
+          {% macro wrap(text) %}
+            [{{ text }}]
+          {% endmacro %}
+          {% set title='My Page' %}
+        {% endfilter %}
+        <title>{{ title|default('Untitled') }}</title>
+        <body>
+          {{ wrap(42) }}
+        </body>
+
+.. admonition:: Note
+
+    This implementation was improved in Jinja 1.1. In Jinja 1.0 blocks that
+    were not top-level were not propagated to the layout template. This made
+    it impossible to use conditional expressions for inclusion in non root
+    templates.
+
+Undefined Variables
+===================
+
+If you have already worked with python you probably know about the fact that
+undefined variables raise an exception. This is different in Jinja. There is a
+special value called `undefined` that represents values that do not exist.
+
+Depending on the configuration it will behave different.
+
+In order to check if a value is defined you can use the `defined` test:
+
+.. sourcecode:: jinja
+
+    {{ myvariable is not defined }}
+        will return true if the variable does not exist.
+
+`SilentUndefined`:
+
+    The silent `undefined` is the default behavior. The `undefined` object works
+    complete different from any variables you maybe know. If you print it
+    using ``{{ variable }}`` it will not appear because it's literally empty.
+    If you try to iterate over it, it will work. But no items are returned.
+
+    In order to check if a value is defined you can use the `defined` test:
+
+    There are also some additional rules regarding this special value. Any
+    mathematical operators (``+``, ``-``, ``*``, ``/``) return the operand
+    as result:
+
+    .. sourcecode:: jinja
+
+        {{ undefined + "foo" }}
+            returns "foo"
+
+        {{ undefined - 42 }}
+            returns 42. Note: not -42!
+
+    In any expression `undefined` evaluates to `false`. It has no length, all
+    attribute calls return undefined, calling too:
+
+    .. sourcecode:: jinja
+
+        {{ undefined.attribute().attribute_too[42] }}
+            still returns `undefined`.
+
+`ComplainingUndefined`:
+
+    Starting with Jinja 1.1 it's possible to replace the default undefined
+    object with different values. The other common undefined object which
+    comes with Jinja is the `ComplainingUndefined` object.
+
+    It raises exceptions as soon as you either render it or want to iterate
+    over it or try to access attributes etc.
diff --git a/docs/src/templatei18n.txt b/docs/src/templatei18n.txt
new file mode 100644 (file)
index 0000000..50ed017
--- /dev/null
@@ -0,0 +1,72 @@
+=============================
+Template Internationalization
+=============================
+
+If the application is configured for i18n, you can define translatable blocks
+for translators using the `trans` tag or the special underscore function:
+
+.. sourcecode:: jinja
+
+    {% trans %}
+        this is a translatable block
+    {% endtrans %}
+
+    {% trans "This is a translatable string" %}
+
+    {{ _("This is a translatable string") }}
+
+The latter one is useful if you want translatable arguments for filters etc.
+
+If you want to have plural forms too, use the `pluralize` block:
+
+.. sourcecode:: jinja
+
+    {% trans users=users %}
+        One user found.
+    {% pluralize %}
+        {{ users }} users found.
+    {% endtrans %}
+
+    {% trans first=(users|first).username|escape, user=users|length %}
+        one user {{ first }} found.
+    {% pluralize users %}
+        {{ users }} users found, the first one is called {{ first }}.
+    {% endtrans %}
+
+If you have multiple arguments, the first one is assumed to be the indicator (the
+number that is used to determine the correct singular or plural form. If you
+don't have the indicator variable on position 1 you have to tell the `pluralize`
+tag the correct variable name.
+
+Inside translatable blocks you cannot use blocks or expressions (however you can
+still use the ``raw`` block which will work as expected). The variable
+print syntax (``{{ variablename }}``) is the only way to insert the variables
+defined in the ``trans`` header. Filters must be applied in the header.
+
+.. admonition:: note
+
+    Please make sure that you always use pluralize blocks where required.
+    Many languages have more complex plural forms than the English language.
+    
+    Never try to workaround that issue by using something like this:
+
+    .. sourcecode:: jinja
+
+        {% if count != 1 %}
+            {{ count }} users found.
+        {% else %}
+            one user found.
+        {% endif %}
+
+*New in Jinja 1.1*: It's now possible to use the marker name as implicit
+default:
+
+.. sourcecode:: jinja
+
+    instead of this version:
+
+        {% trans username=username %}Hello {{ username }}!{% endtrans %}
+
+    you can now write this:
+
+        {% trans username %}Hello {{ username }}!{% endtrans %}