From 5b1f04fb91b2da701c9ea913883874eda5c3dafb Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 14:42:56 -0400 Subject: added namespace test --- pyramid/tests/fixtures/components.mak | 3 +++ pyramid/tests/fixtures/hellocompo.mak | 3 +++ pyramid/tests/test_mako_templating.py | 5 +++++ 3 files changed, 11 insertions(+) create mode 100644 pyramid/tests/fixtures/components.mak create mode 100644 pyramid/tests/fixtures/hellocompo.mak diff --git a/pyramid/tests/fixtures/components.mak b/pyramid/tests/fixtures/components.mak new file mode 100644 index 000000000..cc886805c --- /dev/null +++ b/pyramid/tests/fixtures/components.mak @@ -0,0 +1,3 @@ +<%def name="comp()"> +World! + \ No newline at end of file diff --git a/pyramid/tests/fixtures/hellocompo.mak b/pyramid/tests/fixtures/hellocompo.mak new file mode 100644 index 000000000..142676a11 --- /dev/null +++ b/pyramid/tests/fixtures/hellocompo.mak @@ -0,0 +1,3 @@ +<%namespace name="comp" file="pyramid.tests:fixtures/components.mak"/> +Namespace +Hello ${comp.comp()} \ No newline at end of file diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index fbb04273b..8b738c21d 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -402,6 +402,11 @@ class TestIntegration(unittest.TestCase): result = render('hello_inherit_pkg.mak', {}).replace('\r','') self.assertEqual(result, text_('Layout\nHello World!\n')) + def test_render_namespace(self): + from pyramid.renderers import render + result = render('hellocompo.mak', {}).replace('\r','') + self.assertEqual(result, text_('\nNamespace\nHello \nWorld!\n')) + def test_render_to_response(self): from pyramid.renderers import render_to_response result = render_to_response('helloworld.mak', {'a':1}) -- cgit v1.2.3 From f71ed59edb74e9a13362521918e2660e4e4263ba Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 16:32:41 -0400 Subject: added a new makodef renderer to call a def inside a mako template, fixed tests and removed old tuple way of calling def. Based on zzzeek example of client/server templating. --- pyramid/config/rendering.py | 1 + pyramid/mako_templating.py | 19 +++++++++++-------- pyramid/tests/test_mako_templating.py | 21 ++++++++++----------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index 926511b7b..bfa41ee03 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -21,6 +21,7 @@ DEFAULT_RENDERERS = ( ('.pt', chameleon_zpt.renderer_factory), ('.mak', mako_renderer_factory), ('.mako', mako_renderer_factory), + ('.makodef', mako_renderer_factory), ('json', renderers.json_renderer_factory), ('string', renderers.string_renderer_factory), ) diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 208e54bf5..48288c930 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -1,4 +1,5 @@ import os +import re import sys import threading @@ -76,7 +77,11 @@ class MakoRendererFactoryHelper(object): self.settings_prefix = settings_prefix def __call__(self, info): - path = info.name + p = re.compile( + r'(?P[\w_.:/]+)' + r'(?:\#(?P[\w_]+))?' + ) + path, defname = p.match(info.name).group("path", "defname") registry = info.registry settings = info.settings settings_prefix = self.settings_prefix @@ -141,7 +146,7 @@ class MakoRendererFactoryHelper(object): finally: registry_lock.release() - return MakoLookupTemplateRenderer(path, lookup) + return MakoLookupTemplateRenderer(path, defname, lookup) renderer_factory = MakoRendererFactoryHelper('mako.') @@ -156,8 +161,9 @@ class MakoRenderingException(Exception): @implementer(ITemplateRenderer) class MakoLookupTemplateRenderer(object): - def __init__(self, path, lookup): + def __init__(self, path, defname, lookup): self.path = path + self.defname = defname self.lookup = lookup def implementation(self): @@ -167,16 +173,13 @@ class MakoLookupTemplateRenderer(object): context = system.pop('context', None) if context is not None: system['_context'] = context - def_name = None - if isinstance(value, tuple): - def_name, value = value try: system.update(value) except (TypeError, ValueError): raise ValueError('renderer was passed non-dictionary as value') template = self.implementation() - if def_name is not None: - template = template.get_def(def_name) + if self.defname is not None: + template = template.get_def(self.defname) try: result = template.render_unicode(**system) except: diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index 8b738c21d..cd7b140d6 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -315,7 +315,7 @@ class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def test_instance_implements_ITemplate(self): from zope.interface.verify import verifyObject from pyramid.interfaces import ITemplateRenderer - verifyObject(ITemplateRenderer, self._makeOne(None, None)) + verifyObject(ITemplateRenderer, self._makeOne(None, None, None)) def test_class_implements_ITemplate(self): from zope.interface.verify import verifyClass @@ -324,7 +324,7 @@ class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def test_call(self): lookup = DummyLookup() - instance = self._makeOne('path', lookup) + instance = self._makeOne('path', None, lookup) result = instance({}, {'system':1}) self.assertTrue(isinstance(result, text_type)) self.assertEqual(result, text_('result')) @@ -332,29 +332,28 @@ class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def test_call_with_system_context(self): # lame lookup = DummyLookup() - instance = self._makeOne('path', lookup) + instance = self._makeOne('path', None, lookup) result = instance({}, {'context':1}) self.assertTrue(isinstance(result, text_type)) self.assertEqual(result, text_('result')) self.assertEqual(lookup.values, {'_context':1}) - def test_call_with_tuple_value(self): + def test_call_with_defname(self): lookup = DummyLookup() - instance = self._makeOne('path', lookup) - result = instance(('fub', {}), {'context':1}) - self.assertEqual(lookup.deffed, 'fub') + instance = self._makeOne('path', 'defname', lookup) + result = instance({}, {'system':1}) + self.assertTrue(isinstance(result, text_type)) self.assertEqual(result, text_('result')) - self.assertEqual(lookup.values, {'_context':1}) def test_call_with_nondict_value(self): lookup = DummyLookup() - instance = self._makeOne('path', lookup) + instance = self._makeOne('path', None, lookup) self.assertRaises(ValueError, instance, None, {}) def test_call_render_raises(self): from pyramid.mako_templating import MakoRenderingException lookup = DummyLookup(exc=NotImplementedError) - instance = self._makeOne('path', lookup) + instance = self._makeOne('path', None, lookup) try: instance({}, {}) except MakoRenderingException as e: @@ -364,7 +363,7 @@ class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def test_implementation(self): lookup = DummyLookup() - instance = self._makeOne('path', lookup) + instance = self._makeOne('path', None, lookup) result = instance.implementation().render_unicode() self.assertTrue(isinstance(result, text_type)) self.assertEqual(result, text_('result')) -- cgit v1.2.3 From c358304043e7e68c7fc97dff42f88633b8f15c69 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 18:49:53 -0400 Subject: added removed tuple for bw compat --- pyramid/mako_templating.py | 3 +++ pyramid/tests/test_mako_templating.py | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 48288c930..f866e2630 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -173,6 +173,9 @@ class MakoLookupTemplateRenderer(object): context = system.pop('context', None) if context is not None: system['_context'] = context + if self.defname is None: + if isinstance(value, tuple): + self.defname, value = value try: system.update(value) except (TypeError, ValueError): diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index cd7b140d6..6cfa3ea4b 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -338,6 +338,14 @@ class MakoLookupTemplateRendererTests(Base, unittest.TestCase): self.assertEqual(result, text_('result')) self.assertEqual(lookup.values, {'_context':1}) + def test_call_with_tuple_value(self): + lookup = DummyLookup() + instance = self._makeOne('path', None, lookup) + result = instance(('fub', {}), {'context':1}) + self.assertEqual(lookup.deffed, 'fub') + self.assertEqual(result, text_('result')) + self.assertEqual(lookup.values, {'_context':1}) + def test_call_with_defname(self): lookup = DummyLookup() instance = self._makeOne('path', 'defname', lookup) -- cgit v1.2.3 From 59f8017b4a4aa9767bab49b39db362e973bdacf1 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 19:28:55 -0400 Subject: removed .makodef, use tuple value if defname in renderer (bw compat), changed format for package:some/template#defname.mako --- pyramid/config/rendering.py | 1 - pyramid/mako_templating.py | 7 ++++++- pyramid/tests/test_mako_templating.py | 8 ++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pyramid/config/rendering.py b/pyramid/config/rendering.py index bfa41ee03..926511b7b 100644 --- a/pyramid/config/rendering.py +++ b/pyramid/config/rendering.py @@ -21,7 +21,6 @@ DEFAULT_RENDERERS = ( ('.pt', chameleon_zpt.renderer_factory), ('.mak', mako_renderer_factory), ('.mako', mako_renderer_factory), - ('.makodef', mako_renderer_factory), ('json', renderers.json_renderer_factory), ('string', renderers.string_renderer_factory), ) diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index f866e2630..8bd9381f0 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -80,8 +80,10 @@ class MakoRendererFactoryHelper(object): p = re.compile( r'(?P[\w_.:/]+)' r'(?:\#(?P[\w_]+))?' + r'(\.(?P.*))' ) - path, defname = p.match(info.name).group("path", "defname") + asset, defname, ext = p.match(info.name).group('path', 'defname', 'ext') + path = '%s.%s' % (asset, ext) registry = info.registry settings = info.settings settings_prefix = self.settings_prefix @@ -176,6 +178,9 @@ class MakoLookupTemplateRenderer(object): if self.defname is None: if isinstance(value, tuple): self.defname, value = value + else: + if isinstance(value, tuple): + _, value = value try: system.update(value) except (TypeError, ValueError): diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index 6cfa3ea4b..41fa9bdc4 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -353,6 +353,14 @@ class MakoLookupTemplateRendererTests(Base, unittest.TestCase): self.assertTrue(isinstance(result, text_type)) self.assertEqual(result, text_('result')) + def test_call_with_defname_with_tuple_value(self): + lookup = DummyLookup() + instance = self._makeOne('path', 'defname', lookup) + result = instance(('defname', {}), {'context':1}) + self.assertEqual(lookup.deffed, 'defname') + self.assertEqual(result, text_('result')) + self.assertEqual(lookup.values, {'_context':1}) + def test_call_with_nondict_value(self): lookup = DummyLookup() instance = self._makeOne('path', None, lookup) -- cgit v1.2.3 From b015d702d4c5367cd24fa05bd8d83462b6d59ac1 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 19:30:01 -0400 Subject: renamed path for asset in regex --- pyramid/mako_templating.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 8bd9381f0..b02daa23c 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -78,11 +78,11 @@ class MakoRendererFactoryHelper(object): def __call__(self, info): p = re.compile( - r'(?P[\w_.:/]+)' + r'(?P[\w_.:/]+)' r'(?:\#(?P[\w_]+))?' r'(\.(?P.*))' ) - asset, defname, ext = p.match(info.name).group('path', 'defname', 'ext') + asset, defname, ext = p.match(info.name).group('asset', 'defname', 'ext') path = '%s.%s' % (asset, ext) registry = info.registry settings = info.settings -- cgit v1.2.3 From ea009a6d4a1ffa8585faa85581848f6e74a57dfc Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 20:12:55 -0400 Subject: added docs and changes for using defs in mako renderer --- CHANGES.txt | 5 +++++ docs/narr/templates.rst | 16 ++++++++++++++++ pyramid/mako_templating.py | 7 +++++++ 3 files changed, 28 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 7c2af4451..3cb2f2848 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -41,3 +41,8 @@ Features - The static view machinery now raises (rather than returns) ``HTTPNotFound`` and ``HTTPMovedPermanently`` exceptions, so these can be caught by the NotFound view (and other exception views). + +- The mako renderer now accepts a def name and returns the template def + result for the view being called. The uri format using an asset spec is + package:path/to/template#defname.mako. The old way of returning a tuple + from the view is supported for backward compatibility, ('defname', {}). diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 9db0b1c4d..4ac01c96e 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -714,6 +714,22 @@ This template doesn't use any advanced features of Mako, only the :term:`renderer globals`. See the `the Mako documentation `_ to use more advanced features. +Using def inside Mako Templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use a def inside a Mako template, given a :term:`Mako` template file named +``foo.mak`` and a def named ``bar``, you can configure the template as a +:term:`renderer` like so: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + @view_config(renderer='foo#defname.mak') + def my_view(request): + return {'project':'my project'} + .. index:: single: automatic reloading of templates single: template automatic reload diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index b02daa23c..bb4ccb2f0 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -163,6 +163,13 @@ class MakoRenderingException(Exception): @implementer(ITemplateRenderer) class MakoLookupTemplateRenderer(object): + """ Render a :term:`Mako` template using the template + implied by the ``path`` argument.The ``path`` argument may be a + package-relative path, an absolute path, or a :term:`asset + specification`. If a defname is defined, in the form of + package:path/to/template#defname.mako, a function named ``defname`` + inside the template will then be rendered. + """ def __init__(self, path, defname, lookup): self.path = path self.defname = defname -- cgit v1.2.3 From 6cea47e9c34841cdf109899e8d965c67af3a5ce9 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 20:20:17 -0400 Subject: fixed typos --- CHANGES.txt | 2 +- docs/narr/templates.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 3cb2f2848..1fd92fe19 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -42,7 +42,7 @@ Features and ``HTTPMovedPermanently`` exceptions, so these can be caught by the NotFound view (and other exception views). -- The mako renderer now accepts a def name and returns the template def +- The mako renderer now accepts a defname and returns the template def result for the view being called. The uri format using an asset spec is package:path/to/template#defname.mako. The old way of returning a tuple from the view is supported for backward compatibility, ('defname', {}). diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 4ac01c96e..5656026ae 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -718,7 +718,7 @@ Using def inside Mako Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To use a def inside a Mako template, given a :term:`Mako` template file named -``foo.mak`` and a def named ``bar``, you can configure the template as a +``foo.mak`` and a defname ``bar``, you can configure the template as a :term:`renderer` like so: .. code-block:: python -- cgit v1.2.3 From c2d65ff71dac6a9b15119db8c2fb09884f4060e3 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 19 Jun 2012 20:22:34 -0400 Subject: fixed typos --- CHANGES.txt | 2 +- docs/narr/templates.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1fd92fe19..3cb2f2848 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -42,7 +42,7 @@ Features and ``HTTPMovedPermanently`` exceptions, so these can be caught by the NotFound view (and other exception views). -- The mako renderer now accepts a defname and returns the template def +- The mako renderer now accepts a def name and returns the template def result for the view being called. The uri format using an asset spec is package:path/to/template#defname.mako. The old way of returning a tuple from the view is supported for backward compatibility, ('defname', {}). diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index 5656026ae..860010a1a 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -718,7 +718,7 @@ Using def inside Mako Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To use a def inside a Mako template, given a :term:`Mako` template file named -``foo.mak`` and a defname ``bar``, you can configure the template as a +``foo.mak`` and a def named ``bar``, you can configure the template as a :term:`renderer` like so: .. code-block:: python @@ -726,7 +726,7 @@ To use a def inside a Mako template, given a :term:`Mako` template file named from pyramid.view import view_config - @view_config(renderer='foo#defname.mak') + @view_config(renderer='foo#bar.mak') def my_view(request): return {'project':'my project'} -- cgit v1.2.3