[svn] checked in changes from the last days regarding jinja, added jinja 1.1 notice...
authorArmin Ronacher <armin.ronacher@active-4.com>
Wed, 11 Apr 2007 19:49:48 +0000 (21:49 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Wed, 11 Apr 2007 19:49:48 +0000 (21:49 +0200)
--HG--
branch : trunk

CHANGES
docs/src/designerdoc.txt
docs/src/devintro.txt
docs/src/index.txt
jinja/datastructure.py
jinja/defaults.py
jinja/parser.py
jinja/translators/python.py
jinja/utils.py

diff --git a/CHANGES b/CHANGES
index 1fb0393faa53189603437d414a38b1d1caac7a1c..18545e5a2e25083ab4e2648239a41ae3cc6b72ed 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -32,6 +32,9 @@ Version 1.1
 - 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.
+
 
 Version 1.0
 -----------
index 959a79baa98a212fe7780dd4c0366374f4b89750..b8d79041c4afd1286f9ad194737fd9e30a7c5acd 100644 (file)
@@ -88,9 +88,9 @@ with the arguments ``'foo'`` and ``'bar'``, and pass the result to the filter
 
 .. admonition:: note
 
-    Filters have 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:
+    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
 
@@ -104,6 +104,19 @@ with the arguments ``'foo'`` and ``'bar'``, and pass the result to the filter
         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
 =====
 
@@ -368,7 +381,8 @@ can use expressions. In expressions you can use any of the following operators:
     ``/``   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``.
+            integer result: ``{{ 20 // 7 }}`` is ``2``. (*new 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
index 9bf7b41c237caa85dcd4557f77e72a9c6db4bfef..11cf2f09264d3ff38ebf3383adb52e272f51e2f0 100644 (file)
@@ -24,6 +24,26 @@ This example should output the following string after execution::
 If you receive an error, check if you have a typo in your code. If not, have
 a look at the `installation`_ page for troubleshooting.
 
+Basically the important method on a template is the `render` method. It
+takes either a dict or keyword arguments. All keyword arguments appear
+in the template as variables.
+
+So these two snippets do the same:
+
+.. sourcecode:: python
+
+    tmpl.render(
+        knights='we say nih',
+        spam='and eggs'
+    )
+
+.. sourcecode:: python
+
+    tmpl.render({
+        'knights':  'we say nih',
+        'spam':     'and eggs'
+    })
+
 The Environment
 ===============
 
index 3a81e178531b17f84a097aa9563ee9bfd3f52929..6253ec8f12f66a6f12a5cfc2e510572220d313e7 100644 (file)
@@ -30,6 +30,8 @@ Welcome in the Jinja documentation.
 
   - `Internationalization <i18n.txt>`_
 
+  - `Recipies <devrecipies.txt>`_
+
 - Template Designer Documentation:
 
   - `Syntax Reference <designerdoc.txt>`_
index e59cda987ab7ffd6fb8c0b934bd0a58fa4cac487..432e9df3241ebdc1fb1b5185c0fb5771fb82e31d 100644 (file)
@@ -182,7 +182,7 @@ class Flush(TemplateData):
 
 class Context(object):
     """
-    Dict like object.
+    Dict like object containing the variables for the template.
     """
 
     def __init__(self, _environment_, *args, **kwargs):
@@ -190,6 +190,9 @@ class Context(object):
         self._stack = [_environment_.globals, dict(*args, **kwargs), {}]
         self.globals, self.initial, self.current = self._stack
 
+        # translator function added by the environment rendering function
+        self.translate_func = None
+
         # cache object used for filters and tests
         self.cache = {}
 
index 7d13c60524eadf1925ccf754c185154f7b6b2a84..43b67a1dcf8cff246120b8fb3152019c96bd8cb0 100644 (file)
@@ -10,7 +10,7 @@
 """
 from jinja.filters import FILTERS as DEFAULT_FILTERS
 from jinja.tests import TESTS as DEFAULT_TESTS
-from jinja.utils import debug_context, safe_range, generate_lorem_ipsum, \
+from jinja.utils import debug_helper, safe_range, generate_lorem_ipsum, \
      watch_changes, flush
 
 
@@ -19,7 +19,7 @@ __all__ = ['DEFAULT_FILTERS', 'DEFAULT_TESTS', 'DEFAULT_NAMESPACE']
 
 DEFAULT_NAMESPACE = {
     'range':                safe_range,
-    'debug':                debug_context,
+    'debug':                debug_helper,
     'lipsum':               generate_lorem_ipsum,
     'watchchanges':         watch_changes,
     'flush':                flush
index ec09e60cd97fb8e21e92e32afc9557df8cfd2a46..033b10128017d2352628cf39a8727a1c67aaea36 100644 (file)
@@ -474,6 +474,8 @@ class Parser(object):
                 # if a string is ASCII only we yield it as string
                 # in other cases as unicode. This works around
                 # problems with datetimeobj.strftime()
+                # also escape newlines in strings
+                t_data = t_data.replace('\n', '\\n')
                 try:
                     str(t_data)
                 except UnicodeError:
index 1fe633592a6584a2d3192b74f56a18b82388b8a0..d58537f9764e9a98a5a8375ef354ac5d611844bb 100644 (file)
@@ -416,7 +416,8 @@ class PythonTranslator(Translator):
                 '    def translate(s, p=None, n=None, r=None):\n'
                 '        if p is None:\n'
                 '            return translator.gettext(s) % (r or {})\n'
-                '        return translator.ngettext(s, p, r[n]) % (r or {})'
+                '        return translator.ngettext(s, p, r[n]) % (r or {})\n'
+                '    context.translate_func = translate'
             )
 
         # add body lines and "generator hook"
@@ -585,7 +586,7 @@ class PythonTranslator(Translator):
         buf = []
         write = lambda x: buf.append(self.indent(x))
 
-        write('if not %r in context.current:' % name)
+        write('if %r not in context.current:' % name)
         self.indention += 1
         write(self.nodeinfo(node))
         if node.seq.__class__ in (ast.Tuple, ast.List):
@@ -683,7 +684,7 @@ class PythonTranslator(Translator):
         self.indention += 1
         write('yield None')
         self.indention -= 2
-        write('yield %s' % self.filter('u\'\'.join(filtered())',
+        write('yield %s' % self.filter('buffereater(filtered)()',
                                        node.filters))
         return '\n'.join(buf)
 
@@ -734,7 +735,7 @@ class PythonTranslator(Translator):
         else:
             replacements = 'None'
         return self.indent(self.nodeinfo(node)) + '\n' +\
-               self.indent('yield translate(%r, %r, %r, %s)' % (
+               self.indent('yield context.translate_func(%r, %r, %r, %s)' % (
             node.singular,
             node.plural,
             node.indicator,
@@ -751,7 +752,7 @@ class PythonTranslator(Translator):
             return self.constants[node.name]
         elif node.name == '_':
             self.require_translations = True
-            return 'translate'
+            return 'context.translate_func'
         return 'context[%r]' % node.name
 
     def handle_compare(self, node):
index 45b19d131934937d0f3e2a88571c23c03ae69d26..33afac713f8f97413b2b0052b2d440e45dfba615 100644 (file)
@@ -29,6 +29,11 @@ if sys.version_info >= (2, 5):
 else:
     deque = None
 
+try:
+    set
+except NameError:
+    from sets import Set as set
+
 #: number of maximal range items
 MAX_RANGE = 1000000
 
@@ -123,15 +128,6 @@ def get_attribute(obj, name):
     return getattr(obj, name)
 
 
-def debug_context(env, context):
-    """
-    Use this function in templates to get a printed context.
-    """
-    from pprint import pformat
-    return pformat(context.to_dict())
-debug_context.jinja_context_callable = True
-
-
 def safe_range(start, stop=None, step=None):
     """
     "Safe" form of range that does not generate too large lists.
@@ -370,6 +366,48 @@ def collect_translations(ast):
     return result
 
 
+class DebugHelper(object):
+    """
+    Debugging Helper. Available in the template as "debug".
+    """
+    jinja_context_callable = True
+    jinja_allowed_attributes = ['filters']
+
+    def __init__(self):
+        raise TypeError('cannot create %r instances' %
+                        self.__class__.__name__)
+
+    def __call__(self, env, context):
+        """Print a nice representation of the context."""
+        from pprint import pformat
+        return pformat(context.to_dict())
+
+    def filters(self, env, context, builtins=True):
+        """List the filters."""
+        from inspect import getdoc
+        strip = set()
+        if not builtins:
+            from jinja.defaults import DEFAULT_FILTERS
+            strip = set(DEFAULT_FILTERS.values())
+        filters = env.filters.items()
+        filters.sort(lambda a, b: cmp(a[0].lower(), b[0].lower()))
+        result = []
+        for name, f in filters:
+            if f in strip:
+                continue
+            doc = '\n'.join('    ' + x for x in (getdoc(f) or '').splitlines())
+            result.append('`%s`\n\n%s' % (name, doc))
+        return '\n\n'.join(result)
+    filters.jinja_context_callable = True
+
+    def __str__(self):
+        print 'use debug() for debugging the context'
+
+
+#: the singleton instance of `DebugHelper`
+debug_helper = object.__new__(DebugHelper)
+
+
 class TracebackLoader(object):
     """
     Fake importer that just returns the source of a template.