[Checkins] SVN: grokcore.chameleon/trunk/src/grokcore/chameleon/ ressurect the PageTemplateFile behaviour where a relative path could be given as the first argument. This behaviour got lost when the z3.pt base class for page template files was no longer used.
Jan Wijbrand Kolman
cvs-admin at zope.org
Mon May 7 14:57:21 UTC 2012
Log message for revision 125684:
ressurect the PageTemplateFile behaviour where a relative path could be given as the first argument. This behaviour got lost when the z3.pt base class for page template files was no longer used.
Changed:
U grokcore.chameleon/trunk/src/grokcore/chameleon/components.py
A grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templatefile.py
A grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templates/
A grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templates/foo.cpt
U grokcore.chameleon/trunk/src/grokcore/chameleon/tests/test_megrok_chameleon.py
-=-
Modified: grokcore.chameleon/trunk/src/grokcore/chameleon/components.py
===================================================================
--- grokcore.chameleon/trunk/src/grokcore/chameleon/components.py 2012-05-07 14:41:58 UTC (rev 125683)
+++ grokcore.chameleon/trunk/src/grokcore/chameleon/components.py 2012-05-07 14:57:17 UTC (rev 125684)
@@ -31,20 +31,12 @@
from z3c.pt.expressions import PathExpr, ProviderExpr
-#
-# Chameleon Zope Page Templates...
-#
class PageTemplate(PageTemplate, GrokTemplate):
- """A `z3c.pt` page template suitable for use with views.
+ """A Chameleon page template suitable for use with views.
- This page template implementation is different from `z3c.pt`
- implementation in two respects:
-
- - It sets ``python`` as default mode (instead of ``path``)
- - It injects any views ``static`` variable in template namespace.
+ It defines the path and provider expression types to the template in
+ addition to the "standard" expressions types.
"""
- default_expression = 'python' # Use the chameleon default
-
expression_types = {
'python': PythonExpr,
'string': StringExpr,
@@ -56,21 +48,47 @@
'structure': StructureExpr,
}
+def _module_relative_to_abs(ctx, filename):
+ # Taken and adapted from z3c.pth.pagetemplate.
+ if os.path.isabs(filename):
+ return filename
+ for depth in (2, 3):
+ frame = sys._getframe(depth)
+ package_name = frame.f_globals.get('__name__', None)
+ if package_name is not None and \
+ package_name != ctx:
+ module = sys.modules[package_name]
+ try:
+ path = module.__path__[0]
+ except AttributeError:
+ path = module.__file__
+ path = path[:path.rfind(os.sep)]
+ break
+ else:
+ package_path = frame.f_globals.get('__file__', None)
+ if package_path is not None:
+ path = os.path.dirname(package_path)
+ break
+ return os.path.join(path, filename)
+
class PageTemplateFile(PageTemplate, PageTemplateFile):
- """A `z3c.pt` page template file suitable for use with views.
+ """A Chameleon page template file suitable for use with views.
- This implementation is different from `z3c.pt` implementation in
- two respects:
-
- - It sets ``python`` as default mode (instead of ``path``)
- - It injects any views ``static`` variable in template namespace.
+ Takes an absolute path to the template file as the first argument.
"""
- default_expression = 'python'
+ def __init__(self, filename):
+ filename = _module_relative_to_abs(self, filename)
+ super(PageTemplateFile, self).__init__(filename)
class ChameleonPageTemplate(GrokTemplate):
+ """Encapsulates a Chameleon-based template as a GrokTemplate
+ implementation.
+ Used for Grok View components by way of the grok.template() directive.
+ """
+
def setFromString(self, string):
self._filename = None
self._template = PageTemplate(string)
@@ -87,18 +105,25 @@
def render(self, view):
context = self.getNamespace(view)
-
if 'target_language' not in context:
try:
target_language = zope.i18n.negotiate(context['request'])
except:
target_language = None
context['target_language'] = target_language
-
return self._template(**context)
+
class ChameleonPageTemplateFile(ChameleonPageTemplate):
+ """Encapsulates a Chameleon-based template file as a GrokTemplate
+ implementation.
+ Used for Grok View components by way of the grok.template() directive.
+
+ The filename will be relative to the module in which the Grok View
+ component is defined.
+ """
+
def __init__(self, filename, _prefix=None):
self.__grok_module__ = martian.util.caller_module()
if _prefix is None:
Added: grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templatefile.py
===================================================================
--- grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templatefile.py (rev 0)
+++ grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templatefile.py 2012-05-07 14:57:17 UTC (rev 125684)
@@ -0,0 +1,56 @@
+"""
+ >>> from zope.publisher.browser import TestRequest
+ >>> context = FooContext()
+ >>> request = TestRequest()
+ >>> view = WithFooTemplate(context, request)
+ >>> print view()
+ Foo Template.
+
+ >>> view = WithFooTemplateNoExists(context, request)
+ >>> view()
+ Traceback (most recent call last):
+ ...
+ IOError: [Errno 2] No such file or directory: '...templates/nothere.cpt'
+
+ >>> view = NonGrokViewWithTemplate(context, request)
+ >>> print view()
+ Foo Template.
+
+ >>> view = NonGrokViewWithTemplateNoExists(context, request)
+ >>> view()
+ Traceback (most recent call last):
+ ...
+ IOError: [Errno 2] No such file or directory: '...templates/nothere.cpt'
+
+"""
+import zope.interface
+import grokcore.component.interfaces
+import grokcore.component
+import grokcore.view
+
+from grokcore.chameleon.components import ChameleonPageTemplateFile
+from grokcore.chameleon.components import PageTemplateFile
+
+class FooContext(object):
+ zope.interface.implements(grokcore.component.interfaces.IContext)
+
+class WithFooTemplate(grokcore.view.View):
+ grokcore.component.context(zope.interface.Interface)
+
+ template = ChameleonPageTemplateFile('templates/foo.cpt')
+
+class WithFooTemplateNoExists(WithFooTemplate):
+ template = ChameleonPageTemplateFile('templates/nothere.cpt')
+
+class NonGrokViewWithTemplate(object):
+ template = PageTemplateFile('templates/foo.cpt')
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def __call__(self):
+ return self.template()
+
+class NonGrokViewWithTemplateNoExists(NonGrokViewWithTemplate):
+ template = PageTemplateFile('templates/nothere.cpt')
Added: grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templates/foo.cpt
===================================================================
--- grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templates/foo.cpt (rev 0)
+++ grokcore.chameleon/trunk/src/grokcore/chameleon/tests/templates/foo.cpt 2012-05-07 14:57:17 UTC (rev 125684)
@@ -0,0 +1 @@
+Foo Template.
Modified: grokcore.chameleon/trunk/src/grokcore/chameleon/tests/test_megrok_chameleon.py
===================================================================
--- grokcore.chameleon/trunk/src/grokcore/chameleon/tests/test_megrok_chameleon.py 2012-05-07 14:41:58 UTC (rev 125683)
+++ grokcore.chameleon/trunk/src/grokcore/chameleon/tests/test_megrok_chameleon.py 2012-05-07 14:57:17 UTC (rev 125684)
@@ -43,7 +43,7 @@
"""Get a testsuite of all doctests.
"""
suite = unittest.TestSuite()
- test = doctest.DocFileSuite(
+ readme = doctest.DocFileSuite(
'README.txt',
setUp=setUpStatic,
package=grokcore.chameleon,
@@ -52,6 +52,13 @@
),
optionflags=FLAGS,
)
- test.layer = FunctionalLayer
- suite.addTest(test)
+ readme.layer = FunctionalLayer
+ suite.addTest(readme)
+ suite.addTest(
+ doctest.DocTestSuite(
+ 'grokcore.chameleon.tests.templatefile',
+ setUp=setUpStatic,
+ optionflags=FLAGS,
+ )
+ )
return suite
More information about the checkins
mailing list