diff options
| -rw-r--r-- | README.txt | 29 | ||||
| -rw-r--r-- | repoze/bfg/__init__.py | 2 | ||||
| -rw-r--r-- | repoze/bfg/sampleapp/configure.zcml | 18 | ||||
| -rw-r--r-- | repoze/bfg/sampleapp/templates/blog.pt | 6 | ||||
| -rw-r--r-- | repoze/bfg/sampleapp/templates/blog_entry.pt | 6 | ||||
| -rw-r--r-- | repoze/bfg/sampleapp/templates/blog_entry_add.pt | 15 | ||||
| -rw-r--r-- | repoze/bfg/sampleapp/views.py | 97 | ||||
| -rw-r--r-- | repoze/bfg/template.py | 36 | ||||
| -rw-r--r-- | repoze/bfg/tests/fixtureapp/configure.zcml | 1 | ||||
| -rw-r--r-- | repoze/bfg/tests/fixtureapp/views.py | 4 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_template.py | 6 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_view.py | 30 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_zcml.py | 129 | ||||
| -rw-r--r-- | repoze/bfg/view.py | 22 | ||||
| -rw-r--r-- | repoze/bfg/zcml.py | 65 |
15 files changed, 210 insertions, 256 deletions
diff --git a/README.txt b/README.txt index 104f321cb..e3f1f6ea5 100644 --- a/README.txt +++ b/README.txt @@ -268,23 +268,14 @@ A views.py module might look like so:: from webob import Response from repoze.bfg.view import TemplateView - class MyHelloView(object): - def __init__(self, context, request): - self.context = context - self.request = request + def my_hello_view(context, request): + response = Response('Hello from %s @ %s' % ( + context.__name__, + request.environ['PATH_INFO'])) + return response - def __call__(self): - response = Response('Hello from %s @ %s' % ( - self.context.__name__, - self.request.environ['PATH_INFO'])) - return response - - class MyTemplateView(TemplateView): - - template = 'templates/my.pt' - - def getInfo(self): - return {'name':self.context.__name__} + def my_template_view(context, request): + return render_template('templates/my.pt', name=context.__name__) models.py ~~~~~~~~~ @@ -335,7 +326,7 @@ A view registry might look like so:: permission="repoze.view" /> - <!-- the templated view for a MyModel --> + <!-- the templated.html view for a MyModel --> <bfg:view for=".models.IMyModel" factory=".views.MyTemplateView" @@ -353,8 +344,8 @@ A template that is used by a view might look like so:: <html xmlns="http://www.w3.org/1999/xhtml" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head></head> - <body tal:define="info view.getInfo()"> - <h1>My template viewing ${info.name}</h1> + <body> + <h1>My template viewing ${name}</h1> </body> </html> diff --git a/repoze/bfg/__init__.py b/repoze/bfg/__init__.py index 76bdd005d..7add3dca8 100644 --- a/repoze/bfg/__init__.py +++ b/repoze/bfg/__init__.py @@ -1,2 +1,2 @@ from repoze.bfg.router import make_app # for import elsewhere -from repoze.bfg.view import View +from repoze.bfg.template import render_template diff --git a/repoze/bfg/sampleapp/configure.zcml b/repoze/bfg/sampleapp/configure.zcml index 5e7a83ffd..e026a12f2 100644 --- a/repoze/bfg/sampleapp/configure.zcml +++ b/repoze/bfg/sampleapp/configure.zcml @@ -7,39 +7,29 @@ <!-- the default view for a Blog --> <bfg:view for=".models.IBlog" - factory=".views.BlogDefaultView" - template="templates/blog.pt" + factory=".views.blog_default_view" permission="repoze.view" /> <!-- the default view for a BlogEntry --> <bfg:view for=".models.IBlogEntry" - factory=".views.BlogEntryDefaultView" - template="templates/blog_entry.pt" + factory=".views.blog_entry_default_view" permission="repoze.view" /> <!-- the add template for a BlogEntry --> <bfg:view for=".models.IBlog" - template="templates/blog_entry_add.pt" + factory=".views.blog_entry_add_view" name="add_entry.html" permission="repoze.view" /> - <!-- the add handler for a BlogEntry --> - <bfg:view - for=".models.IBlog" - factory=".views.BlogEntryAddView" - permission="repoze.view" - name="add_entry_handler" - /> - <!-- the contents view for any mapping (shows dict members) --> <bfg:view for=".models.IMapping" - template="templates/contents.pt" + factory=".views.contents_view" name="contents.html" permission="repoze.view" /> diff --git a/repoze/bfg/sampleapp/templates/blog.pt b/repoze/bfg/sampleapp/templates/blog.pt index 8ccbe56a2..8eb3945db 100644 --- a/repoze/bfg/sampleapp/templates/blog.pt +++ b/repoze/bfg/sampleapp/templates/blog.pt @@ -1,15 +1,15 @@ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:tal="http://xml.zope.org/namespaces/tal"> <head></head> -<body tal:define="info view.getInfo()"> - <h1 tal:content="info.name">Blog Name</h1> +<body> + <h1 tal:content="name">Blog Name</h1> <table border="0"> <thead> <th>Title</th> <th>Author</th> <th>Created</th> </thead> - <tr tal:repeat="entry info.entries"> + <tr tal:repeat="entry entries"> <td><a href="${entry.name}/">${entry.title}</a></td> <td>${entry.author}</td> <td>${entry.created}</td> diff --git a/repoze/bfg/sampleapp/templates/blog_entry.pt b/repoze/bfg/sampleapp/templates/blog_entry.pt index 20e1b4409..830876525 100644 --- a/repoze/bfg/sampleapp/templates/blog_entry.pt +++ b/repoze/bfg/sampleapp/templates/blog_entry.pt @@ -2,10 +2,10 @@ xmlns:tal="http://xml.zope.org/namespaces/tal"> <head></head> <body> - <div tal:define="info view.getInfo()"> + <div> <p><a href="..">Up</a></p> - <h1>${info.title}</h1> - <p>by ${info.author}</p> + <h1>${title}</h1> + <p>by ${author}</p> <div tal:content="structure info.body"></div> </div> </body> diff --git a/repoze/bfg/sampleapp/templates/blog_entry_add.pt b/repoze/bfg/sampleapp/templates/blog_entry_add.pt index b41ae4b02..101163b44 100644 --- a/repoze/bfg/sampleapp/templates/blog_entry_add.pt +++ b/repoze/bfg/sampleapp/templates/blog_entry_add.pt @@ -1,24 +1,27 @@ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:tal="http://xml.zope.org/namespaces/tal"> -<head></head> +<head> +</head> <body> - <form action="add_entry_handler" method="POST"> + <form action="${request.path_url}" method="POST"> + <h2 tal:condition="message" tal:content="message"></h2> <h1>Add a blog entry</h1> <table border="0"> <tr> <th>Title</th> - <td><input type="text" name="title"/></td> + <td><input type="text" name="title"/>${title}</td> </tr> <tr> <th>Author</th> - <td><input type="text" name="author"/></td> + <td><input type="text" name="author"/>${author}</td> </tr> <tr> <th>Body</th> - <td><textarea name="body" rows="10" value=""> </textarea></td> + <td><textarea name="body" rows="10" cols="80"> ${body}</textarea + ></td> </tr> <tr> - <td><input type="submit" name="add" value="Add"/></td> + <td><input type="submit" name="form.submitted" value="Add"/></td> </tr> </table> </form> diff --git a/repoze/bfg/sampleapp/views.py b/repoze/bfg/sampleapp/views.py index 196fce703..8e2ddd467 100644 --- a/repoze/bfg/sampleapp/views.py +++ b/repoze/bfg/sampleapp/views.py @@ -1,49 +1,74 @@ +import formencode import time from webob.exc import HTTPFound -from repoze.bfg.view import TemplateView -from repoze.bfg.view import View - +from repoze.bfg.template import render_template from repoze.bfg.sampleapp.models import BlogEntry def datestring(dt): return dt.strftime('%Y-%m-%d %H:%M:%S') -class BlogDefaultView(TemplateView): - - def getInfo(self): - entrydata = [] - for name, entry in self.context.items(): - entrydata.append( - { - 'name':name, - 'title':entry.title, - 'author':entry.author, - 'created':datestring(entry.created), - } - ) - return {'name':self.context.__name__, 'entries':entrydata} - -class BlogEntryDefaultView(TemplateView): - - def getInfo(self): - return { - 'name':self.context.__name__, - 'title':self.context.title, - 'body':self.context.body, - 'author':self.context.author, - 'created':datestring(self.context.created), +def blog_default_view(context, request): + entrydata = [] + for name, entry in self.context.items(): + entrydata.append( + { + 'name':name, + 'title':entry.title, + 'author':entry.author, + 'created':datestring(entry.created), + 'message':self.request.params.get('message'), } + ) + + info = {'name':self.context.__name__, entries:entrydata} + return render_template('templates/blog.pt', info) + +def blog_entry_default_view(context, request): + info = { + 'name':self.context.__name__, + 'title':self.context.title, + 'body':self.context.body, + 'author':self.context.author, + 'created':datestring(self.context.created), + } + return render_template('templates/blog_entry.pt', **info) + +class BlogAddSchema(formencode.Schema): + allow_extra_fields = True + author = formencode.validators.NotEmpty() + body = formencode.validators.NotEmpty() + title = formencode.validators.NotEmpty() + +def blog_entry_add_view(context, request): + params = self.request.params + + message = None -class BlogEntryAddView(View): + author = params.get('author', '') + body = params.get('body', '') + title = params.get('title', '') + info = dict(request=self.request, + author=author, body=body, title=title, message=None) - def __call__(self): - author = self.request.params['author'] - body = self.request.params['body'] - title = self.request.params['title'] - name = str(time.time()) - new_entry = BlogEntry(name, title, body, author) - self.context[name] = new_entry - return HTTPFound(location='/') + if params.has_key('form.submitted'): + schema = BlogAddSchema() + try: + form = schema.to_python(params) + except formencode.validators.Invalid, why: + message = str(why) + info['message'] = message + else: + author = form['author'] + body = form['body'] + title = form['title'] + name = str(time.time()) + new_entry = BlogEntry(name, title, body, author) + self.context[name] = new_entry + return HTTPFound(location='/') + else: + return render_template('templates/blog_entry_add.pt', **info) +def contents_view(context, request): + return render_template('templates/contents.pt', context=context) diff --git a/repoze/bfg/template.py b/repoze/bfg/template.py index c3e34c99a..4cd78f4f4 100644 --- a/repoze/bfg/template.py +++ b/repoze/bfg/template.py @@ -29,28 +29,32 @@ class Z3CPTTemplateFactory(object): def package_path(package): return os.path.abspath(os.path.dirname(package.__file__)) -def render_template(view, template_path, **kw): +def registerTemplate(template, path): + try: + sm = getSiteManager() + except ComponentLookupError: + pass + else: + sm.registerUtility(template, IView, name=path) + +def render_template_explicit(path, **kw): # XXX use pkg_resources - if not os.path.isabs(template_path): + if not os.path.isabs(path): package_globals = sys._getframe(1).f_globals package_name = package_globals['__name__'] package = sys.modules[package_name] prefix = package_path(package) - template_path = os.path.join(prefix, template_path) + path = os.path.join(prefix, path) - template = queryUtility(IView, template_path) + template = queryUtility(IView, path) if template is None: - if not os.path.exists(template_path): - raise ValueError('Missing template file: %s' % template_path) - template = Z3CPTTemplateFactory(template_path) - try: - sm = getSiteManager() - except ComponentLookupError: - pass - else: - sm.registerUtility(template, IView, name=template_path) - - return template(view=view, context=view.context, request=view.request, - options=kw) + if not os.path.exists(path): + raise ValueError('Missing template file: %s' % path) + template = Z3CPTTemplateFactory(path) + registerTemplate(template, path) + + return template(**kw) + +render_template = render_template_explicit diff --git a/repoze/bfg/tests/fixtureapp/configure.zcml b/repoze/bfg/tests/fixtureapp/configure.zcml index 99d0708aa..f08cd58ad 100644 --- a/repoze/bfg/tests/fixtureapp/configure.zcml +++ b/repoze/bfg/tests/fixtureapp/configure.zcml @@ -12,7 +12,6 @@ <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 36fe07cc6..b9b9fc7d9 100644 --- a/repoze/bfg/tests/fixtureapp/views.py +++ b/repoze/bfg/tests/fixtureapp/views.py @@ -1,5 +1,3 @@ -from repoze.bfg.view import TemplateView - class FixtureView(object): def __init__(self, context, request): self.context = context @@ -8,5 +6,3 @@ class FixtureView(object): def __call__(self): pass -class FixtureTemplateView(TemplateView): - pass diff --git a/repoze/bfg/tests/test_template.py b/repoze/bfg/tests/test_template.py index 59dce3efa..96129504d 100644 --- a/repoze/bfg/tests/test_template.py +++ b/repoze/bfg/tests/test_template.py @@ -78,9 +78,8 @@ class RenderTemplateTests(unittest.TestCase, Base): from repoze.bfg.interfaces import IView minimal = self._getTemplatePath('minimal.pt') self.assertEqual(queryUtility(IView, minimal), None) - view = DummyView() render = self._getFUT() - result = render(view, minimal) + result = render(minimal) from webob import Response self.failUnless(isinstance(result, Response)) self.assertEqual(result.app_iter, ['<div>\n</div>']) @@ -100,9 +99,8 @@ class RenderTemplateTests(unittest.TestCase, Base): utility = Z3CPTTemplateFactory(minimal) gsm = getGlobalSiteManager() gsm.registerUtility(utility, IView, name=minimal) - view = DummyView() render = self._getFUT() - result = render(view, minimal) + result = render(minimal) from webob import Response self.failUnless(isinstance(result, Response)) self.assertEqual(result.app_iter, ['<div>\n</div>']) diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index 7d87b9c83..b6982f431 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -32,33 +32,3 @@ class ViewTests(unittest.TestCase): view = self._makeOne(None, None) self.assertRaises(NotImplementedError, view) -class TemplateViewTests(unittest.TestCase, Base): - def setUp(self): - Base.setUp(self) - - def tearDown(self): - Base.tearDown(self) - - def _getTargetClass(self): - from repoze.bfg.view import TemplateView - return TemplateView - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_call(self): - self._zcmlConfigure() - view = self._makeOne(None, None) - view.template = self._getTemplatePath('minimal.pt') - result = view(foo='foo') - from webob import Response - self.failUnless(isinstance(result, Response)) - self.assertEqual(result.app_iter, ['<div>\n</div>']) - self.assertEqual(result.status, '200 OK') - self.assertEqual(len(result.headerlist), 2) - - def test_call_no_template(self): - self._zcmlConfigure() - view = self._makeOne(None, None) - self.assertRaises(ValueError, view) diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index f87c49424..db826b687 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -103,101 +103,72 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): def test_template_and_factory(self): f = self._getFUT() context = DummyContext() - 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) + from zope.configuration.exceptions import ConfigurationError + self.assertRaises(ConfigurationError, f, context, 'repoze.view', + None, factory=object, template='minimal.pt') -class TestTemplateViewFactory(unittest.TestCase): +class TestTemplateOnlyViewFactory(unittest.TestCase): def _getTargetClass(self): - from repoze.bfg.zcml import TemplateViewFactory - return TemplateViewFactory + from repoze.bfg.zcml import TemplateOnlyViewFactory + return TemplateOnlyViewFactory - def _makeOne(self, template, base=None): - return self._getTargetClass()(template, base) + def _makeOne(self, template): + return self._getTargetClass()(template) 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_templateonly(self): + def test_call(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)) + from repoze.bfg.zcml import TemplateOnlyView + self.failUnless(isinstance(view, TemplateOnlyView)) 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) +class TemplateOnlyViewTests(unittest.TestCase, PlacelessSetup): + def setUp(self): + PlacelessSetup.setUp(self) - 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) + def tearDown(self): + PlacelessSetup.tearDown(self) + + def _getTargetClass(self): + from repoze.bfg.zcml import TemplateOnlyView + return TemplateOnlyView + + def _zcmlConfigure(self): + import repoze.bfg + import zope.configuration.xmlconfig + zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg) + + def _getTemplatePath(self, name): + import os + here = os.path.abspath(os.path.dirname(__file__)) + return os.path.join(here, 'fixtures', name) + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_call(self): + self._zcmlConfigure() + view = self._makeOne(None, None) + view.template = self._getTemplatePath('minimal.pt') + result = view(foo='foo') + from webob import Response + self.failUnless(isinstance(result, Response)) + self.assertEqual(result.app_iter, ['<div>\n</div>']) + self.assertEqual(result.status, '200 OK') + self.assertEqual(len(result.headerlist), 2) + + def test_call_no_template(self): + self._zcmlConfigure() + view = self._makeOne(None, None) + self.assertRaises(ValueError, view) class TestSampleApp(unittest.TestCase, PlacelessSetup): def setUp(self): diff --git a/repoze/bfg/view.py b/repoze/bfg/view.py index 07c3d183d..e2ea156a0 100644 --- a/repoze/bfg/view.py +++ b/repoze/bfg/view.py @@ -1,7 +1,13 @@ -from repoze.bfg.template import render_template +from zope.interface import implements +from zope.interface import classProvides + +from repoze.bfg.interfaces import IView +from repoze.bfg.interfaces import IViewFactory class View(object): """ Convenience base class for user-defined views """ + implements(IView) + classProvides(IViewFactory) def __init__(self, context, request): self.context = context self.request = request @@ -9,19 +15,5 @@ class View(object): def __call__(self, **kw): raise NotImplementedError -class TemplateView(View): - template = None - def __call__(self, **kw): - if self.template is None: - raise ValueError('a "template" attribute must be attached to ' - 'a TemplateView') - return render_template(self, self.template, **kw) - - def __repr__(self): - klass = self.__class__ - return '<%s.%s object at %s for %s>' % (klass.__module__, - klass.__mame__, - id(self), - self.template) diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index dc05cca18..1cfdcf953 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -1,6 +1,4 @@ -import inspect import os -import new from zope.component.zcml import handler from zope.component.interface import provideInterface @@ -8,10 +6,11 @@ from zope.configuration.exceptions import ConfigurationError from zope.configuration.fields import GlobalObject from zope.configuration.fields import Path -from zope.schema import TextLine from zope.interface import Interface from zope.interface import implements +from zope.interface import classProvides +from zope.schema import TextLine from zope.security.zcml import Permission from repoze.bfg.interfaces import IRequest @@ -19,31 +18,42 @@ from repoze.bfg.interfaces import IViewFactory from repoze.bfg.interfaces import IView from repoze.bfg.template import Z3CPTTemplateFactory -from repoze.bfg.view import TemplateView - -class TemplateViewFactory(object): - """ Pickleable template view factory """ +from repoze.bfg.template import render_template_explicit + +class TemplateOnlyView(object): + implements(IView) + classProvides(IViewFactory) + template = None + + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self, **kw): + if self.template is None: + raise ValueError('a "template" attribute must be attached to ' + 'a TemplateOnlyView') + kw = dict(view=self, context=self.context, request=self.request, + options=kw) + return render_template_explicit(self.template, **kw) + + def __repr__(self): + klass = self.__class__ + return '<%s.%s object at %s for %s>' % (klass.__module__, + klass.__mame__, + id(self), + self.template) + +class TemplateOnlyViewFactory(object): + """ Pickleable template-only view factory """ implements(IViewFactory) - 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) + def __init__(self, template): self.template = template - self.base = base def __call__(self, 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 = TemplateOnlyView(context, request) factory.template = self.template return factory @@ -57,9 +67,9 @@ def view(_context, # XXX we do nothing yet with permission - if not (template or factory): + if (template and factory): raise ConfigurationError( - 'One of template or factory (or both) must be specified') + 'One of template or factory must be specified, not both') if template: template_abs = os.path.abspath(str(_context.path(template))) @@ -71,7 +81,12 @@ def view(_context, callable = handler, args = ('registerUtility', utility, IView, template_abs), ) - factory = TemplateViewFactory(template_abs, factory) + factory = TemplateOnlyViewFactory(template_abs) + + if not factory: + raise ConfigurationError( + 'Neither template nor factory was specified, though one must be ' + 'specified.') if for_ is not None: _context.action( |
