summaryrefslogtreecommitdiff
path: root/repoze
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2008-07-14 08:54:26 +0000
committerChris McDonough <chrism@agendaless.com>2008-07-14 08:54:26 +0000
commitc0c663bd97e4c7fe1d9971fc8070791a148f106f (patch)
tree2ea114deb5b2cc32d9b535666707b4957f2dbef8 /repoze
parent85427fa0479aefd59bd55dca397b9a36277edade (diff)
downloadpyramid-c0c663bd97e4c7fe1d9971fc8070791a148f106f.tar.gz
pyramid-c0c663bd97e4c7fe1d9971fc8070791a148f106f.tar.bz2
pyramid-c0c663bd97e4c7fe1d9971fc8070791a148f106f.zip
And, just to maximally confuse Paul, come full circle, and don't require that the template be spelled on the class, while still allowing us to pickle the registry actions.
Diffstat (limited to 'repoze')
-rw-r--r--repoze/bfg/sampleapp/configure.zcml2
-rw-r--r--repoze/bfg/sampleapp/views.py4
-rw-r--r--repoze/bfg/tests/fixtureapp/configure.zcml1
-rw-r--r--repoze/bfg/tests/fixtureapp/views.py4
-rw-r--r--repoze/bfg/tests/test_zcml.py84
-rw-r--r--repoze/bfg/zcml.py28
6 files changed, 103 insertions, 20 deletions
diff --git a/repoze/bfg/sampleapp/configure.zcml b/repoze/bfg/sampleapp/configure.zcml
index d5cba4d33..5e7a83ffd 100644
--- a/repoze/bfg/sampleapp/configure.zcml
+++ b/repoze/bfg/sampleapp/configure.zcml
@@ -8,6 +8,7 @@
<bfg:view
for=".models.IBlog"
factory=".views.BlogDefaultView"
+ template="templates/blog.pt"
permission="repoze.view"
/>
@@ -15,6 +16,7 @@
<bfg:view
for=".models.IBlogEntry"
factory=".views.BlogEntryDefaultView"
+ template="templates/blog_entry.pt"
permission="repoze.view"
/>
diff --git a/repoze/bfg/sampleapp/views.py b/repoze/bfg/sampleapp/views.py
index 98b285b67..196fce703 100644
--- a/repoze/bfg/sampleapp/views.py
+++ b/repoze/bfg/sampleapp/views.py
@@ -12,8 +12,6 @@ def datestring(dt):
class BlogDefaultView(TemplateView):
- template = 'templates/blog.pt'
-
def getInfo(self):
entrydata = []
for name, entry in self.context.items():
@@ -29,8 +27,6 @@ class BlogDefaultView(TemplateView):
class BlogEntryDefaultView(TemplateView):
- template = 'templates/blog_entry.pt'
-
def getInfo(self):
return {
'name':self.context.__name__,
diff --git a/repoze/bfg/tests/fixtureapp/configure.zcml b/repoze/bfg/tests/fixtureapp/configure.zcml
index f08cd58ad..99d0708aa 100644
--- a/repoze/bfg/tests/fixtureapp/configure.zcml
+++ b/repoze/bfg/tests/fixtureapp/configure.zcml
@@ -12,6 +12,7 @@
<bfg:view
for=".models.IFixture"
+ factory=".views.FixtureTemplateView"
template="templates/fixture.pt"
permission="repoze.view"
name="fixture.html"
diff --git a/repoze/bfg/tests/fixtureapp/views.py b/repoze/bfg/tests/fixtureapp/views.py
index b9b9fc7d9..36fe07cc6 100644
--- a/repoze/bfg/tests/fixtureapp/views.py
+++ b/repoze/bfg/tests/fixtureapp/views.py
@@ -1,3 +1,5 @@
+from repoze.bfg.view import TemplateView
+
class FixtureView(object):
def __init__(self, context, request):
self.context = context
@@ -6,3 +8,5 @@ class FixtureView(object):
def __call__(self):
pass
+class FixtureTemplateView(TemplateView):
+ pass
diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py
index 11f392f78..7aaf6e4c3 100644
--- a/repoze/bfg/tests/test_zcml.py
+++ b/repoze/bfg/tests/test_zcml.py
@@ -100,34 +100,104 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup):
self.assertEqual(regadapt['args'][4], '')
self.assertEqual(regadapt['args'][5], None)
- def test_template_and_factory_raises(self):
+ def test_template_and_factory(self):
f = self._getFUT()
context = DummyContext()
- from zope.configuration.exceptions import ConfigurationError
- self.assertRaises(ConfigurationError, f, context, 'repoze.view', None,
- Dummy, 'minimal.html', 'minimal.pt')
+ class IFoo:
+ pass
+ class DummyView:
+ pass
+ f(context, 'repoze.view', IFoo, factory=DummyView,
+ template='minimal.pt')
+ actions = context.actions
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IRequest
+ from repoze.bfg.interfaces import IViewFactory
+ from zope.component.zcml import handler
+ from zope.component.interface import provideInterface
+
+ self.assertEqual(len(actions), 3)
+
+ regutil_discriminator = ('utility', IView, context.path('minimal.pt'))
+ regutil = actions[0]
+ self.assertEqual(regutil['discriminator'], regutil_discriminator)
+ self.assertEqual(regutil['callable'], handler)
+ self.assertEqual(regutil['args'][0], 'registerUtility')
+ self.assertEqual(regutil['args'][1].template.filename,
+ context.path('minimal.pt'))
+ self.assertEqual(regutil['args'][2], IView)
+ self.assertEqual(regutil['args'][3], context.path('minimal.pt'))
+
+ provide = actions[1]
+ self.assertEqual(provide['discriminator'], None)
+ self.assertEqual(provide['callable'], provideInterface)
+ self.assertEqual(provide['args'][0], '')
+ self.assertEqual(provide['args'][1], IFoo)
+
+ regadapt = actions[2]
+ regadapt_discriminator = ('view', IFoo, '', IRequest, IViewFactory)
+ self.assertEqual(regadapt['discriminator'], regadapt_discriminator)
+ self.assertEqual(regadapt['callable'], handler)
+ self.assertEqual(regadapt['args'][0], 'registerAdapter')
+ self.assertEqual(regadapt['args'][1].template,
+ context.path('minimal.pt'))
+ self.assertEqual(regadapt['args'][2], (IFoo, IRequest))
+ self.assertEqual(regadapt['args'][3], IViewFactory)
+ self.assertEqual(regadapt['args'][4], '')
+ self.assertEqual(regadapt['args'][5], None)
class TestTemplateViewFactory(unittest.TestCase):
def _getTargetClass(self):
from repoze.bfg.zcml import TemplateViewFactory
return TemplateViewFactory
- def _makeOne(self, template):
- return self._getTargetClass()(template)
+ def _makeOne(self, template, base=None):
+ return self._getTargetClass()(template, base)
def test_instance_conforms_to_IViewFactory(self):
from zope.interface.verify import verifyObject
from repoze.bfg.interfaces import IViewFactory
verifyObject(IViewFactory, self._makeOne('a'))
- def test_call(self):
+ def test_call_templateonly(self):
context = DummyContext()
template = context.path('minimal.pt')
factory = self._makeOne(template)
view = factory(None, None)
from repoze.bfg.view import TemplateView
self.failUnless(isinstance(view, TemplateView))
+ self.assertEqual(view.template, template)
+ def test_call_nonclassbase(self):
+ context = DummyContext()
+ def factory():
+ pass
+ template = context.path('minimal.pt')
+ self.assertRaises(ValueError, self._makeOne, template, factory)
+
+ def test_call_classbase_not_templateview_subclass(self):
+ context = DummyContext()
+ template = context.path('minimal.pt')
+ factory = self._makeOne(template, Dummy)
+ view = factory(None, None)
+ from repoze.bfg.view import TemplateView
+ self.assertEqual(view.__bases__[0], Dummy)
+ self.assertEqual(view.__bases__[1], TemplateView)
+ self.assertEqual(view.__name__, 'DynamicTemplateView_For_Dummy')
+ self.assertEqual(view.template, template)
+
+ def test_call_classbase_templateview_subclass(self):
+ context = DummyContext()
+ template = context.path('minimal.pt')
+ from repoze.bfg.view import TemplateView
+ class TemplateViewSubclass(TemplateView):
+ pass
+ factory = self._makeOne(template, TemplateViewSubclass)
+ view = factory(None, None)
+ self.assertEqual(view.__bases__[0], TemplateViewSubclass)
+ self.assertEqual(view.__name__,
+ 'DynamicTemplateView_For_TemplateViewSubclass')
+ self.assertEqual(view.template, template)
class Dummy:
pass
diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py
index a1a2497b5..dc05cca18 100644
--- a/repoze/bfg/zcml.py
+++ b/repoze/bfg/zcml.py
@@ -1,4 +1,6 @@
+import inspect
import os
+import new
from zope.component.zcml import handler
from zope.component.interface import provideInterface
@@ -24,11 +26,24 @@ class TemplateViewFactory(object):
implements(IViewFactory)
- def __init__(self, template):
+ def __init__(self, template, base=None):
+ if base is not None:
+ if not inspect.isclass(base):
+ raise ValueError('Factory must be a class to be used '
+ 'with a template, but %s was supplied' % base)
self.template = template
+ self.base = base
def __call__(self, context, request):
- factory = TemplateView(context, request)
+ if self.base and self.base is not TemplateView:
+ if issubclass(self.base, TemplateView):
+ bases = (self.base,)
+ else:
+ bases = (self.base, TemplateView)
+ name = 'DynamicTemplateView_For_%s' % self.base.__name__
+ factory = new.classobj(name, bases, {})
+ else:
+ factory = TemplateView(context, request)
factory.template = self.template
return factory
@@ -42,14 +57,9 @@ def view(_context,
# XXX we do nothing yet with permission
- if template and factory:
- raise ConfigurationError('A template must not be specified if a '
- 'factory is also specified')
-
if not (template or factory):
raise ConfigurationError(
- 'One of template or factory must be specified')
-
+ 'One of template or factory (or both) must be specified')
if template:
template_abs = os.path.abspath(str(_context.path(template)))
@@ -61,7 +71,7 @@ def view(_context,
callable = handler,
args = ('registerUtility', utility, IView, template_abs),
)
- factory = TemplateViewFactory(template_abs)
+ factory = TemplateViewFactory(template_abs, factory)
if for_ is not None:
_context.action(