some more doc changes in jinja for the upcoming release
authorArmin Ronacher <armin.ronacher@active-4.com>
Fri, 16 Nov 2007 15:16:23 +0000 (16:16 +0100)
committerArmin Ronacher <armin.ronacher@active-4.com>
Fri, 16 Nov 2007 15:16:23 +0000 (16:16 +0100)
--HG--
branch : trunk

12 files changed:
.hgignore [new file with mode: 0644]
CHANGES
docs/src/debugging.txt
docs/src/designerdoc.txt
docs/src/devrecipies.txt
docs/src/escaping.txt
docs/src/frameworks.txt
docs/src/installation.txt
docs/src/scopes.txt
jinja/datastructure.py
setup.py
tests/test_security.py

diff --git a/.hgignore b/.hgignore
new file mode 100644 (file)
index 0000000..bfd0c2a
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,6 @@
+^instance$
+^instance/
+^jinja/.*\.so$
+^(build|dist|Jinja\.egg-info)/
+\.py[co]$
+\.DS_Store$
diff --git a/CHANGES b/CHANGES
index 2a0a9532da4cad4cc643d4ef582508c942d9f96b..632b902dce0a3c0e24237ba825e0eb3198bddfb0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,7 +3,14 @@ Jinja Changelog
 
 Version 1.2
 -----------
-(codename to be selected, release date unknown)
+(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.
index a67f98992755d91339e40546187d2d9b1eb943da..e8f432a6a1c7fc5fc5fd7999028a00abe099e7a2 100644 (file)
@@ -8,20 +8,25 @@ 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 module support it:
+However most of the extended web development traceback modules have support
+for `__loader__`.  Either directly or via the linecache module:
 
--  `Colubrid Debugging Middleware`_
+-  `Werkzeug Debugging Middleware`_
+-  `Django`_
 -  `cgitb`_
 -  `EvalException`_
 
-Note that the django traceback module currently does not provide this. `A
-ticket`_ was filed already so there is hope that this will be fixed.
-
 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.
+
 
-.. _Colubrid Debugging Middleware: http://trac.pocoo.org/repos/colubrid/trunk/colubrid/debug.py
+.. _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
-.. _A ticket: http://code.djangoproject.com/ticket/3734
index 1ca741da6ff18e505b662f4362509c060baa0a06..978565a05e439487f5777c09fb5cf864213564f7 100644 (file)
@@ -223,6 +223,14 @@ table shows which syntax elements are supported:
     ``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
 =========
 
index f0ec3c80b54de908a813e2d3c130dfef7900318a..dfa20437411a46f6805d0afc885d2aca23ba0c75 100644 (file)
@@ -38,6 +38,7 @@ You can use it now like this:
 
 In the template you can now access the local variables `seq` and `foo`.
 
+
 Using Django Filters with Jinja
 ===============================
 
@@ -75,10 +76,18 @@ And use it:
 Also keep in mind that Jinja knows about keywords, thus you cannot have a filter
 that is called `pluralize` for example.
 
+Such a conversion function is also part of the djangosupport module which was
+introduced in Jinja 1.2.  It's explained on the `Framework Integration`_ page.
+
 
 Using Jinja in Django
 =====================
 
+.. admonition:: Note
+
+    This section is more or less obsolete as of Jinja 1.2 which provides a
+    djangosupport module, covered on the `Framework Integration`_ page.
+
 This snippet was contributed by Bryan McLemore. It provides a `render_to_response`
 function similar to the one shipped with django just that it uses Jinja for
 rendering. It applies the context processors on the context and consumes a
@@ -125,3 +134,6 @@ environment class:
 
 Because Django uses gettext internally we can create just assign the
 ngettext and gettext functions directly to the translator class.
+
+
+.. _Framework Integration: frameworks.txt
index ab7e8d6439ed0bfd731aad42dc2e3c8829a8a399..73c0d93dfcb3eb0c5b2e5e3763ef68bce58b2fe6 100644 (file)
@@ -40,8 +40,8 @@ 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:
+(for example a `for` tag), a comment or variable element you can remove
+the whitespaces after or before that block:
 
 .. sourcecode:: jinja
 
index 930b001f4be3cfe3e066ffa8771fd2ff0545a404..88aafea027e1721f101d54cf5fe7d3840bfbf969 100644 (file)
@@ -15,6 +15,7 @@ called `General Template Interface`_ which isn't implemented by any existing
 framework so far. This specification however tries to solve the problems that
 exist in Buffet.
 
+
 Buffet
 ======
 
@@ -108,6 +109,7 @@ a folder in the ``yourapplication`` python package.
 
 The `downloads` action uses the pylons specific leading foreslash notation.
 
+
 General Template Interface
 ==========================
 
@@ -121,7 +123,112 @@ Django
 
 Using Jinja in django is straightforward because django has a pretty low
 level response interface. Just have a look at the `developer recipies`_,
-there are some examples for django.
+there are some examples for django.  Starting with Jinja 1.2 there is also
+a contrib module that simplifies using Jinja in an unicode enabled django.
+
+Quickstart
+----------
+
+To get started execute the following code at the bottom of your settings.py
+or in some general application file such as urls.py or a central module. The
+only thing that matters is that it's executed right *after* the settings
+were set up and *before* `django.contrib.jinja` is imported::
+
+    from jinja.contrib import djangosupport
+    djangosupport.configure()
+
+What this does is setting up a Jinja environment for this django instance
+with loaders for `TEMPLATE_DIRS` etc.  It also converts a couple of default
+django filters such as `date` and `timesince` which are not available in
+Jinja per default.  If you want to change the list you can provide others
+by passing a list with filter import names as `convert_filters` keyword
+argument.
+
+All other keyword arguments are forwarded to the environment.  If you want
+to provide a loader yourself pass it a loader keyword argument.
+
+Rendering Templates
+-------------------
+
+To render a template you can use the functions `render_to_string` or
+`render_to_response` from the `django.contrib.jinja` module::
+
+    from django.contrib.jinja import render_to_response
+    resp = render_to_response('Hello {{ username }}!', {
+        'username':     req.session['username']
+    }, req)
+
+`render_to_string` and `render_to_response` take at least the name of
+the template as argument, then the optional dict which will become the
+context.  If you also provide a request object as third argument the
+context processors will be applied.
+
+`render_to_response` also takes a forth parameter which can be the
+content type which defaults to `DEFAULT_CONTENT_TYPE`.
+
+Converting Filters
+------------------
+
+One of the useful objects provided by `django.contrib.jinja` is the
+`register` object which can be used to register filters, tests and
+global objects.  You can also convert any filter django provides in
+a Jinja filter using `convert_django_filter`::
+
+    from django.contrib.jinja import register, convert_django_filter
+    from django.template.defaultfilters import floatformat
+
+    register.filter(convert_django_filter(floatformat), 'floatformat')
+
+Available methods on the `register` object:
+
+``object (obj[, name])``
+    Register a new global as name or with the object's name.
+    Returns the function object unchanged so that you can use
+    it as decorator if no name is provided.
+
+``filter (func[, name])``
+    Register a function as filter with the name provided or
+    the object's name as filtername.
+    Returns the function object unchanged so that you can use
+    it as decorator if no name is provided.
+
+``test (func[, name])``
+    Register a function as test with the name provided or the
+    object's name as testname.
+    Returns the function object unchanged so that you can use
+    it as decorator if no name is provided.
+
+``context_inclusion (func, template[, name])``
+    Register a function with a name provided or the func object's
+    name in the global namespace that acts as subrender function.
+
+    func is called with the callers context as dict and the
+    arguments and keywords argument of the inclusion function.
+    The function should then process the context and return a
+    new context or the same context object. Afterwards the
+    template is rendered with this context.
+
+    Example::
+
+        def add_author(context, author=None):
+            if author is not None:
+                author = Author.objects.get(name=author)
+            context['author'] = author
+            return context
+
+        register.context_inclusion(add_author, 'author_details.html',
+                                   'render_author_details')
+
+    You can use it in the template like this then::
+
+        {{ render_author_details('John Doe') }}
+
+``clean_inclusion (func, template[, name[, run_processors]]) ``
+    Works like `context_inclusion` but doesn't use the calles
+    context but an empty context. If `run_processors` is `True`
+    it will lookup the context for a `request` object and pass
+    it to the render function to apply context processors.
+
 
 
 .. _Pylons: http://www.pylonshq.com/
index 5b48a0747efbf21eb9d72d670b8e0a9294aa0574..8f7cbadcc26fa22d27678408c165c2d16828c38d 100644 (file)
@@ -4,6 +4,7 @@ Installation
 
 Jinja requires at least Python 2.3 to work correctly.
 
+
 Installing a released version
 =============================
 
@@ -30,6 +31,7 @@ internet connection.
 
 This will install Jinja into your Python installation's site-packages directory.
 
+
 Installing the development version
 ==================================
 
@@ -42,7 +44,8 @@ If you want to play around with the code
 4.  ``ln -s jinja /usr/lib/python2.X/site-packages``
 
 As an alternative to steps 4 you can also do ``python setup.py develop``
-which will install the package via setuptools in development mode.
+which will install the package via setuptools in development mode.  This also
+has the advantage that the c extensions are compiled.
 
 If you just want the latest features and use them
 -------------------------------------------------
@@ -55,6 +58,19 @@ This will install a Jinja egg containing the latest Subversion trunk code
 in your Python installation's site-packages directory. Every time the command
 is run, the sources are updated from Subversion.
 
+
+Windows Installation Information
+================================
+
+On windows computers without Visual Studio 2003 Jinja is unable to compile the
+C extensions.  This is usually not a problem because there is a fallback for
+native Python implementations of those C libraries.  However under certain
+conditions the installation may fail with an error message.  In that case try
+to disable the extensions by passing the following parameters to setup.py::
+
+    python setup.py install --without-speedups --without-extended-debugger
+
+
 Documentation
 =============
 
index baf8c69811f43e4bb6aca3c3ed3fc59221d8bfa2..8dd1e43f4554349a5b35addc73fb43e974ddbbaa 100644 (file)
@@ -182,6 +182,5 @@ it. There is however a way to override a variable from an outer scope using the
 
 After the iteration `last_item` will point to the item of the last iteration.
 
-If `last_item` was not defined in the outer scope it wouldn't exist now because
-in that situation `set`, even with a postfixed bang just behaves like setting a
-scope variable.
+If `last_item` was not defined in the outer scope it would be defined in the
+outermost scope.
index 8e07a0318087fb9532f7c5ec447ea77fe71a7fe1..eb213d4dc5f718efc5471dcb934df089a1dc6794 100644 (file)
@@ -274,7 +274,7 @@ class Context(BaseContext):
             if name in layer:
                 layer[name] = value
                 return
-        self.current[name] = value
+        self.initial[name] = value
 
     def translate_func(self):
         """
index a7086c2c3c6cce03e39765bc4dd6d0b688bd7d5b..772e1eaad82bb6dc7fda684d4e3e0a4d34254bb4 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -90,15 +90,15 @@ setup(
     features={
         'speedups': Feature(
             'optional C-speed enhancements',
-            standard = True,
-            ext_modules = [
+            standard=True,
+            ext_modules=[
                 Extension('jinja._speedups', ['jinja/_speedups.c'])
             ]
         ),
         'extended-debugger': Feature(
             'extended debugger',
-            standard = True,
-            ext_modules = [
+            standard=True,
+            ext_modules=[
                 Extension('jinja._debugger', ['jinja/_debugger.c'])
             ]
         )
index 78a1e0a2f5ad5661bde1084bd7f7cc2706ac6d3e..a0faf18e662bb99912f877de248bdbbb1b190d57 100644 (file)
@@ -6,6 +6,14 @@
     :copyright: 2007 by Armin Ronacher.
     :license: BSD, see LICENSE for more details.
 """
+from jinja import Environment
+
+
+NONLOCALSET = '''\
+{% for item in range(10) %}
+    {%- set outer = item! -%}
+{% endfor -%}
+{{ outer }}'''
 
 
 class PrivateStuff(object):
@@ -49,3 +57,11 @@ Traceback (most recent call last):
     ...
 TemplateSyntaxError: cannot assign to expression (line 1)
 '''
+
+
+def test_nonlocal_set():
+    env = Environment()
+    env.globals['outer'] = 42
+    tmpl = env.from_string(NONLOCALSET)
+    assert tmpl.render() == '9'
+    assert env.globals['outer'] == 42