[Checkins] SVN: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/ Refactoring of the registration functions. The only way to call
Martijn Faassen
faassen at startifact.com
Sat Jul 4 12:27:52 EDT 2009
Log message for revision 101547:
Refactoring of the registration functions. The only way to call
register_directory is now using a module_info. Both registering a
directory and registering inline templates check the other registry
to see whether there is no conflict.
Changed:
U grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py
U grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py
U grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt
-=-
Modified: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py
===================================================================
--- grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py 2009-07-04 15:23:37 UTC (rev 101546)
+++ grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py 2009-07-04 16:27:51 UTC (rev 101547)
@@ -162,3 +162,6 @@
def render(view):
"""Renders the template"""
+
+class TemplateLookupError(Exception):
+ pass
Modified: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py
===================================================================
--- grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py 2009-07-04 15:23:37 UTC (rev 101546)
+++ grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py 2009-07-04 16:27:51 UTC (rev 101547)
@@ -4,16 +4,33 @@
import grokcore.component
import grokcore.view
from martian.error import GrokError
-from grokcore.view.interfaces import ITemplateFileFactory
+from grokcore.view.interfaces import ITemplateFileFactory, TemplateLookupError
from grokcore.view.components import PageTemplate
-
+
class InlineTemplateRegistry(object):
def __init__(self):
self._reg = {}
self._unassociated = set()
+
def register_inline_template(self, module_info, template_name, template):
+ # verify no file template got registered with the same name
+ template_dir = file_template_registry.get_template_dir(module_info)
+
+ try:
+ existing_template = file_template_registry.lookup(
+ template_dir, template_name)
+ except TemplateLookupError:
+ pass
+ else:
+ raise GrokError("Conflicting templates found for name '%s': "
+ "the inline template in module '%s' conflicts "
+ "with the file template in directory '%s'" %
+ (template_name, module_info.dotted_name,
+ template_dir), None)
+
+ # register the inline template
self._reg[(module_info.dotted_name, template_name)] = template
self._unassociated.add((module_info.dotted_name, template_name))
@@ -23,7 +40,7 @@
def lookup(self, module_info, template_name):
result = self._reg.get((module_info.dotted_name, template_name))
if result is None:
- raise LookupError("inline template '%s' in '%s' cannot be found" % (
+ raise TemplateLookupError("inline template '%s' in '%s' cannot be found" % (
template_name, module_info.dotted_name))
return result
@@ -35,24 +52,21 @@
self._reg = {}
self._unassociated = set()
- def register_directory_for_module(self, module_info):
+ def register_directory(self, module_info):
# we cannot register a templates dir for a package
if module_info.isPackage():
return
template_dir = self.get_template_dir(module_info)
- self.register_directory(template_dir)
-
- def register_directory(self, template_dir):
# we can only register for directories
if not os.path.isdir(template_dir):
return
-
+
for template_file in os.listdir(template_dir):
- self._register_template_file(
- os.path.join(template_dir, template_file))
-
- def _register_template_file(self, template_path):
+ template_path = os.path.join(template_dir, template_file)
+ self._register_template_file(module_info, template_path)
+
+ def _register_template_file(self, module_info, template_path):
template_dir, template_file = os.path.split(template_path)
if template_file.startswith('.') or template_file.endswith('~'):
@@ -61,22 +75,24 @@
# chameleon creates '<tpl_name>.cache' files on the fly
return
-# inline_template = self.getLocal(template_name)
-# if inline_template:
-# raise GrokError("Conflicting templates found for name '%s' "
-# "in module %r, either inline and in template "
-# "directory '%s', or two templates with the "
-# "same name and different extensions."
-# % (template_name, module_info.getModule(),
-# template_dir), inline_template)
-
template_name, extension = os.path.splitext(template_file)
if (template_dir, template_name) in self._reg:
raise GrokError("Conflicting templates found for name '%s' "
"in directory '%s': multiple templates with "
"the same name and different extensions ." %
(template_name, template_dir), None)
-
+ # verify no inline template exists with the same name
+ try:
+ inline_template_registry.lookup(module_info, template_name)
+ except TemplateLookupError:
+ pass
+ else:
+ raise GrokError("Conflicting templates found for name '%s': "
+ "the inline template in module '%s' conflicts "
+ "with the file template in directory '%s'" %
+ (template_name, module_info.dotted_name,
+ template_dir), None)
+
extension = extension[1:] # Get rid of the leading dot.
template_factory = zope.component.queryUtility(
grokcore.view.interfaces.ITemplateFileFactory,
@@ -103,7 +119,7 @@
def lookup(self, template_dir, template_name):
result = self._reg.get((template_dir, template_name))
if result is None:
- raise LookupError("template '%s' in '%s' cannot be found" % (
+ raise TemplateLookupError("template '%s' in '%s' cannot be found" % (
template_name, template_dir))
return result
@@ -122,30 +138,10 @@
inline_template_registry = InlineTemplateRegistry()
file_template_registry = FileTemplateRegistry()
-def register_inline_template(module_info, template_name, template):
- template_dir = file_template_registry.get_template_dir(module_info)
+register_inline_template = inline_template_registry.register_inline_template
- try:
- existing_template = file_template_registry.lookup(
- template_dir, template_name)
- except LookupError:
- pass # we actually want a LookupError as the template shouldn't exist
- else:
- raise GrokError("Conflicting templates found for name '%s': "
- "the inline template in module '%s' conflicts "
- "with the file template in directory '%s'" %
- (template_name, module_info.dotted_name,
- template_dir), None)
- inline_template_registry.register_inline_template(
- module_info, template_name, template)
+register_directory = file_template_registry.register_directory
-
-def register_directory(template_dir):
- file_template_registry.register_directory(template_dir)
-
-
-
-
all_directory_templates_registries = {}
Modified: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt
===================================================================
--- grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt 2009-07-04 15:23:37 UTC (rev 101546)
+++ grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt 2009-07-04 16:27:51 UTC (rev 101547)
@@ -14,25 +14,20 @@
* an action gets registered that gets executed late in configuration
process that reports on any unassociated templates that are left.
-Setup
------
+Registration functions
+----------------------
-We create our global template registry once::
+In a normal run of the application, the global registration functions
+are used to register templates. These are ``register_inline_template``
+for inline templates in Python code, and ``register_directory`` for
+templates in directories associated with a module::
- >>> from grokcore.view.templatereg import FileTemplateRegistry
- >>> reg = FileTemplateRegistry()
+ >>> from grokcore.view.templatereg import (register_directory,
+ ... register_inline_template)
-For testing purposes we will create a directory with two templates in it::
+Setup
+-----
- >>> import os, tempfile
- >>> template_dir = tempfile.mkdtemp()
- >>> f = open(os.path.join(template_dir, 'foo.template'), 'w')
- >>> f.write('foo')
- >>> f.close()
- >>> f = open(os.path.join(template_dir, 'bar.template'), 'w')
- >>> f.write('bar')
- >>> f.close()
-
Our templates are ``.template``, so we need to register a
``ITemplateFileFactory`` utility for them that knows how to make the
appropriate templates::
@@ -64,22 +59,50 @@
>>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory,
... name='template')
-Registration functions
-----------------------
+We create a way to create a fake module_info for a (actually
+nonexistent) module with a real directory that contains templates::
-Below we are going to manually create and test template registries. In
-a normal run of the application, the global registration functions are
-used to register templates. These are ``register_inline_template`` for
-inline templates in Python code, and ``register_directory`` for
-templates in directories.
+ >>> class ModuleInfo(object):
+ ... def __init__(self, name, dir):
+ ... self.dotted_name = name
+ ... self.name = name
+ ... self.dir = dir
+ ... def getModule(self):
+ ... return None
+ ... def getResourcePath(self, template_dir_name):
+ ... return os.path.join(self.dir, template_dir_name)
+ ... def isPackage(self):
+ ... return False
+ >>> import os, tempfile
+ >>> def create_module_info_with_templates(module_name):
+ ... package_dir = tempfile.mkdtemp()
+ ... templates_dir = os.path.join(package_dir, module_name + '_templates')
+ ... os.mkdir(templates_dir)
+ ... return ModuleInfo(module_name, package_dir), templates_dir
+
Registering a directory
-----------------------
-We can now register the filesystem templates with the registry::
+We create a directory with two templates in it::
- >>> reg.register_directory(template_dir)
+ >>> module_info, template_dir = create_module_info_with_templates('fake')
+ >>> f = open(os.path.join(template_dir, 'foo.template'), 'w')
+ >>> f.write('foo')
+ >>> f.close()
+ >>> f = open(os.path.join(template_dir, 'bar.template'), 'w')
+ >>> f.write('bar')
+ >>> f.close()
+We can now register the filesystem templates associated with our
+module_info with the registry::
+
+ >>> register_directory(module_info)
+
+We'll also import the global template registry to do some checks::
+
+ >>> from grokcore.view.templatereg import file_template_registry as reg
+
We can look up the templates in the registry now::
>>> reg.lookup(template_dir, 'foo')
@@ -88,19 +111,19 @@
<Template 'bar.template' in '...'>
If we try to look up a template in a directory that doesn't exist, we get
-a LookupError::
+a TemplateLookupError::
>>> reg.lookup('certainlydoesntexist', 'foo')
Traceback (most recent call last):
...
- LookupError: template 'foo' in 'certainlydoesntexist' cannot be found
+ TemplateLookupError: template 'foo' in 'certainlydoesntexist' cannot be found
We get this error for templates that do not exist as well::
>>> reg.lookup(template_dir, 'doesntexist')
Traceback (most recent call last):
...
- LookupError: template 'doesntexist' in ... cannot be found
+ TemplateLookupError: template 'doesntexist' in ... cannot be found
Since no templates have yet been associated, retrieving the unassociated
templates will get us all registered templates::
@@ -124,7 +147,7 @@
the system::
>>> import os, tempfile
- >>> template_dir2 = tempfile.mkdtemp()
+ >>> module_info2, template_dir2 = create_module_info_with_templates('module2')
>>> f = open(os.path.join(template_dir2, 'foo.unknown'), 'w')
>>> f.write('unknown')
>>> f.close()
@@ -139,7 +162,7 @@
We register the directory now, and we get the warning::
- >>> reg.register_directory(template_dir2)
+ >>> reg.register_directory(module_info2)
From grok.testing's warn():
... UserWarning: File 'foo.unknown' has an unrecognized extension in directory '...'
...
@@ -153,7 +176,7 @@
>>> reg.lookup(template_dir2, 'foo.unknown')
Traceback (most recent call last):
...
- LookupError: template 'foo.unknown' in '...' cannot be found
+ TemplateLookupError: template 'foo.unknown' in '...' cannot be found
Multiple templates with the same name
-------------------------------------
@@ -169,8 +192,7 @@
templates have the same name but use different template languages, and
Grok won't know which one it should use::
- >>> import os, tempfile
- >>> template_dir3 = tempfile.mkdtemp()
+ >>> module_info3, template_dir3 = create_module_info_with_templates('module3')
>>> f = open(os.path.join(template_dir3, 'foo.1'), 'w')
>>> f.write('1')
>>> f.close()
@@ -180,7 +202,7 @@
We expect an error when we register this directory::
- >>> reg.register_directory(template_dir3)
+ >>> register_directory(module_info3)
Traceback (most recent call last):
...
GrokError: Conflicting templates found for name 'foo' in directory '...':
@@ -192,24 +214,6 @@
Inline templates are defined in a Python module instead of on the
filesystem.
-First we create a fake ModuleInfo class:
-
- >>> class ModuleInfo(object):
- ... dotted_name = 'module'
- ... name = 'module'
- ... def __init__(self, dotted_name, name, dir):
- ... self.dotted_name = dotted_name
- ... self.name = name
- ... self.dir = dir
- ... def getModule(self):
- ... return None
- ... def getResourcePath(self, template_dir_name):
- ... return os.path.join(self.dir, template_dir_name)
-
-an create an instance of this class::
-
- >>> module_info = ModuleInfo('module', 'module', None)
-
Let's create a class for inline template and create an instance::
>>> class InlineTemplate(object):
@@ -219,73 +223,87 @@
... return "<InlineTemplate '%s'>" % self.name
>>> cavepainting = InlineTemplate('cavepainting')
-We create our global inline template registry once::
+Let's register an inline template with the registry::
- >>> from grokcore.view.templatereg import InlineTemplateRegistry
- >>> inline_reg = InlineTemplateRegistry()
+ >>> module_info4, template_dir4 = create_module_info_with_templates('module4')
+ >>> register_inline_template(module_info4, 'cavepainting', cavepainting)
-Let's register an inline template with the registry::
+ >>> from grokcore.view.templatereg import inline_template_registry as inline_reg
- >>> inline_reg.register_inline_template(module_info, 'cavepainting', cavepainting)
-
We can look it up now::
- >>> inline_reg.lookup(module_info, 'cavepainting')
+ >>> inline_reg.lookup(module_info4, 'cavepainting')
<InlineTemplate 'cavepainting'>
If we cannot find the template we get an error::
- >>> inline_reg.lookup(module_info, 'unknown')
+ >>> inline_reg.lookup(module_info4, 'unknown')
Traceback (most recent call last):
...
- LookupError: inline template 'unknown' in 'module' cannot be found
+ TemplateLookupError: inline template 'unknown' in 'module4' cannot be found
Since no templates have yet been associated, retrieving the
unassociated templates will get us all registered inline templates::
>>> sorted(inline_reg.unassociated())
- [('module', 'cavepainting')]
+ [('module4', 'cavepainting')]
Conflicts between inline templates and file templates
-----------------------------------------------------
-
We construct a fake templates directory that's associated with the fictional
``module`` module::
>>> import os, tempfile
- >>> package_dir = tempfile.mkdtemp()
- >>> module_template_dir = os.path.join(package_dir, 'module_templates')
- >>> os.mkdir(module_template_dir)
-And we create the module info for this::
+ >>> module_info5, template_dir5 = create_module_info_with_templates('module5')
- >>> module_info = ModuleInfo('module', 'module', package_dir)
-
We create a template with the name ``foo`` in it::
- >>> f = open(os.path.join(module_template_dir, 'foo.template'), 'w')
+ >>> f = open(os.path.join(template_dir5, 'foo.template'), 'w')
>>> f.write('foo')
>>> f.close()
We register this directory, using the global registration functionality::
- >>> from grokcore.view.templatereg import register_directory
- >>> register_directory(module_template_dir)
+ >>> register_directory(module_info5)
We now also try to register an inline template with the same name
(``foo``), but this fails due to a conflict with the file template::
- >>> from grokcore.view.templatereg import register_inline_template
- >>> register_inline_template(module_info, 'foo', InlineTemplate('foo'))
+ >>> register_inline_template(module_info5, 'foo', InlineTemplate('foo'))
Traceback (most recent call last):
...
GrokError: Conflicting templates found for name 'foo': the inline template
- in module 'module' conflicts with the file template in directory
- '...module_templates'
+ in module 'module5' conflicts with the file template in directory
+ '...module5_templates'
+Let's now demonstrate the same conflict, the other way around.
+First we set up a fictional filesystem structure surrounding a
+``module6``::
+ >>> module_info6, template_dir6 = create_module_info_with_templates('module6')
+
+We add a template to it::
+ >>> f = open(os.path.join(template_dir6, 'bar.template'), 'w')
+ >>> f.write('bar')
+ >>> f.close()
+
+Now we first register an inline template ``bar`` before loading up that
+directory::
+ >>> register_inline_template(module_info6, 'bar', InlineTemplate('bar'))
+
+When we now try to register the template ``bar`` in a directory, we'll
+get an error::
+
+ >>> register_directory(module_info6)
+ Traceback (most recent call last):
+ ...
+ GrokError: Conflicting templates found for name 'bar':
+ the inline template in module 'module6' conflicts with the file template in directory '...'
+
+
XXX a common lookup function that looks up both inline or filesystem?
More information about the Checkins
mailing list