.gitignore | ●●●●● patch | view | raw | blame | history | |
pyramid/configuration.py | ●●●●● patch | view | raw | blame | history | |
pyramid/mako_templating.py | ●●●●● patch | view | raw | blame | history | |
pyramid/resource.py | ●●●●● patch | view | raw | blame | history | |
pyramid/tests/fixtures/helloworld.mak | ●●●●● patch | view | raw | blame | history | |
pyramid/tests/fixtures/helloworld.mako | ●●●●● patch | view | raw | blame | history | |
pyramid/tests/test_mako_templating.py | ●●●●● patch | view | raw | blame | history | |
pyramid/tests/test_resource.py | ●●●●● patch | view | raw | blame | history | |
setup.py | ●●●●● patch | view | raw | blame | history |
.gitignore
@@ -5,3 +5,5 @@ *.txt.py .coverage env26 env24 pyramid/configuration.py
@@ -45,6 +45,7 @@ from pyramid import chameleon_text from pyramid import chameleon_zpt from pyramid.mako_templating import renderer_factory as mako_renderer_factory from pyramid import renderers from pyramid.renderers import RendererHelper from pyramid.authorization import ACLAuthorizationPolicy @@ -82,6 +83,8 @@ DEFAULT_RENDERERS = ( ('.pt', chameleon_zpt.renderer_factory), ('.txt', chameleon_text.renderer_factory), ('.mak', mako_renderer_factory), ('.mako', mako_renderer_factory), ('json', renderers.json_renderer_factory), ('string', renderers.string_renderer_factory), ) pyramid/mako_templating.py
New file @@ -0,0 +1,67 @@ from zope.interface import implements from zope.interface import Interface from mako.lookup import TemplateLookup from pyramid.interfaces import ITemplateRenderer from pyramid.exceptions import ConfigurationError from pyramid.threadlocal import get_current_registry from pyramid.settings import get_settings from pyramid.resource import resolve_resource_spec from pyramid.resource import abspath_from_resource_spec class IMakoLookup(Interface): pass def renderer_factory(path): registry = get_current_registry() lookup = registry.queryUtility(IMakoLookup) if lookup is None: settings = get_settings() or {} reload_templates = settings.get('reload_templates', False) directories = settings.get('mako.directories') module_directory = settings.get('mako.module_directory') input_encoding = settings.get('mako.input_encoding', 'utf-8') if directories is None: raise ConfigurationError( 'Mako template used without a lookup path') directories = directories.splitlines() directories = [ abspath_from_resource_spec(d) for d in directories ] lookup = TemplateLookup(directories=directories, module_directory=module_directory, input_encoding=input_encoding, filesystem_checks=reload_templates) registry.registerUtility(lookup, IMakoLookup) _, path = resolve_resource_spec(path) return MakoLookupTemplateRenderer(path, lookup) class MakoLookupTemplateRenderer(object): implements(ITemplateRenderer) def __init__(self, path, lookup): self.path = path self.lookup = lookup def implementation(self): return self.template @property def template(self): return self.lookup.get_template(self.path) def __call__(self, value, system): 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.template if def_name is not None: template = template.get_def(def_name) result = template.render_unicode(**system) return result pyramid/resource.py
@@ -198,4 +198,10 @@ relpath.replace(os.path.sep, '/')) return abspath def abspath_from_resource_spec(spec, pname='__main__'): if pname is None: return spec pname, filename = resolve_resource_spec(spec, pname) if pname is None: return filename return pkg_resources.resource_filename(pname, filename) pyramid/tests/fixtures/helloworld.mak
New file @@ -0,0 +1,3 @@ ## -*- coding: utf-8 -*- <% a, b = 'foo', u'föö' %> Hello ${u'föö'} pyramid/tests/fixtures/helloworld.mako
New file @@ -0,0 +1,3 @@ ## -*- coding: utf-8 -*- <% a, b = 'foo', u'föö' %> Hello ${u'föö'} pyramid/tests/test_mako_templating.py
New file @@ -0,0 +1,149 @@ ## come on python gimme some of that sweet, sweet -*- coding: utf-8 -*- import unittest class Base(object): def setUp(self): from pyramid.configuration import Configurator self.config = Configurator() self.config.begin() import os here = os.path.abspath(os.path.dirname(__file__)) self.templates_dir = os.path.join(here, 'fixtures') def tearDown(self): self.config.end() class Test_renderer_factory(Base, unittest.TestCase): def _callFUT(self, path): from pyramid.mako_templating import renderer_factory return renderer_factory(path) def test_no_directories(self): from pyramid.exceptions import ConfigurationError self.assertRaises(ConfigurationError, self._callFUT, 'path') def test_no_lookup(self): from pyramid.mako_templating import IMakoLookup self.config.add_settings({'mako.directories':self.templates_dir}) renderer = self._callFUT('helloworld.mak') lookup = self.config.registry.getUtility(IMakoLookup) self.assertEqual(lookup.directories, [self.templates_dir]) self.assertEqual(lookup.filesystem_checks, False) self.assertEqual(renderer.path, 'helloworld.mak') self.assertEqual(renderer.lookup, lookup) def test_composite_directories_path(self): from pyramid.mako_templating import IMakoLookup twice = self.templates_dir + '\n' + self.templates_dir self.config.add_settings({'mako.directories':twice}) self._callFUT('helloworld.mak') lookup = self.config.registry.getUtility(IMakoLookup) self.assertEqual(lookup.directories, [self.templates_dir]*2) def test_with_lookup(self): from pyramid.mako_templating import IMakoLookup lookup = dict() self.config.registry.registerUtility(lookup, IMakoLookup) renderer = self._callFUT('helloworld.mak') self.assertEqual(renderer.lookup, lookup) self.assertEqual(renderer.path, 'helloworld.mak') class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def _getTargetClass(self): from pyramid.mako_templating import MakoLookupTemplateRenderer return MakoLookupTemplateRenderer def _makeOne(self, *arg, **kw): klass = self._getTargetClass() return klass(*arg, **kw) def test_instance_implements_ITemplate(self): from zope.interface.verify import verifyObject from pyramid.interfaces import ITemplateRenderer verifyObject(ITemplateRenderer, self._makeOne(None, None)) def test_class_implements_ITemplate(self): from zope.interface.verify import verifyClass from pyramid.interfaces import ITemplateRenderer verifyClass(ITemplateRenderer, self._getTargetClass()) def test_call(self): lookup = DummyLookup() instance = self._makeOne('path', lookup) result = instance({}, {'system':1}) self.failUnless(isinstance(result, unicode)) self.assertEqual(result, u'result') def test_call_with_system_context(self): # lame lookup = DummyLookup() instance = self._makeOne('path', lookup) result = instance({}, {'context':1}) self.failUnless(isinstance(result, unicode)) self.assertEqual(result, u'result') self.assertEqual(lookup.values, {'_context':1}) def test_call_with_tuple_value(self): lookup = DummyLookup() instance = self._makeOne('path', lookup) result = instance(('fub', {}), {'context':1}) self.assertEqual(lookup.deffed, 'fub') self.assertEqual(result, u'result') self.assertEqual(lookup.values, {'_context':1}) def test_call_with_nondict_value(self): lookup = DummyLookup() instance = self._makeOne('path', lookup) self.assertRaises(ValueError, instance, None, {}) def test_implementation(self): lookup = DummyLookup() instance = self._makeOne('path', lookup) result = instance.implementation().render_unicode() self.failUnless(isinstance(result, unicode)) self.assertEqual(result, u'result') class TestIntegration(unittest.TestCase): def setUp(self): import pyramid.mako_templating from pyramid.configuration import Configurator self.config = Configurator() self.config.begin() self.config.add_settings({'mako.directories': 'pyramid.tests:fixtures'}) self.config.add_renderer('.mak', pyramid.mako_templating.renderer_factory) def tearDown(self): self.config.end() def test_render(self): from pyramid.renderers import render result = render('helloworld.mak', {'a':1}) self.assertEqual(result, u'\nHello föö\n') def test_render_to_response(self): from pyramid.renderers import render_to_response result = render_to_response('helloworld.mak', {'a':1}) self.assertEqual(result.ubody, u'\nHello föö\n') def test_get_renderer(self): from pyramid.renderers import get_renderer result = get_renderer('helloworld.mak') self.assertEqual(result.implementation().render_unicode(), u'\nHello föö\n') class DummyLookup(object): def get_template(self, path): self.path = path return self def get_def(self, path): self.deffed = path return self def render_unicode(self, **values): self.values = values return u'result' pyramid/tests/test_resource.py
@@ -401,7 +401,27 @@ o = self._makeOne('foo.pt', 'package', 'bar.pt') result = o('notfound.pt') self.assertEqual(result, None) class Test_abspath_from_resource_spec(unittest.TestCase): def _callFUT(self, spec, pname='__main__'): from pyramid.resource import abspath_from_resource_spec return abspath_from_resource_spec(spec, pname) def test_pname_is_None_before_resolve_resource_spec(self): result = self._callFUT('abc', None) self.assertEqual(result, 'abc') def test_pname_is_None_after_resolve_resource_spec(self): result = self._callFUT('/abc', '__main__') self.assertEqual(result, '/abc') def test_pkgrelative(self): import os here = os.path.dirname(__file__) path = os.path.abspath(here) result = self._callFUT('abc', 'pyramid.tests') self.assertEqual(result, os.path.join(path, 'abc')) class DummyOverride: def __init__(self, result): self.result = result setup.py
@@ -29,6 +29,7 @@ install_requires=[ 'Chameleon >= 1.2.3', 'Mako', 'Paste > 1.7', # temp version pin to prevent PyPi install failure :-( 'PasteDeploy', 'PasteScript',