summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-06-19 21:41:42 -0400
committerChris McDonough <chrism@plope.com>2012-06-19 21:41:42 -0400
commita5d9fb4fe86ed7d3da785af6b8b8e82e21d7ae63 (patch)
tree23760cfe4cf86ea1a7d754a8826c5489f3cae5f8
parent3da92290bfaa8b4072019c916e75cd96ebc0f6dc (diff)
parentc2d65ff71dac6a9b15119db8c2fb09884f4060e3 (diff)
downloadpyramid-a5d9fb4fe86ed7d3da785af6b8b8e82e21d7ae63.tar.gz
pyramid-a5d9fb4fe86ed7d3da785af6b8b8e82e21d7ae63.tar.bz2
pyramid-a5d9fb4fe86ed7d3da785af6b8b8e82e21d7ae63.zip
Merge branch 'master' of github.com:Pylons/pyramid
-rw-r--r--CHANGES.txt5
-rw-r--r--docs/narr/templates.rst16
-rw-r--r--pyramid/mako_templating.py34
-rw-r--r--pyramid/tests/fixtures/components.mak3
-rw-r--r--pyramid/tests/fixtures/hellocompo.mak3
-rw-r--r--pyramid/tests/test_mako_templating.py34
6 files changed, 80 insertions, 15 deletions
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..860010a1a 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
<http://www.makotemplates.org/>`_ 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#bar.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 208e54bf5..bb4ccb2f0 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,13 @@ class MakoRendererFactoryHelper(object):
self.settings_prefix = settings_prefix
def __call__(self, info):
- path = info.name
+ p = re.compile(
+ r'(?P<asset>[\w_.:/]+)'
+ r'(?:\#(?P<defname>[\w_]+))?'
+ r'(\.(?P<ext>.*))'
+ )
+ asset, defname, ext = p.match(info.name).group('asset', 'defname', 'ext')
+ path = '%s.%s' % (asset, ext)
registry = info.registry
settings = info.settings
settings_prefix = self.settings_prefix
@@ -141,7 +148,7 @@ class MakoRendererFactoryHelper(object):
finally:
registry_lock.release()
- return MakoLookupTemplateRenderer(path, lookup)
+ return MakoLookupTemplateRenderer(path, defname, lookup)
renderer_factory = MakoRendererFactoryHelper('mako.')
@@ -156,8 +163,16 @@ class MakoRenderingException(Exception):
@implementer(ITemplateRenderer)
class MakoLookupTemplateRenderer(object):
- def __init__(self, path, lookup):
+ """ 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
self.lookup = lookup
def implementation(self):
@@ -167,16 +182,19 @@ 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
+ 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):
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/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!
+</%def> \ 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..41fa9bdc4 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,7 +332,7 @@ 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'))
@@ -340,21 +340,36 @@ class MakoLookupTemplateRendererTests(Base, unittest.TestCase):
def test_call_with_tuple_value(self):
lookup = DummyLookup()
- instance = self._makeOne('path', lookup)
+ 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)
+ result = instance({}, {'system':1})
+ 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', 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 +379,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'))
@@ -402,6 +417,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})