Implemented and documented "joiner"
authorArmin Ronacher <armin.ronacher@active-4.com>
Mon, 13 Oct 2008 21:47:51 +0000 (23:47 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Mon, 13 Oct 2008 21:47:51 +0000 (23:47 +0200)
--HG--
branch : trunk

CHANGES
docs/templates.rst
jinja2/defaults.py
jinja2/loaders.py
jinja2/utils.py

diff --git a/CHANGES b/CHANGES
index c0c7139f99a2ab9bef4254ba1eec9ce0e8631a82..3b50265799f9122fe5a1b31d34e1b101b0693ec7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -37,7 +37,9 @@ Version 2.1
 - inclusions and imports "with context" forward all variables now, not only
   the initial context.
 
-- added a cycle helper called `cycle`.
+- added a cycle helper called `cycler`.
+
+- added a joining helper called `joiner`.
 
 Version 2.0
 -----------
index d797fec047e14ff30e398b3b0bc545ef450e69ee..ac80400614a9a17c1adaf4759140e836241540e9 100644 (file)
@@ -1080,6 +1080,26 @@ The following functions are available in the global scope by default:
     
     **new in Jinja 2.1**
 
+.. class:: joiner(sep=', ')
+
+    A tiny helper that can be use to "join" multiple sections.  A joiner is
+    passed a string and will return that string every time it's calld, except
+    the first time in which situation it returns an empty string.  You can
+    use this to join things::
+
+        {% set pipe = joiner("|") %}
+        {% if categories %} {{ pipe() }}
+            Categories: {{ categories|join(", ") }}
+        {% endif %}
+        {% if author %} {{ pipe() }}
+            Author: {{ author() }}
+        {% endif %}
+        {% if can_edit %} {{ pipe() }}
+            <a href="?action=edit">Edit</a>
+        {% endif %}
+
+    **new in Jinja 2.1**
+
 
 Extensions
 ----------
index 61706aea9951ccb223e5d646d1bcc83ea44815a6..3e24e7decb1d30644faac204b44bab76d857ed9a 100644 (file)
@@ -8,7 +8,7 @@
     :copyright: 2007-2008 by Armin Ronacher.
     :license: BSD, see LICENSE for more details.
 """
-from jinja2.utils import generate_lorem_ipsum, Cycler
+from jinja2.utils import generate_lorem_ipsum, Cycler, Joiner
 
 
 # defaults for the parser / lexer
@@ -30,7 +30,8 @@ DEFAULT_NAMESPACE = {
     'range':        xrange,
     'dict':         lambda **kw: kw,
     'lipsum':       generate_lorem_ipsum,
-    'cycler':       Cycler
+    'cycler':       Cycler,
+    'joiner':       Joiner
 }
 
 
index 8b2221f00f6f0b2ac4a7d154d4b6f33e30166924..c61cd840fbd6f759458af2a695308630d8e59bbc 100644 (file)
@@ -149,8 +149,14 @@ class FileSystemLoader(BaseLoader):
                 contents = f.read().decode(self.encoding)
             finally:
                 f.close()
-            old = path.getmtime(filename)
-            return contents, filename, lambda: path.getmtime(filename) == old
+
+            mtime = path.getmtime(filename)
+            def uptodate():
+                try:
+                    return path.getmtime(filename) == mtime
+                except OSError:
+                    return False
+            return contents, filename, uptodate
         raise TemplateNotFound(template)
 
 
@@ -191,7 +197,10 @@ class PackageLoader(BaseLoader):
             filename = self.provider.get_resource_filename(self.manager, p)
             mtime = path.getmtime(filename)
             def uptodate():
-                return path.getmtime(filename) == mtime
+                try:
+                    return path.getmtime(filename) == mtime
+                except OSError:
+                    return False
 
         source = self.provider.get_resource_string(self.manager, p)
         return source.decode(self.encoding), filename, uptodate
index 338db4a15f0c6d05ba220dc38acfc868e160e802..249e36309d3552b1789ad2011b92f5082c18d3de 100644 (file)
@@ -685,6 +685,20 @@ class Cycler(object):
         return rv
 
 
+class Joiner(object):
+    """A joining helper for templates."""
+
+    def __init__(self, sep=u', '):
+        self.sep = sep
+        self.used = False
+
+    def __call__(self):
+        if not self.used:
+            self.used = True
+            return u''
+        return self.sep
+
+
 # we have to import it down here as the speedups module imports the
 # markup type which is define above.
 try: