Josip Delic <delij...@gmail.com> added the comment:

sorry for the late response. i moved from freiburg to hamburg.
i looked a little bit closer at the implementation in chameleon_zpt.py. I've
changed my code to work like it. I've added a first version of my changes,
waiting for feedback ;-)

__________________________________
Repoze Bugs <b...@bugs.repoze.org>
<http://bugs.repoze.org/issue97>
__________________________________
Index: repoze/bfg/jinja2/tests/templates_more/hellomacro.jinja2
===================================================================
--- repoze/bfg/jinja2/tests/templates_more/hellomacro.jinja2	(Revision 0)
+++ repoze/bfg/jinja2/tests/templates_more/hellomacro.jinja2	(Revision 0)
@@ -0,0 +1,5 @@
+{% import 'hellomacro.macro_jinja2' as macro %}
+{{ macro.foo('delijati') }}
+
+{% import 'hellomacromore.macro_jinja2' as macro2 %}
+{{ macro2.foo('jatideli') }}
Index: repoze/bfg/jinja2/tests/templates_more/hellomacromore.macro_jinja2
===================================================================
--- repoze/bfg/jinja2/tests/templates_more/hellomacromore.macro_jinja2	(Revision 0)
+++ repoze/bfg/jinja2/tests/templates_more/hellomacromore.macro_jinja2	(Revision 0)
@@ -0,0 +1,5 @@
+{% macro foo(name) -%}
+  Hello {{ name }}
+{%- endmacro %}
+
+
Index: repoze/bfg/jinja2/tests/test_bindings.py
===================================================================
--- repoze/bfg/jinja2/tests/test_bindings.py	(Revision 6678)
+++ repoze/bfg/jinja2/tests/test_bindings.py	(Arbeitskopie)
@@ -1,146 +1,204 @@
-import os.path
 import unittest
-from repoze.bfg import testing
 
-class TestAutoReload(unittest.TestCase):
+from repoze.bfg.testing import cleanUp
+
+class Base(object):
     def setUp(self):
-        testing.cleanUp()
+        cleanUp()
 
     def tearDown(self):
-        testing.cleanUp()
-        
-    def _callFUT(self):
-        from repoze.bfg.jinja2.bindings import _auto_reload
-        return _auto_reload()
+        cleanUp()
 
-    def test_true(self):
-        from repoze.bfg.interfaces import ISettings
-        class Settings:
-            reload_templates = True
-        settings = Settings()
-        testing.registerUtility(settings, ISettings)
-        self.assertEqual(self._callFUT(), True)
+    def _getTemplatePath(self, name):
+        import os
+        here = os.path.abspath(os.path.dirname(__file__))
+        return os.path.join(here, 'templates', name)
         
-    def test_false(self):
-        from repoze.bfg.interfaces import ISettings
-        class Settings:
-            reload_templates = True
-        settings = Settings()
-        testing.registerUtility(settings, ISettings)
-        self.assertEqual(self._callFUT(), True)
+class JINJA2TemplateRenderer(Base, unittest.TestCase):
+    def _getTargetClass(self):
+        from repoze.bfg.jinja2.bindings import JINJA2TemplateRenderer
+        return JINJA2TemplateRenderer
 
-    def test_unregistered(self):
-        self.assertEqual(self._callFUT(), False)
+    def _makeOne(self, *arg, **kw):
+        klass = self._getTargetClass()
+        return klass(*arg, **kw)
 
-class TestLoadTemplate(unittest.TestCase):
-    def _callFUT(self, path):
-        from repoze.bfg.jinja2.bindings import load_template
-        return load_template(path)
+    def test_instance_implements_ITemplate(self):
+        from zope.interface.verify import verifyObject
+        from repoze.bfg.interfaces import ITemplateRenderer
+        path = self._getTemplatePath('helloworld.jinja2')
+        verifyObject(ITemplateRenderer, self._makeOne(path))
+
+    def test_class_implements_ITemplate(self):
+        from zope.interface.verify import verifyClass
+        from repoze.bfg.interfaces import ITemplateRenderer
+        verifyClass(ITemplateRenderer, self._getTargetClass())
+
+    def test_call(self):
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        instance = self._makeOne(minimal)
+        result = instance({}, {})
+        self.failUnless(isinstance(result, unicode))
+        self.assertEqual(result, u'\nHello f\xf6\xf6')
+
+    def test_call_with_nondict_value(self):
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        instance = self._makeOne(minimal)
+        self.assertRaises(ValueError, instance, None, {})
+
+    def test_implementation(self):
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        instance = self._makeOne(minimal)
+        result = instance.implementation().render()
+        self.failUnless(isinstance(result, unicode))
+        self.assertEqual(result, u'\nHello f\xf6\xf6')
         
-    def test_load_template(self):
-        template = self._callFUT('templates/helloworld.jinja2')
-        self.assertEqual(template[0], 
-            u"{% set a, b = 'foo', 'f\xf6\xf6' %}\nHello {{ b }}\n")
-        self.assert_(
-            template[1].endswith('tests/templates/helloworld.jinja2')
-            )
-        uptodate = template[2]
-        self.assertEqual(uptodate(), True)
 
-    def test_load_template_deleted_template_uptodate(self):
-        name = 'templates/to_delete.jinja2'
-        path = os.path.join(os.path.dirname(__file__), name)
-        f = open(path, 'w')
-        f.write('')
-        f.close()
-        template = self._callFUT(name)
-        uptodate = template[2]
-        self.assertEqual(uptodate(), True)
-        os.unlink(path)
-        self.assertEqual(uptodate(), False)
-        self.assertEqual(self._callFUT(name), None)
+class RenderTemplateTests(Base, unittest.TestCase):
+    def _callFUT(self, name, **kw):
+        from repoze.bfg.jinja2.bindings import render_template
+        return render_template(name, **kw)
 
-    def test_load_template_nonexistent_template(self):
-        from repoze.bfg.jinja2.bindings import load_template
-        name = 'templates/nonexistent.jinja2'
-        path = os.path.join(os.path.dirname(__file__), name)
-        self.assertEqual(load_template(name), None)
-
-class TestBfgLoader(unittest.TestCase):
-    def _getTargetClass(self):
-        from repoze.bfg.jinja2.bindings import BfgLoader
-        return BfgLoader
+    def test_it(self):
+        rendering = self._callFUT('templates/helloworld.jinja2')
+        self.assertEqual(rendering, u'\nHello f\xf6\xf6')
     
-    def _makeOne(self, load_func):
-        return self._getTargetClass()(load_func)
 
-    def test_get_source_autoreload_None_default(self):
-        def load_func(path):
-            return u'123'
-        loader = self._makeOne(load_func)
-        class Environment:
-            auto_reload = False
-        environ = Environment()
-        result = loader.get_source(environ, 'whatever')
-        self.assertEqual(loader.auto_reload, False)
-        self.assertEqual(result, (u'123', None, None))
-        self.assertEqual(environ.auto_reload, False)
+class RenderTemplateToResponseTests(Base, unittest.TestCase):
+    def _callFUT(self, name, **kw):
+        from repoze.bfg.jinja2.bindings import render_template_to_response
+        return render_template_to_response(name, **kw)
 
-    def test_get_source_autoreload_None_withisettings(self):
-        def load_func(path):
-            return u'123'
-        loader = self._makeOne(load_func)
-        class Environment:
-            auto_reload = False
-        environ = Environment()
-        from repoze.bfg.interfaces import ISettings
-        class Settings:
-            reload_templates = True
-        settings = Settings()
-        testing.registerUtility(settings, ISettings)
-        result = loader.get_source(environ, 'whatever')
-        self.assertEqual(loader.auto_reload, True)
-        self.assertEqual(result, (u'123', None, None))
-        self.assertEqual(environ.auto_reload, True)
+    def test_it(self):
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        result = self._callFUT(minimal)
+        from webob import Response
+        self.failUnless(isinstance(result, Response))
+        self.assertEqual(result.app_iter,
+                     ['\nHello f\xc3\xb6\xc3\xb6'])
+        self.assertEqual(result.status, '200 OK')
+        self.assertEqual(len(result.headerlist), 2)
 
-    def test_get_source_autoreload_true(self):
-        def load_func(path):
-            return u'123'
-        loader = self._makeOne(load_func)
-        loader.auto_reload = True
-        class Environment:
-            auto_reload = False
-        environ = Environment()
-        result = loader.get_source(environ, 'whatever')
-        self.assertEqual(result, (u'123', None, None))
-        self.assertEqual(environ.auto_reload, True)
+    def test_iresponsefactory_override(self):
+        from zope.component import getGlobalSiteManager
+        gsm = getGlobalSiteManager()
+        from webob import Response
+        class Response2(Response):
+            pass
+        from repoze.bfg.interfaces import IResponseFactory
+        gsm.registerUtility(Response2, IResponseFactory)
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        result = self._callFUT(minimal)
+        self.failUnless(isinstance(result, Response2))
 
-class TestGetTemplate(unittest.TestCase):
-    def _callFUT(self, path):
+class GetRendererTests(Base, unittest.TestCase):
+    def _callFUT(self, name):
+        from repoze.bfg.jinja2.bindings import get_renderer
+        return get_renderer(name)
+
+    def test_nonabs_registered(self):
+        from zope.component import getGlobalSiteManager
+        from zope.component import queryUtility
+        from repoze.bfg.jinja2.bindings import JINJA2TemplateRenderer
+        from repoze.bfg.interfaces import ITemplateRenderer
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        utility = JINJA2TemplateRenderer(minimal)
+        gsm = getGlobalSiteManager()
+        gsm.registerUtility(utility, ITemplateRenderer, name=minimal)
+        result = self._callFUT(minimal)
+        self.assertEqual(result, utility)
+        self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility)
+        
+    def test_nonabs_unregistered(self):
+        from zope.component import getGlobalSiteManager
+        from zope.component import queryUtility
+        from repoze.bfg.jinja2.bindings import JINJA2TemplateRenderer
+        from repoze.bfg.interfaces import ITemplateRenderer
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        self.assertEqual(queryUtility(ITemplateRenderer, minimal), None)
+        utility = JINJA2TemplateRenderer(minimal)
+        gsm = getGlobalSiteManager()
+        gsm.registerUtility(utility, ITemplateRenderer, name=minimal)
+        result = self._callFUT(minimal)
+        self.assertEqual(result, utility)
+        self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility)
+
+    def test_explicit_registration(self):
+        from zope.component import getGlobalSiteManager
+        from repoze.bfg.interfaces import ITemplateRenderer
+        class Dummy:
+            template = object()
+        gsm = getGlobalSiteManager()
+        utility = Dummy()
+        gsm.registerUtility(utility, ITemplateRenderer, name='foo')
+        result = self._callFUT('foo')
+        self.failUnless(result is utility)
+
+class GetTemplateTests(Base, unittest.TestCase):
+    def _callFUT(self, name):
         from repoze.bfg.jinja2.bindings import get_template
-        return get_template(path)
+        return get_template(name)
+
+    def test_nonabs_registered(self):
+        from zope.component import getGlobalSiteManager
+        from zope.component import queryUtility
+        from repoze.bfg.jinja2.bindings import JINJA2TemplateRenderer
+        from repoze.bfg.interfaces import ITemplateRenderer
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        utility = JINJA2TemplateRenderer(minimal)
+        gsm = getGlobalSiteManager()
+        gsm.registerUtility(utility, ITemplateRenderer, name=minimal)
+        result = self._callFUT(minimal)
+        self.assertEqual(result.filename, minimal)
+        self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility)
         
-    def test_it(self):
-        template = self._callFUT('templates/helloworld.jinja2')
-        self.assertEqual(template.module.a, 'foo')
-        self.assertEqual(template.module.b, u'f\xf6\xf6')
+    def test_nonabs_unregistered(self):
+        from zope.component import getGlobalSiteManager
+        from zope.component import queryUtility
+        from repoze.bfg.jinja2.bindings import JINJA2TemplateRenderer
+        from repoze.bfg.interfaces import ITemplateRenderer
+        minimal = self._getTemplatePath('helloworld.jinja2')
+        self.assertEqual(queryUtility(ITemplateRenderer, minimal), None)
+        utility = JINJA2TemplateRenderer(minimal)
+        gsm = getGlobalSiteManager()
+        gsm.registerUtility(utility, ITemplateRenderer, name=minimal)
+        result = self._callFUT(minimal)
+        self.assertEqual(result.filename, minimal)
+        self.assertEqual(queryUtility(ITemplateRenderer, minimal), utility)
 
-class TestRenderTemplate(unittest.TestCase):
+    def test_explicit_registration(self):
+        from zope.component import getGlobalSiteManager
+        from repoze.bfg.interfaces import ITemplateRenderer
+        class Dummy:
+            template = object()
+            def implementation(self):
+                return self.template
+        gsm = getGlobalSiteManager()
+        utility = Dummy()
+        gsm.registerUtility(utility, ITemplateRenderer, name='foo')
+        result = self._callFUT('foo')
+        self.failUnless(result is utility.template)
+
+class TestRenderMacroTemplate(unittest.TestCase):
     def _callFUT(self, path):
         from repoze.bfg.jinja2.bindings import render_template
         return render_template(path)
-
+        
     def test_it(self):
-        rendering = self._callFUT('templates/helloworld.jinja2')
-        self.assertEqual(rendering, u'\nHello f\xf6\xf6')
-
-class TestRenderTemplateToResponse(unittest.TestCase):
+        rendering = self._callFUT('templates/hellomacro.jinja2')
+        self.assertEqual(rendering, u'\nHello delijati\n')
+ 
+class TestRenderMacroTemplateMore(unittest.TestCase):
     def _callFUT(self, path):
-        from repoze.bfg.jinja2.bindings import render_template_to_response
-        return render_template_to_response(path)
+        from repoze.bfg.jinja2.bindings import render_template
+        return render_template(path)
         
     def test_it(self):
-        response = self._callFUT('templates/helloworld.jinja2')
-        self.assertEqual(response.app_iter[0],
-                         u'\nHello f\xf6\xf6'.encode('utf-8'))
+        rendering = self._callFUT('templates_more/hellomacro.jinja2')
+        self.assertEqual(rendering, u'\nHello delijati\n\n\nHello jatideli')
+      
         
+        
+        
+
+
Index: repoze/bfg/jinja2/tests/templates/hellomacro.jinja2
===================================================================
--- repoze/bfg/jinja2/tests/templates/hellomacro.jinja2	(Revision 0)
+++ repoze/bfg/jinja2/tests/templates/hellomacro.jinja2	(Revision 0)
@@ -0,0 +1,3 @@
+{% import 'hellomacro.macro_jinja2' as macro %}
+{{ macro.foo('delijati') }}
+
Index: repoze/bfg/jinja2/tests/templates/hellomacro.macro_jinja2
===================================================================
--- repoze/bfg/jinja2/tests/templates/hellomacro.macro_jinja2	(Revision 0)
+++ repoze/bfg/jinja2/tests/templates/hellomacro.macro_jinja2	(Revision 0)
@@ -0,0 +1,5 @@
+{% macro foo(name) -%}
+  Hello {{ name }}
+{%- endmacro %}
+
+
Index: repoze/bfg/jinja2/bindings.py
===================================================================
--- repoze/bfg/jinja2/bindings.py	(Revision 6678)
+++ repoze/bfg/jinja2/bindings.py	(Arbeitskopie)
@@ -1,30 +1,31 @@
-from os.path import getmtime
-
 from webob import Response
 
 from zope.component import queryUtility
+from zope.interface import implements
 
-from repoze.bfg.interfaces import ISettings
-from repoze.bfg.path import caller_path
+from repoze.bfg.interfaces import IResponseFactory
+from repoze.bfg.interfaces import ITemplateRenderer
 
+from repoze.bfg.renderers import template_renderer_factory
+from repoze.bfg.settings import get_settings
+
 from jinja2.loaders import FunctionLoader
-from jinja2 import Environment
+from jinja2 import Environment, ChoiceLoader, FileSystemLoader
+import os
 
-def _auto_reload():
-    settings = queryUtility(ISettings)
-    auto_reload = (settings and settings.reload_templates) or False
-    return auto_reload
-    
+def renderer_factory(path, level=4):
+    return template_renderer_factory(path, JINJA2TemplateRenderer, level=4)
+
 def load_template(path):
-    path = caller_path(path)
+    #path = caller_path(path)
     try:
         data = open(path, 'rb').read()
-        mtime = getmtime(path)
+        mtime = os.path.getmtime(path)
     except (OSError, IOError):
         return None
     def uptodate():
         try:
-            return getmtime(path) == mtime
+            return os.path.getmtime(path) == mtime
         except (OSError, IOError):
             return False
     return unicode(data, 'utf-8'), path, uptodate
@@ -34,33 +35,74 @@
     Extends jinja2.loaders.FunctionLoader with configurable auto-reloading.    
     """
     auto_reload = None
+
     def get_source(self, environment, template):
         if self.auto_reload is None:
-            self.auto_reload = _auto_reload()
+            settings = get_settings()
+            self.auto_reload = settings and settings['reload_templates']
         environment.auto_reload = self.auto_reload
         return super(BfgLoader, self).get_source(environment, template)
-        
-env = Environment(loader=BfgLoader(load_template))
 
+class JINJA2TemplateRenderer(object):
+    implements(ITemplateRenderer)
+
+    loader_array = []
+    env = None
+    path = ""
+
+    def __init__(self, path):
+        self.loader_array.append(BfgLoader(load_template))
+        settings = get_settings()
+        auto_reload = settings and settings['reload_templates']
+        self.path = path
+        self.env = Environment(loader=ChoiceLoader(self.loader_array))
+
+    def implementation(self):
+        fsla = [loa for loa in self.env.loader.loaders if isinstance(loa, FileSystemLoader)]
+        if len(fsla) == 0:
+            self.env.loader.loaders.append(FileSystemLoader(os.path.dirname(self.path)))
+        else:
+            # searchpath is an array 
+            fsl = [loa for loa in fsla if os.path.dirname(self.path) not in loa.searchpath ]
+            if len(fsl) == len(fsla):
+                self.env.loader.loaders.append(FileSystemLoader(os.path.dirname(self.path)))
+
+        return self.env.get_template(self.path)
+
+    def __call__(self, value, system):
+        try:
+            system.update(value)
+        except (TypeError, ValueError):
+            raise ValueError('renderer was passed non-dictionary as value')
+        result = self.implementation().render(**system)
+        return result
+
+def get_renderer(path):
+    """ Return a callable ``ITemplateRenderer`` object representing a
+    ``chameleon.zpt`` template at the package-relative path (may also
+    be absolute). """
+    return renderer_factory(path)
+
 def get_template(path):
-    """ Return a z3c.pt template object at the package-relative path
-    (may also be absolute) """
-    path = caller_path(path)
-    return env.get_template(path)
+    """ Return a ``chameleon.zpt`` template at the package-relative
+    path (may also be absolute).  """
+    renderer = renderer_factory(path)
+    return renderer.implementation()
 
 def render_template(path, **kw):
-    """ Render a z3c.pt (ZPT) template at the package-relative path
-    (may also be absolute) using the kwargs in ``*kw`` as top-level
-    names and return a string. """
-    path = caller_path(path)
-    template = get_template(path)
-    return template.render(**kw)
+    """ Render a ``chameleon.zpt`` template at the package-relative
+    path (may also be absolute) using the kwargs in ``*kw`` as
+    top-level names and return a string."""
+    renderer = renderer_factory(path)
+    return renderer(kw, {})
 
 def render_template_to_response(path, **kw):
-    """ Render a z3c.pt (ZPT) template at the package-relative path
-    (may also be absolute) using the kwargs in ``*kw`` as top-level
-    names and return a Response object. """
-    path = caller_path(path)
-    result = render_template(path, **kw)
-    return Response(result)
+    """ Render a ``chameleon.zpt`` template at the package-relative
+    path (may also be absolute) using the kwargs in ``*kw`` as
+    top-level names and return a Response object with the body as the
+    template result. """
+    renderer = renderer_factory(path)
+    result = renderer(kw, {})
+    response_factory = queryUtility(IResponseFactory, default=Response)
+    return response_factory(result)
 
Index: CHANGES.txt
===================================================================
--- CHANGES.txt	(Revision 6678)
+++ CHANGES.txt	(Arbeitskopie)
@@ -3,7 +3,8 @@
 
 Next release
 ------------
-
+- added macro support, now it also add the template folder
+- changed implementation to work like in chamelon_zpt.py
 - Respect ``reload_templates`` option in BFG.
 
 0.3 (2009-05-03)
_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to