diff options
| author | Chris McDonough <chrism@plope.com> | 2012-02-19 12:55:35 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2012-02-19 12:55:35 -0500 |
| commit | d679fac8a17d3eaf1cca9a4edaf37b4e56f1d010 (patch) | |
| tree | 8b22042a5d40d6c586693331f3590c0400b65393 | |
| parent | 8d9aafb56f00506109cce444e6037cba63428ad4 (diff) | |
| download | pyramid-d679fac8a17d3eaf1cca9a4edaf37b4e56f1d010.tar.gz pyramid-d679fac8a17d3eaf1cca9a4edaf37b4e56f1d010.tar.bz2 pyramid-d679fac8a17d3eaf1cca9a4edaf37b4e56f1d010.zip | |
- Create a "MakoRendererFactoryHelper" that provides customizable settings
key prefixes. Allows settings prefixes other than "mako." to be used to
create different factories that don't use the global mako settings. This
will be useful for the debug toolbar, which can currently be sabotaged by
someone using custom mako configuration settings.
| -rw-r--r-- | CHANGES.txt | 9 | ||||
| -rw-r--r-- | TODO.txt | 6 | ||||
| -rw-r--r-- | pyramid/mako_templating.py | 125 | ||||
| -rw-r--r-- | pyramid/tests/test_mako_templating.py | 98 |
4 files changed, 149 insertions, 89 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index feba9156e..f3ba85cc3 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -105,6 +105,15 @@ Dependencies - Depend on ``venusian`` >= 1.0a3 to provide scan ``ignore`` support. +Internal +-------- + +- Create a "MakoRendererFactoryHelper" that provides customizable settings + key prefixes. Allows settings prefixes other than "mako." to be used to + create different factories that don't use the global mako settings. This + will be useful for the debug toolbar, which can currently be sabotaged by + someone using custom mako configuration settings. + 1.3a7 (2012-02-07) ================== @@ -4,12 +4,6 @@ Pyramid TODOs Nice-to-Have ------------ -- Create a "mako_renderer_factory_factory" that provides searches in settings - for "mako."-prefixed keys but allows other prefixes to be used to create - different factories that don't use the global mako settings. This would be - useful for the debug toolbar, which can currently be sabotaged by someone - using custom mako configuration settings. - - Add docs about upgrading between Pyramid versions (e.g. how to see deprecation warnings). diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 761695220..b2db28ba7 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -65,58 +65,79 @@ class PkgResourceTemplateLookup(TemplateLookup): registry_lock = threading.Lock() -def renderer_factory(info): - path = info.name - registry = info.registry - settings = info.settings - lookup = registry.queryUtility(IMakoLookup) - if lookup is None: - reload_templates = settings.get('reload_templates', False) - directories = settings.get('mako.directories', []) - module_directory = settings.get('mako.module_directory', None) - input_encoding = settings.get('mako.input_encoding', 'utf-8') - error_handler = settings.get('mako.error_handler', None) - default_filters = settings.get('mako.default_filters', 'h') - imports = settings.get('mako.imports', None) - strict_undefined = settings.get('mako.strict_undefined', 'false') - preprocessor = settings.get('mako.preprocessor', None) - if not is_nonstr_iter(directories): - directories = list(filter(None, directories.splitlines())) - directories = [ abspath_from_asset_spec(d) for d in directories ] - if module_directory is not None: - module_directory = abspath_from_asset_spec(module_directory) - if error_handler is not None: - dotted = DottedNameResolver(info.package) - error_handler = dotted.maybe_resolve(error_handler) - if default_filters is not None: - if not is_nonstr_iter(default_filters): - default_filters = list(filter( - None, default_filters.splitlines())) - if imports is not None: - if not is_nonstr_iter(imports): - imports = list(filter(None, imports.splitlines())) - strict_undefined = asbool(strict_undefined) - if preprocessor is not None: - dotted = DottedNameResolver(info.package) - preprocessor = dotted.maybe_resolve(preprocessor) - - - lookup = PkgResourceTemplateLookup(directories=directories, - module_directory=module_directory, - input_encoding=input_encoding, - error_handler=error_handler, - default_filters=default_filters, - imports=imports, - filesystem_checks=reload_templates, - strict_undefined=strict_undefined, - preprocessor=preprocessor) - registry_lock.acquire() - try: - registry.registerUtility(lookup, IMakoLookup) - finally: - registry_lock.release() - - return MakoLookupTemplateRenderer(path, lookup) +class MakoRendererFactoryHelper(object): + def __init__(self, settings_prefix=None): + self.settings_prefix = settings_prefix + + def __call__(self, info): + path = info.name + registry = info.registry + settings = info.settings + settings_prefix = self.settings_prefix + + if settings_prefix is None: + settings_prefix = info.type +'.' + + lookup = registry.queryUtility(IMakoLookup, name=settings_prefix) + + def sget(name, default=None): + return settings.get(settings_prefix + name, default) + + if lookup is None: + reload_templates = settings.get('pyramid.reload_templates', None) + if reload_templates is None: + reload_templates = settings.get('reload_templates', False) + reload_templates = asbool(reload_templates) + directories = sget('directories', []) + module_directory = sget('module_directory', None) + input_encoding = sget('input_encoding', 'utf-8') + error_handler = sget('error_handler', None) + default_filters = sget('default_filters', 'h') + imports = sget('imports', None) + strict_undefined = asbool(sget('strict_undefined', False)) + preprocessor = sget('preprocessor', None) + if not is_nonstr_iter(directories): + directories = list(filter(None, directories.splitlines())) + directories = [ abspath_from_asset_spec(d) for d in directories ] + if module_directory is not None: + module_directory = abspath_from_asset_spec(module_directory) + if error_handler is not None: + dotted = DottedNameResolver(info.package) + error_handler = dotted.maybe_resolve(error_handler) + if default_filters is not None: + if not is_nonstr_iter(default_filters): + default_filters = list(filter( + None, default_filters.splitlines())) + if imports is not None: + if not is_nonstr_iter(imports): + imports = list(filter(None, imports.splitlines())) + if preprocessor is not None: + dotted = DottedNameResolver(info.package) + preprocessor = dotted.maybe_resolve(preprocessor) + + + lookup = PkgResourceTemplateLookup( + directories=directories, + module_directory=module_directory, + input_encoding=input_encoding, + error_handler=error_handler, + default_filters=default_filters, + imports=imports, + filesystem_checks=reload_templates, + strict_undefined=strict_undefined, + preprocessor=preprocessor + ) + + registry_lock.acquire() + try: + registry.registerUtility(lookup, IMakoLookup, + name=settings_prefix) + finally: + registry_lock.release() + + return MakoLookupTemplateRenderer(path, lookup) + +renderer_factory = MakoRendererFactoryHelper('mako.') class MakoRenderingException(Exception): def __init__(self, text): diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index 4c444facf..0726c5250 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -21,8 +21,11 @@ class Test_renderer_factory(Base, unittest.TestCase): from pyramid.mako_templating import renderer_factory return renderer_factory(info) - def test_no_directories(self): + def _getLookup(self, name='mako.'): from pyramid.mako_templating import IMakoLookup + return self.config.registry.getUtility(IMakoLookup, name=name) + + def test_no_directories(self): info = DummyRendererInfo({ 'name':'pyramid.tests:fixtures/helloworld.mak', 'package':None, @@ -30,7 +33,7 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':{}, }) renderer = self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, []) self.assertEqual(lookup.filesystem_checks, False) self.assertEqual(renderer.path, @@ -38,7 +41,6 @@ class Test_renderer_factory(Base, unittest.TestCase): self.assertEqual(renderer.lookup, lookup) def test_no_lookup(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir} info = DummyRendererInfo({ 'name':'helloworld.mak', @@ -47,14 +49,13 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) renderer = self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() 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 = '\n' + self.templates_dir + '\n' + self.templates_dir + '\n' settings = {'mako.directories':twice} info = DummyRendererInfo({ @@ -64,13 +65,12 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.directories, [self.templates_dir]*2) def test_directories_list(self): import sys import os.path - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':['a', 'b']} info = DummyRendererInfo({ 'name':'helloworld.mak', @@ -79,7 +79,7 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() module_path = os.path.dirname( sys.modules['__main__'].__file__).rstrip('.') # ./setup.py self.assertEqual(lookup.directories, [ @@ -88,7 +88,6 @@ class Test_renderer_factory(Base, unittest.TestCase): def test_with_module_directory_asset_spec(self): import os - from pyramid.mako_templating import IMakoLookup module_directory = 'pyramid.tests:fixtures' settings = {'mako.directories':self.templates_dir, 'mako.module_directory':module_directory} @@ -99,13 +98,12 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') self.assertEqual(lookup.module_directory, fixtures) def test_with_module_directory_asset_abspath(self): import os - from pyramid.mako_templating import IMakoLookup fixtures = os.path.join(os.path.dirname(__file__), 'fixtures') settings = {'mako.directories':self.templates_dir, 'mako.module_directory':fixtures} @@ -116,11 +114,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.module_directory, fixtures) def test_with_input_encoding(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.input_encoding':'utf-16'} info = DummyRendererInfo({ @@ -130,11 +127,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['input_encoding'], 'utf-16') def test_with_error_handler(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.error_handler':'pyramid.tests'} import pyramid.tests @@ -145,11 +141,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['error_handler'], pyramid.tests) def test_with_preprocessor(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.preprocessor':'pyramid.tests'} import pyramid.tests @@ -160,11 +155,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['preprocessor'], pyramid.tests) def test_with_default_filters(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.default_filters':'\nh\ng\n\n'} info = DummyRendererInfo({ @@ -174,11 +168,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) def test_with_default_filters_list(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.default_filters':['h', 'g']} info = DummyRendererInfo({ @@ -188,11 +181,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['default_filters'], ['h', 'g']) def test_with_imports(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.imports':'\none\ntwo\n\n'} info = DummyRendererInfo({ @@ -202,11 +194,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['imports'], ['one', 'two']) def test_with_imports_list(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.imports':['one', 'two']} info = DummyRendererInfo({ @@ -216,11 +207,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['imports'], ['one', 'two']) def test_with_strict_undefined_true(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.strict_undefined':'true'} info = DummyRendererInfo({ @@ -230,11 +220,10 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['strict_undefined'], True) def test_with_strict_undefined_false(self): - from pyramid.mako_templating import IMakoLookup settings = {'mako.directories':self.templates_dir, 'mako.strict_undefined':'false'} info = DummyRendererInfo({ @@ -244,13 +233,13 @@ class Test_renderer_factory(Base, unittest.TestCase): 'settings':settings, }) self._callFUT(info) - lookup = self.config.registry.getUtility(IMakoLookup) + lookup = self._getLookup() self.assertEqual(lookup.template_args['strict_undefined'], False) def test_with_lookup(self): from pyramid.mako_templating import IMakoLookup lookup = dict() - self.config.registry.registerUtility(lookup, IMakoLookup) + self.config.registry.registerUtility(lookup, IMakoLookup, name='mako.') info = DummyRendererInfo({ 'name':'helloworld.mak', 'package':None, @@ -261,6 +250,53 @@ class Test_renderer_factory(Base, unittest.TestCase): self.assertEqual(renderer.lookup, lookup) self.assertEqual(renderer.path, 'helloworld.mak') +class MakoRendererFactoryHelperTests(Base, unittest.TestCase): + def _getTargetClass(self): + from pyramid.mako_templating import MakoRendererFactoryHelper + return MakoRendererFactoryHelper + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def _getLookup(self, name='mako.'): + from pyramid.mako_templating import IMakoLookup + return self.config.registry.getUtility(IMakoLookup, name=name) + + def test_no_settings_prefix(self): + settings = {'foo.directories':self.templates_dir} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + 'type':'foo', + }) + helper = self._makeOne() + renderer = helper(info) + lookup = self._getLookup('foo.') + 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_custom_settings_prefix(self): + settings = {'bar.directories':self.templates_dir} + info = DummyRendererInfo({ + 'name':'helloworld.mak', + 'package':None, + 'registry':self.config.registry, + 'settings':settings, + 'type':'foo', + }) + helper = self._makeOne('bar.') + renderer = helper(info) + lookup = self._getLookup('bar.') + self.assertEqual(lookup.directories, [self.templates_dir]) + self.assertEqual(lookup.filesystem_checks, False) + self.assertEqual(renderer.path, 'helloworld.mak') + self.assertEqual(renderer.lookup, lookup) + class MakoLookupTemplateRendererTests(Base, unittest.TestCase): def _getTargetClass(self): from pyramid.mako_templating import MakoLookupTemplateRenderer |
