Index: repoze/bfg/jinja2/tests/test_bindings.py
===================================================================
--- repoze/bfg/jinja2/tests/test_bindings.py	(revision 5223)
+++ repoze/bfg/jinja2/tests/test_bindings.py	(working copy)
@@ -4,8 +4,8 @@
     def test_load_template(self):
         from repoze.bfg.jinja2.bindings import load_template
         template = load_template('templates/helloworld.jinja2')
-        self.assertEqual(template,
-              u"{% set a, b = 'foo', 'f\xf6\xf6' %}\nHello {{ b }}\n")
+        self.assertEqual(template, 
+            u"{% set a, b = 'foo', 'f\xf6\xf6' %}\nHello {{ b }}\n")
 
     def test_get_template(self):
         from repoze.bfg.jinja2.bindings import get_template
Index: repoze/bfg/jinja2/bindings.py
===================================================================
--- repoze/bfg/jinja2/bindings.py	(revision 5223)
+++ repoze/bfg/jinja2/bindings.py	(working copy)
@@ -1,16 +1,79 @@
+from os.path import getmtime
+
 from webob import Response
 
+from zope.component import queryUtility
+
+from repoze.bfg.interfaces import ISettings
 from repoze.bfg.path import caller_path
 
-from jinja2.loaders import FunctionLoader
+from jinja2.loaders import BaseLoader
 from jinja2 import Environment
 
+def _auto_reload():
+    settings = queryUtility(ISettings)
+    auto_reload = settings and settings.reload_templates
+    return auto_reload
+    
 def load_template(path):
     path = caller_path(path)
     data = open(path, 'rb').read()
     return unicode(data, 'utf-8')
 
-env = Environment(loader=FunctionLoader(load_template))
+class BfgLoader(BaseLoader):
+    """ 
+    Extends jinja2.loaders.FunctionLoader with configurable auto-reloading.
+    
+      >>> loader = BfgLoader(load_template)
+    
+    Without configuration, the loader does not auto reload templates. The   
+    ``get_source`` method returns the template source, null path, and null 
+    ``uptodate`` function.
+    
+      >>> loader.auto_reload is None
+      True
+      >>> source, path, uptodate = loader.get_source(None, 'tests/templates/helloworld.jinja2')
+      >>> source # doctest: +ELLIPSIS
+      u"{% set a, b = 'foo', ..."
+      >>> path is None
+      True
+      >>> uptodate is None
+      True
+    
+    If configured
+    
+      >>> loader.auto_reload = True
+      >>> source, path, uptodate = loader.get_source(None, 'tests/templates/helloworld.jinja2')
+      >>> source # doctest: +ELLIPSIS
+      u"{% set a, b = 'foo', ..."
+      >>> path
+      'tests/templates/helloworld.jinja2'
+      >>> uptodate # doctest: +ELLIPSIS
+      <function uptodate at 0x...>
+    """
+    def __init__(self, func):
+        self.load_func = func
+        self.auto_reload = _auto_reload()
+        
+    def get_source(self, environment, template):
+        rv = self.load_func(template)
+        if rv is None:
+            raise TemplateNotFound(template)
+        elif isinstance(rv, basestring):
+            if not self.auto_reload:
+                return rv, None, None
+            else:
+                path = caller_path(template)
+                mtime = getmtime(path)
+                def uptodate():
+                    try:
+                        return getmtime(path) == mtime
+                    except OSError:
+                        return False
+                return rv, template, uptodate
+        return rv
+        
+env = Environment(loader=BfgLoader(load_template))
 
 def get_template(path):
     """ Return a z3c.pt template object at the package-relative path
