zope.browserpage-4.0.0/0000775000175000017500000000000011775027151014723 5ustar tseavertseaverzope.browserpage-4.0.0/src/0000775000175000017500000000000011775027151015512 5ustar tseavertseaverzope.browserpage-4.0.0/src/zope/0000775000175000017500000000000011775027151016467 5ustar tseavertseaverzope.browserpage-4.0.0/src/zope/__init__.py0000664000175000017500000000007011775027036020577 0ustar tseavertseaver__import__('pkg_resources').declare_namespace(__name__) zope.browserpage-4.0.0/src/zope/browserpage/0000775000175000017500000000000011775027151021007 5ustar tseavertseaverzope.browserpage-4.0.0/src/zope/browserpage/meta.zcml0000664000175000017500000000236311775027036022632 0ustar tseavertseaver zope.browserpage-4.0.0/src/zope/browserpage/metadirectives.py0000664000175000017500000001523411775027036024400 0ustar tseavertseaver############################################################################# # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """ZCML directives for defining browser pages """ from zope.interface import Interface from zope.configuration.fields import GlobalObject, GlobalInterface from zope.configuration.fields import Path, PythonIdentifier, MessageID from zope.schema import TextLine from zope.security.zcml import Permission from zope.component.zcml import IBasicViewInformation try: from zope.browsermenu.field import MenuField except ImportError: # avoid hard dependency on zope.browsermenu MenuField = TextLine class IPagesDirective(IBasicViewInformation): """ Define multiple pages without repeating all of the parameters. The pages directive allows multiple page views to be defined without repeating the 'for', 'permission', 'class', 'layer', 'allowed_attributes', and 'allowed_interface' attributes. """ for_ = GlobalObject( title=u"The interface or class this view is for.", required=False ) layer = GlobalObject( title=u"The request interface or class this view is for.", description= u"Defaults to zope.publisher.interfaces.browser.IDefaultBrowserLayer.", required=False ) permission = Permission( title=u"Permission", description=u"The permission needed to use the view.", required=True ) class IViewDirective(IPagesDirective): """ The view directive defines a view that has subpages. The pages provided by the defined view are accessed by first traversing to the view name and then traversing to the page name. """ for_ = GlobalInterface( title=u"The interface this view is for.", required=False ) name = TextLine( title=u"The name of the view.", description=u"The name shows up in URLs/paths. For example 'foo'.", required=False, default=u'', ) menu = MenuField( title=u"The browser menu to include the page (view) in.", description=u""" Many views are included in menus. It's convenient to name the menu in the page directive, rather than having to give a separate menuItem directive. 'zmi_views' is the menu most often used in the Zope management interface. This attribute will only work if zope.browsermenu is installed. """, required=False ) title = MessageID( title=u"The browser menu label for the page (view)", description=u""" This attribute must be supplied if a menu attribute is supplied. This attribute will only work if zope.browsermenu is installed. """, required=False ) provides = GlobalInterface( title=u"The interface this view provides.", description=u""" A view can provide an interface. This would be used for views that support other views.""", required=False, default=Interface, ) class IViewPageSubdirective(Interface): """ Subdirective to IViewDirective. """ name = TextLine( title=u"The name of the page (view)", description=u""" The name shows up in URLs/paths. For example 'foo' or 'foo.html'. This attribute is required unless you use the subdirective 'page' to create sub views. If you do not have sub pages, it is common to use an extension for the view name such as '.html'. If you do have sub pages and you want to provide a view name, you shouldn't use extensions.""", required=True ) attribute = PythonIdentifier( title=u"The name of the view attribute implementing the page.", description=u""" This refers to the attribute (method) on the view that is implementing a specific sub page.""", required=False ) template = Path( title=u"The name of a template that implements the page.", description=u""" Refers to a file containing a page template (should end in extension '.pt' or '.html').""", required=False ) class IViewDefaultPageSubdirective(Interface): """ Subdirective to IViewDirective. """ name = TextLine( title=u"The name of the page that is the default.", description=u""" The named page will be used as the default if no name is specified explicitly in the path. If no defaultPage directive is supplied, the default page will be the first page listed.""", required=True ) class IPagesPageSubdirective(IViewPageSubdirective): """ Subdirective to IPagesDirective """ menu = MenuField( title=u"The browser menu to include the page (view) in.", description=u""" Many views are included in menus. It's convenient to name the menu in the page directive, rather than having to give a separate menuItem directive. This attribute will only work if zope.browsermenu is installed. """, required=False ) title = MessageID( title=u"The browser menu label for the page (view)", description=u""" This attribute must be supplied if a menu attribute is supplied. This attribute will only work if zope.browsermenu is installed. """, required=False ) class IPageDirective(IPagesDirective, IPagesPageSubdirective): """ The page directive is used to create views that provide a single url or page. The page directive creates a new view class from a given template and/or class and registers it. """ class IExpressionTypeDirective(Interface): """Register a new TALES expression type""" name = TextLine( title=u"Name", description=u"""Name of the expression. This will also be used as the prefix in actual TALES expressions.""", required=True ) handler = GlobalObject( title=u"Handler", description=u"""Handler is class that implements zope.tales.interfaces.ITALESExpression.""", required=True ) zope.browserpage-4.0.0/src/zope/browserpage/namedtemplate.txt0000664000175000017500000000467711775027036024410 0ustar tseavertseaver=============== Named Templates =============== We often want to be able to define view logic and view templates independently. We'd like to be able to change the template used by a form without being forced to modify the form. Named templates provide templates that are registered as named view adapters. To define a named template, use the `NamedTemplateImplementation` constructor: >>> from zope.browserpage import ViewPageTemplateFile >>> from zope.browserpage.namedtemplate import ( ... NamedTemplateImplementation) >>> sample = ViewPageTemplateFile('tests/namedtemplate.pt') >>> sample = NamedTemplateImplementation(sample) Let's define a view that uses the named template. To use a named template, use the NamedTemplate constructor, and give a template name: >>> from zope.browserpage.namedtemplate import NamedTemplate >>> class MyView: ... def __init__(self, context, request): ... self.context = context ... self.request = request ... ... __call__ = NamedTemplate('sample') Normally, we'd register a named template for a view interface, to allow it to be registered for multiple views. We'll just register it for our view class. >>> from zope import component >>> component.provideAdapter(sample, [MyView], name='sample') Now, with this in place, we should be able to use our view: >>> class MyContent: ... def __init__(self, name): ... self.name = name >>> from zope.publisher.browser import TestRequest >>> print MyView(MyContent('bob'), TestRequest())(x=42) Hello bob The URL is http://127.0.0.1 The positional arguments were () The keyword argument x is 42 The view type that a named template is to be used for can be supplied when the named template is created: >>> class MyView: ... def __init__(self, context, request): ... self.context = context ... self.request = request ... ... __call__ = NamedTemplate('sample2') >>> sample = ViewPageTemplateFile('tests/namedtemplate.pt') >>> sample = NamedTemplateImplementation(sample, MyView) >>> component.provideAdapter(sample, name='sample2') >>> print MyView(MyContent('bob'), TestRequest())(x=42) Hello bob The URL is http://127.0.0.1 The positional arguments were () The keyword argument x is 42 zope.browserpage-4.0.0/src/zope/browserpage/tests/0000775000175000017500000000000011775027151022151 5ustar tseavertseaverzope.browserpage-4.0.0/src/zope/browserpage/tests/test_boundpagetemplate.py0000664000175000017500000000217411775027036027270 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Bound Page Template Tests """ import unittest class Test(unittest.TestCase): def testAttributes(self): from zope.browserpage.tests.sample import C C.index.im_func.foo = 1 self.assertEqual(C.index.macros, C.index.im_func.macros) self.assertEqual(C.index.filename, C.index.im_func.filename) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.browserpage-4.0.0/src/zope/browserpage/tests/test_namedtemplate.py0000664000175000017500000000232311775027036026404 0ustar tseavertseaver############################################################################## # # Copyright (c) 2005-2009 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """ """ import os import os.path import zope.component.testing import zope.traversing.adapters def pageSetUp(test): zope.component.testing.setUp(test) zope.component.provideAdapter( zope.traversing.adapters.DefaultTraversable, [None], ) def test_suite(): import doctest filename = os.path.join(os.pardir, 'namedtemplate.txt') return doctest.DocFileSuite( filename, setUp=pageSetUp, tearDown=zope.component.testing.tearDown, globs={'__file__': os.path.abspath(os.path.join(os.path.dirname(__file__), filename))} ) zope.browserpage-4.0.0/src/zope/browserpage/tests/test.pt0000664000175000017500000000003311775027036023473 0ustar tseavertseaver zope.browserpage-4.0.0/src/zope/browserpage/tests/test_expressiontype.py0000664000175000017500000000342611775027036026672 0ustar tseavertseaver############################################################################## # # Copyright (c) 2003 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Tests to check talesapi zcml configuration """ import unittest from cStringIO import StringIO from zope.configuration.xmlconfig import xmlconfig, XMLConfig from zope.pagetemplate.engine import Engine import zope.browserpage from zope.component.testing import PlacelessSetup template = """ %s """ class Handler(object): pass class Test(PlacelessSetup, unittest.TestCase): def setUp(self): super(Test, self).setUp() XMLConfig('meta.zcml', zope.browserpage)() def testExpressionType(self): xmlconfig(StringIO(template % ( """ """ ))) self.assert_("test" in Engine.getTypes()) self.assert_(Handler is Engine.getTypes()['test']) def test_suite(): loader=unittest.TestLoader() return loader.loadTestsFromTestCase(Test) if __name__=='__main__': unittest.TextTestRunner().run(test_suite()) zope.browserpage-4.0.0/src/zope/browserpage/tests/test_simpleviewclass.py0000664000175000017500000001330611775027036027001 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001-2009 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Simple View Class Tests """ import unittest class Test_SimpleTestView(unittest.TestCase): def _getTargetClass(self): from zope.browserpage.tests.simpletestview import SimpleTestView return SimpleTestView def _makeOne(self, context, request): return self._getTargetClass()(context, request) def test_simple(self): from zope.publisher.browser import TestRequest context = DummyContext() request = TestRequest() view = self._makeOne(context, request) macro = view['test'] out = view() self.assertEqual(out, '\n' ' \n' '

hello world

\n' ' \n\n') class Test_SimpleViewClass(unittest.TestCase): def _getTargetClass(self): from zope.browserpage.simpleviewclass import SimpleViewClass return SimpleViewClass def _makeKlass(self, *args, **kw): return self._getTargetClass()(*args, **kw) def test___name__(self): klass = self._makeKlass('testsimpleviewclass.pt', name='test.html') view = klass(None, None) self.assertEqual(view.__name__, 'test.html') def test___getitem___(self): klass = self._makeKlass('testsimpleviewclass.pt', name='test.html') view = klass(None, None) self.assert_(view['test'] is not None) self.assertRaises(KeyError, view.__getitem__, 'foo') def test_w_base_classes(self): from zope.publisher.browser import TestRequest class BaseClass(object): pass klass = self._makeKlass('testsimpleviewclass.pt', bases=(BaseClass, )) self.failUnless(issubclass(klass, BaseClass)) ob = DummyContext() request = TestRequest() view = klass(ob, request) macro = view['test'] out = view() self.assertEqual(out, '\n' ' \n' '

hello world

\n' ' \n\n') class Test_simple(unittest.TestCase): def _getTargetClass(self): from zope.browserpage.simpleviewclass import simple return simple def _makeOne(self, context=None, request=None): if context is None: context = DummyContext() if request is None: request = DummyRequest() return self._getTargetClass()(context, request) def test_class_conforms_to_IBrowserPublisher(self): from zope.interface.verify import verifyClass from zope.publisher.interfaces.browser import IBrowserPublisher verifyClass(IBrowserPublisher, self._getTargetClass()) def test_browserDefault(self): request = DummyRequest() view = self._makeOne(request=request) self.assertEqual(view.browserDefault(request), (view, ())) def test_publishTraverse_not_index_raises_NotFound(self): from zope.publisher.interfaces import NotFound request = DummyRequest() view = self._makeOne(request=request) self.assertRaises(NotFound, view.publishTraverse, request, 'nonesuch') def test_publishTraverse_w_index_returns_index(self): request = DummyRequest() view = self._makeOne(request=request) index = view.index = DummyTemplate() self.failUnless(view.publishTraverse(request, 'index.html') is index) def test___getitem___uses_index_macros(self): view = self._makeOne() view.index = index = DummyTemplate() index.macros = {} index.macros['aaa'] = aaa = object() self.failUnless(view['aaa'] is aaa) def test___call___no_args_no_kw(self): view = self._makeOne() view.index = index = DummyTemplate() result = view() self.failUnless(result is index) self.assertEqual(index._called_with, ((), {})) def test___call___w_args_no_kw(self): view = self._makeOne() view.index = index = DummyTemplate() result = view('abc') self.failUnless(result is index) self.assertEqual(index._called_with, (('abc',), {})) def test___call___no_args_w_kw(self): view = self._makeOne() view.index = index = DummyTemplate() result = view(foo='bar') self.failUnless(result is index) self.assertEqual(index._called_with, ((), {'foo': 'bar'})) def test___call___no_args_no_kw(self): view = self._makeOne() view.index = index = DummyTemplate() result = view('abc', foo='bar') self.failUnless(result is index) self.assertEqual(index._called_with, (('abc',), {'foo': 'bar'})) class DummyContext: pass class DummyResponse: pass class DummyRequest: debug = False response = DummyResponse() class DummyTemplate: def __call__(self, *args, **kw): self._called_with = (args, kw) return self def test_suite(): return unittest.TestSuite(( unittest.makeSuite(Test_SimpleTestView), unittest.makeSuite(Test_SimpleViewClass), unittest.makeSuite(Test_simple), )) zope.browserpage-4.0.0/src/zope/browserpage/tests/testfiles/0000775000175000017500000000000011775027151024153 5ustar tseavertseaverzope.browserpage-4.0.0/src/zope/browserpage/tests/testfiles/test.pt0000664000175000017500000000004611775027036025501 0ustar tseavertseaver

test

zope.browserpage-4.0.0/src/zope/browserpage/tests/testfiles/test2.pt0000664000175000017500000000007611775027036025566 0ustar tseavertseaver

test

zope.browserpage-4.0.0/src/zope/browserpage/tests/testfiles/test3.pt0000664000175000017500000000010011775027036025553 0ustar tseavertseaver

test

zope.browserpage-4.0.0/src/zope/browserpage/tests/test_page.py0000664000175000017500000007720411775027036024512 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Tests for browser:page directive and friends """ import sys import os import unittest from doctest import DocTestSuite from cStringIO import StringIO from zope import component from zope.interface import Interface, implementer, directlyProvides, providedBy import zope.security.management from zope.configuration.xmlconfig import xmlconfig, XMLConfig from zope.configuration.exceptions import ConfigurationError from zope.publisher.browser import TestRequest from zope.publisher.interfaces import IDefaultViewName from zope.publisher.interfaces.browser import IBrowserPublisher from zope.publisher.interfaces.browser import IBrowserRequest from zope.publisher.interfaces.browser import IBrowserSkinType, IDefaultSkin from zope.security.proxy import removeSecurityProxy, ProxyFactory from zope.security.permission import Permission from zope.security.interfaces import IPermission from zope.testing import cleanup from zope.traversing.adapters import DefaultTraversable from zope.traversing.interfaces import ITraversable import zope.publisher.defaultview import zope.browserpage import zope.browsermenu from zope.browsermenu.menu import getFirstMenuItem from zope.browsermenu.interfaces import IMenuItemType from zope.component.testfiles.views import IC, V1, VZMI, R1, IV tests_path = os.path.dirname(__file__) template = """ %s """ class templateclass(object): def data(self): return 42 request = TestRequest() class V2(V1, object): def action(self): return self.action2() def action2(self): return "done" class VT(V1, object): def publishTraverse(self, request, name): try: return int(name) except: return super(VT, self).publishTraverse(request, name) @implementer(IC) class Ob(object): pass ob = Ob() class NCV(object): "non callable view" def __init__(self, context, request): pass class CV(NCV): "callable view" def __call__(self): pass @implementer(Interface) class C_w_implements(NCV): def index(self): return self class ITestLayer(IBrowserRequest): """Test Layer.""" class ITestSkin(ITestLayer): """Test Skin.""" class ITestMenu(Interface): """Test menu.""" directlyProvides(ITestMenu, IMenuItemType) class Test(cleanup.CleanUp, unittest.TestCase): def setUp(self): super(Test, self).setUp() XMLConfig('meta.zcml', zope.browserpage)() XMLConfig('meta.zcml', zope.browsermenu)() component.provideAdapter(DefaultTraversable, (None,), ITraversable, ) zope.security.management.newInteraction() def testPage(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ( ''' ''' ))) v = component.queryMultiAdapter((ob, request), name='test') self.assert_(issubclass(v.__class__, V1)) def testPageWithClassWithMenu(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) testtemplate = os.path.join(tests_path, 'testfiles', 'test.pt') xmlconfig(StringIO(template % ( ''' ''' % testtemplate ))) menuItem = getFirstMenuItem('test_menu', ob, TestRequest()) self.assertEqual(menuItem["title"], "Test View") self.assertEqual(menuItem["action"], "@@test") v = component.queryMultiAdapter((ob, request), name='test') self.assertEqual(v(), "

test

\n") def testPageWithTemplateWithMenu(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) testtemplate = os.path.join(tests_path, 'testfiles', 'test.pt') xmlconfig(StringIO(template % ( ''' ''' % testtemplate ))) menuItem = getFirstMenuItem('test_menu', ob, TestRequest()) self.assertEqual(menuItem["title"], "Test View") self.assertEqual(menuItem["action"], "@@test") v = component.queryMultiAdapter((ob, request), name='test') self.assertEqual(v(), "

test

\n") def testPageInPagesWithTemplateWithMenu(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) testtemplate = os.path.join(tests_path, 'testfiles', 'test.pt') xmlconfig(StringIO(template % ( ''' ''' % testtemplate ))) menuItem = getFirstMenuItem('test_menu', ob, TestRequest()) self.assertEqual(menuItem["title"], "Test View") self.assertEqual(menuItem["action"], "@@test") v = component.queryMultiAdapter((ob, request), name='test') self.assertEqual(v(), "

test

\n") def testPageInPagesWithClassWithMenu(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) testtemplate = os.path.join(tests_path, 'testfiles', 'test.pt') xmlconfig(StringIO(template % ( ''' ''' % testtemplate ))) menuItem = getFirstMenuItem('test_menu', ob, TestRequest()) self.assertEqual(menuItem["title"], "Test View") self.assertEqual(menuItem["action"], "@@test") v = component.queryMultiAdapter((ob, request), name='test') self.assertEqual(v(), "

test

\n") def testSkinPage(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ( ''' ''' ))) v = component.queryMultiAdapter((ob, request), name='test') self.assert_(issubclass(v.__class__, V1)) v = component.queryMultiAdapter( (ob, TestRequest(skin=ITestSkin)), name='test') self.assert_(issubclass(v.__class__, VZMI)) def testInterfaceProtectedPage(self): xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='test') v = ProxyFactory(v) self.assertEqual(v.index(), 'V1 here') self.assertRaises(Exception, getattr, v, 'action') def testAttributeProtectedPage(self): xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='test') v = ProxyFactory(v) self.assertEqual(v.action(), 'done') self.assertEqual(v.action2(), 'done') self.assertRaises(Exception, getattr, v, 'index') def testAttributeProtectedView(self): xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='test') v = ProxyFactory(v) page = v.publishTraverse(request, 'index.html') self.assertEqual(page(), 'done') self.assertEqual(v.action2(), 'done') self.assertRaises(Exception, getattr, page, 'index') def testInterfaceAndAttributeProtectedPage(self): xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='test') self.assertEqual(v.index(), 'V1 here') self.assertEqual(v.action(), 'done') def testDuplicatedInterfaceAndAttributeProtectedPage(self): xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='test') self.assertEqual(v.index(), 'V1 here') self.assertEqual(v.action(), 'done') def test_class_w_implements(self): xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='test') self.assertEqual(v.index(), v) self.assert_(IBrowserPublisher.providedBy(v)) def testIncompleteProtectedPageNoPermission(self): self.assertRaises( ConfigurationError, xmlconfig, StringIO(template % ''' ''' )) def testPageViews(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) test3 = os.path.join(tests_path, 'testfiles', 'test3.pt') xmlconfig(StringIO(template % ''' ''' % test3 )) v = component.getMultiAdapter((ob, request), name='index.html') self.assertEqual(v(), 'V1 here') v = component.getMultiAdapter((ob, request), name='action.html') self.assertEqual(v(), 'done') v = component.getMultiAdapter((ob, request), name='test.html') self.assertEqual(str(v()), '

done

\n') def testNamedViewPageViewsCustomTraversr(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ''' ''' )) view = component.getMultiAdapter((ob, request), name='test') view = removeSecurityProxy(view) self.assertEqual(view.browserDefault(request)[1], (u'index.html', )) v = view.publishTraverse(request, 'index.html') v = removeSecurityProxy(v) self.assertEqual(v(), 'V1 here') v = view.publishTraverse(request, 'action.html') v = removeSecurityProxy(v) self.assertEqual(v(), 'done') def testNamedViewNoPagesForCallable(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ''' ''' )) view = component.getMultiAdapter((ob, request), name='test') view = removeSecurityProxy(view) self.assertEqual(view.browserDefault(request), (view, ())) def testNamedViewNoPagesForNonCallable(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ''' ''' )) view = component.getMultiAdapter((ob, request), name='test') view = removeSecurityProxy(view) self.assertEqual(getattr(view, 'browserDefault', None), None) def testNamedViewPageViewsNoDefault(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) test3 = os.path.join(tests_path, 'testfiles', 'test3.pt') xmlconfig(StringIO(template % ''' ''' % test3 )) view = component.getMultiAdapter((ob, request), name='test') view = removeSecurityProxy(view) self.assertEqual(view.browserDefault(request)[1], (u'index.html', )) v = view.publishTraverse(request, 'index.html') v = removeSecurityProxy(v) self.assertEqual(v(), 'V1 here') v = view.publishTraverse(request, 'action.html') v = removeSecurityProxy(v) self.assertEqual(v(), 'done') v = view.publishTraverse(request, 'test.html') v = removeSecurityProxy(v) self.assertEqual(str(v()), '

done

\n') def testNamedViewPageViewsWithDefault(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) test3 = os.path.join(tests_path, 'testfiles', 'test3.pt') xmlconfig(StringIO(template % ''' ''' % test3 )) view = component.getMultiAdapter((ob, request), name='test') view = removeSecurityProxy(view) self.assertEqual(view.browserDefault(request)[1], (u'test.html', )) v = view.publishTraverse(request, 'index.html') v = removeSecurityProxy(v) self.assertEqual(v(), 'V1 here') v = view.publishTraverse(request, 'action.html') v = removeSecurityProxy(v) self.assertEqual(v(), 'done') v = view.publishTraverse(request, 'test.html') v = removeSecurityProxy(v) self.assertEqual(str(v()), '

done

\n') def testTraversalOfPageForView(self): """Tests proper traversal of a page defined for a view.""" xmlconfig(StringIO(template % ''' ''' )) view = component.getMultiAdapter((ob, request), name='test') view = removeSecurityProxy(view) view.publishTraverse(request, 'index.html') def testTraversalOfPageForViewWithPublishTraverse(self): """Tests proper traversal of a page defined for a view. This test is different from testTraversalOfPageForView in that it tests the behavior on a view that has a publishTraverse method -- the implementation of the lookup is slightly different in such a case. """ xmlconfig(StringIO(template % ''' ''' )) view = component.getMultiAdapter((ob, request), name='test') view = removeSecurityProxy(view) view.publishTraverse(request, 'index.html') def testProtectedPageViews(self): component.provideUtility(Permission('p', 'P'), IPermission, 'p') request = TestRequest() self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='index.html') v = ProxyFactory(v) zope.security.management.getInteraction().add(request) self.assertRaises(Exception, v) v = component.getMultiAdapter((ob, request), name='action.html') v = ProxyFactory(v) self.assertRaises(Exception, v) def testProtectedNamedViewPageViews(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ''' ''' )) view = component.getMultiAdapter((ob, request), name='test') self.assertEqual(view.browserDefault(request)[1], (u'index.html', )) v = view.publishTraverse(request, 'index.html') self.assertEqual(v(), 'V1 here') def testSkinnedPageView(self): self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ''' ''' )) v = component.getMultiAdapter((ob, request), name='index.html') self.assertEqual(v(), 'V1 here') v = component.getMultiAdapter((ob, TestRequest(skin=ITestSkin)), name='index.html') self.assertEqual(v(), 'done') def test_template_page(self): path = os.path.join(tests_path, 'testfiles', 'test.pt') self.assertEqual( component.queryMultiAdapter((ob, request), name='index.html'), None) xmlconfig(StringIO(template % ''' ''' % path )) v = component.getMultiAdapter((ob, request), name='index.html') self.assertEqual(v().strip(), '

test

') def test_page_menu_within_different_layers(self): path = os.path.join(tests_path, 'testfiles', 'test.pt') self.assertEqual( component.queryMultiAdapter((ob, request), name='index.html'), None) xmlconfig(StringIO(template % ''' ''' % (path, path) )) v = component.getMultiAdapter((ob, request), name='index.html') self.assertEqual(v().strip(), '

test

') def testtemplateWClass(self): path = os.path.join(tests_path, 'testfiles', 'test2.pt') self.assertEqual( component.queryMultiAdapter((ob, request), name='index.html'), None) xmlconfig(StringIO(template % ''' ''' % path )) v = component.getMultiAdapter((ob, request), name='index.html') self.assertEqual(v().strip(), '

42

') def testProtectedtemplate(self): path = os.path.join(tests_path, 'testfiles', 'test.pt') request = TestRequest() self.assertEqual( component.queryMultiAdapter((ob, request), name='test'), None) xmlconfig(StringIO(template % ''' ''' % path )) xmlconfig(StringIO(template % ''' ''' % path )) v = component.getMultiAdapter((ob, request), name='xxx.html') v = ProxyFactory(v) zope.security.management.getInteraction().add(request) self.assertRaises(Exception, v) v = component.getMultiAdapter((ob, request), name='index.html') v = ProxyFactory(v) self.assertEqual(v().strip(), '

test

') def testtemplateNoName(self): path = os.path.join(tests_path, 'testfiles', 'test.pt') self.assertRaises( ConfigurationError, xmlconfig, StringIO(template % ''' ''' % path )) def testtemplateAndPage(self): path = os.path.join(tests_path, 'testfiles', 'test.pt') self.assertRaises( ConfigurationError, xmlconfig, StringIO(template % ''' ''' % path )) def testViewThatProvidesAnInterface(self): request = TestRequest() self.assertEqual( component.queryMultiAdapter((ob, request), IV, name='test'), None) xmlconfig(StringIO(template % ''' ''' )) v = component.queryMultiAdapter((ob, request), IV, name='test') self.assertEqual(v, None) xmlconfig(StringIO(template % ''' ''' )) v = component.queryMultiAdapter((ob, request), IV, name='test') self.assert_(isinstance(v, V1)) def testUnnamedViewThatProvidesAnInterface(self): request = TestRequest() self.assertEqual(component.queryMultiAdapter((ob, request), IV), None) xmlconfig(StringIO(template % ''' ''' )) v = component.queryMultiAdapter((ob, request), IV) self.assertEqual(v, None) xmlconfig(StringIO(template % ''' ''' )) v = component.queryMultiAdapter((ob, request), IV) self.assert_(isinstance(v, V1)) def test_suite(): return unittest.makeSuite(Test) zope.browserpage-4.0.0/src/zope/browserpage/tests/test_viewzpt.py0000664000175000017500000001110711775027036025274 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """View ZPT Tests """ import unittest from zope.component import getGlobalSiteManager from zope.component.testing import PlacelessSetup from zope.interface import Interface, implementer from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile class I1(Interface): pass @implementer(I1) class C1(object): pass class InstanceWithContext(object): def __init__(self, context): self.context = context class InstanceWithoutContext(object): pass class TestViewZPT(PlacelessSetup, unittest.TestCase): def setUp(self): super(TestViewZPT, self).setUp() self.t = ViewPageTemplateFile('test.pt') self.context = C1() def testNamespaceContextAvailable(self): context = self.context request = None namespace = self.t.pt_getContext(InstanceWithContext(context), request) self.failUnless(namespace['context'] is context) self.failUnless('views' in namespace) def testNamespaceHereNotAvailable(self): request = None self.assertRaises(AttributeError, self.t.pt_getContext, InstanceWithoutContext(), request) def testViewMapper(self): the_view = "This is the view" the_view_name = "some view name" def ViewMaker(*args, **kw): return the_view from zope.publisher.interfaces import IRequest gsm = getGlobalSiteManager() gsm.registerAdapter( ViewMaker, (I1, IRequest), Interface, the_view_name, event=False) @implementer(IRequest) class MyRequest(object): pass request = MyRequest() namespace = self.t.pt_getContext(InstanceWithContext(self.context), request) views = namespace['views'] self.failUnless(the_view is views[the_view_name]) def test_debug_flags(self): from zope.publisher.browser import TestRequest self.request = TestRequest() self.request.debug.sourceAnnotations = False self.assert_('test.pt' not in self.t(self)) self.request.debug.sourceAnnotations = True self.assert_('test.pt' in self.t(self)) t = ViewPageTemplateFile('testsimpleviewclass.pt') self.request.debug.showTAL = False self.assert_('metal:' not in t(self)) self.request.debug.showTAL = True self.assert_('metal:' in t(self)) def test_render_sets_content_type_unless_set(self): from zope.publisher.browser import TestRequest t = ViewPageTemplateFile('test.pt') self.request = TestRequest() response = self.request.response self.assert_(not response.getHeader('Content-Type')) t(self) self.assertEquals(response.getHeader('Content-Type'), 'text/html') self.request = TestRequest() response = self.request.response response.setHeader('Content-Type', 'application/x-test-junk') t(self) self.assertEquals(response.getHeader('Content-Type'), 'application/x-test-junk') class TestViewZPTContentType(unittest.TestCase): def testInitWithoutType(self): t = ViewPageTemplateFile('test.pt') t._cook_check() self.assertEquals(t.content_type, "text/html") t = ViewPageTemplateFile('testxml.pt') t._cook_check() self.assertEquals(t.content_type, "text/xml") def testInitWithType(self): t = ViewPageTemplateFile('test.pt', content_type="text/plain") t._cook_check() self.assertEquals(t.content_type, "text/plain") t = ViewPageTemplateFile('testxml.pt', content_type="text/plain") t._cook_check() self.assertEquals(t.content_type, "text/xml") def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestViewZPT)) suite.addTest(unittest.makeSuite(TestViewZPTContentType)) return suite if __name__ == '__main__': unittest.TextTestRunner().run(test_suite()) zope.browserpage-4.0.0/src/zope/browserpage/tests/__init__.py0000664000175000017500000000000111775027036024253 0ustar tseavertseaver#zope.browserpage-4.0.0/src/zope/browserpage/tests/simpletestview.py0000664000175000017500000000142311775027036025611 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Simple Test View """ from zope.browserpage.simpleviewclass import SimpleViewClass SimpleTestView = SimpleViewClass('testsimpleviewclass.pt') zope.browserpage-4.0.0/src/zope/browserpage/tests/testxml.pt0000664000175000017500000000006211775027036024216 0ustar tseavertseaver zope.browserpage-4.0.0/src/zope/browserpage/tests/testsimpleviewclass.pt0000664000175000017500000000012311775027036026626 0ustar tseavertseaver

hello world

zope.browserpage-4.0.0/src/zope/browserpage/tests/namedtemplate.pt0000664000175000017500000000035111775027036025337 0ustar tseavertseaver Hello The URL is The positional arguments were The keyword argument x is zope.browserpage-4.0.0/src/zope/browserpage/tests/sample.py0000664000175000017500000000141211775027036024004 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Sample Component """ from zope.browserpage import ViewPageTemplateFile class C(object): index = ViewPageTemplateFile('test.pt') zope.browserpage-4.0.0/src/zope/browserpage/viewpagetemplatefile.py0000664000175000017500000000643211775027036025573 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """File-based page templates that can be used as methods on views. """ __docformat__ = 'restructuredtext' from zope.component import getMultiAdapter from zope.pagetemplate.pagetemplatefile import PageTemplateFile from zope.pagetemplate.engine import TrustedAppPT class ViewPageTemplateFile(TrustedAppPT, PageTemplateFile): """Page Templates used as methods of views defined as Python classes. """ def __init__(self, filename, _prefix=None, content_type=None): _prefix = self.get_path_from_prefix(_prefix) super(ViewPageTemplateFile, self).__init__(filename, _prefix) if content_type is not None: self.content_type = content_type def pt_getContext(self, instance, request, **_kw): # instance is a View component namespace = super(ViewPageTemplateFile, self).pt_getContext(**_kw) namespace['request'] = request namespace['view'] = instance namespace['context'] = context = instance.context namespace['views'] = ViewMapper(context, request) return namespace def __call__(self, instance, *args, **keywords): namespace = self.pt_getContext( request=instance.request, instance=instance, args=args, options=keywords) debug_flags = instance.request.debug s = self.pt_render( namespace, showtal=getattr(debug_flags, 'showTAL', 0), sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0), ) response = instance.request.response if not response.getHeader("Content-Type"): response.setHeader("Content-Type", self.content_type) return s def __get__(self, instance, type): return BoundPageTemplate(self, instance) class ViewMapper(object): def __init__(self, ob, request): self.ob = ob self.request = request def __getitem__(self, name): return getMultiAdapter((self.ob, self.request), name=name) class BoundPageTemplate(object): def __init__(self, pt, ob): object.__setattr__(self, 'im_func', pt) object.__setattr__(self, 'im_self', ob) macros = property(lambda self: self.im_func.macros) filename = property(lambda self: self.im_func.filename) def __call__(self, *args, **kw): if self.im_self is None: im_self, args = args[0], args[1:] else: im_self = self.im_self return self.im_func(im_self, *args, **kw) def __setattr__(self, name, v): raise AttributeError("Can't set attribute", name) def __repr__(self): return "" % self.im_self def NoTraverser(ob, request): return None zope.browserpage-4.0.0/src/zope/browserpage/simpleviewclass.py0000664000175000017500000000345311775027036024602 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Simple View Class """ __docformat__ = 'restructuredtext' import sys from zope.interface import implementer from zope.publisher.browser import BrowserView from zope.publisher.interfaces.browser import IBrowserPublisher from zope.publisher.interfaces import NotFound from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile @implementer(IBrowserPublisher) class simple(BrowserView): def browserDefault(self, request): return self, () def publishTraverse(self, request, name): if name == 'index.html': return self.index raise NotFound(self, name, request) def __getitem__(self, name): return self.index.macros[name] def __call__(self, *args, **kw): return self.index(*args, **kw) def SimpleViewClass(src, offering=None, used_for=None, bases=(), name=u''): if offering is None: offering = sys._getframe(1).f_globals bases += (simple, ) class_ = type("SimpleViewClass from %s" % src, bases, {'index': ViewPageTemplateFile(src, offering), '__name__': name}) if used_for is not None: class_.__used_for__ = used_for return class_ zope.browserpage-4.0.0/src/zope/browserpage/metaconfigure.py0000664000175000017500000003564111775027036024224 0ustar tseavertseaver############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Browser page ZCML configuration code """ import os from zope.component import queryMultiAdapter from zope.component.interface import provideInterface from zope.component.zcml import handler from zope.interface import implementer, classImplements, Interface from zope.publisher.interfaces import NotFound from zope.security.checker import CheckerPublic, Checker, defineChecker from zope.configuration.exceptions import ConfigurationError from zope.pagetemplate.engine import Engine from zope.pagetemplate.engine import _Engine from zope.pagetemplate.engine import TrustedEngine from zope.pagetemplate.engine import _TrustedEngine from zope.publisher.interfaces.browser import IBrowserRequest from zope.publisher.interfaces.browser import IDefaultBrowserLayer from zope.publisher.interfaces.browser import IBrowserPublisher from zope.publisher.browser import BrowserView from zope.browserpage.simpleviewclass import SimpleViewClass from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile try: from zope.browsermenu.metaconfigure import menuItemDirective except ImportError: menuItemDirective = None # There are three cases we want to suport: # # Named view without pages (single-page view) # # # # Unnamed view with pages (multi-page view) # # # # # # # # Named view with pages (add view is a special case of this) # # # # # # # We'll also provide a convenience directive for add views: # # # # # #
# page def page(_context, name, permission, for_=Interface, layer=IDefaultBrowserLayer, template=None, class_=None, allowed_interface=None, allowed_attributes=None, attribute='__call__', menu=None, title=None, ): _handle_menu(_context, menu, title, [for_], name, permission, layer) required = {} permission = _handle_permission(_context, permission) if not (class_ or template): raise ConfigurationError("Must specify a class or template") if attribute != '__call__': if template: raise ConfigurationError( "Attribute and template cannot be used together.") if not class_: raise ConfigurationError( "A class must be provided if attribute is used") if template: template = os.path.abspath(str(_context.path(template))) if not os.path.isfile(template): raise ConfigurationError("No such file", template) required['__getitem__'] = permission # TODO: new __name__ attribute must be tested if class_: if attribute != '__call__': if not hasattr(class_, attribute): raise ConfigurationError( "The provided class doesn't have the specified attribute " ) if template: # class and template new_class = SimpleViewClass(template, bases=(class_, ), name=name) else: if not hasattr(class_, 'browserDefault'): cdict = { 'browserDefault': lambda self, request: (getattr(self, attribute), ()) } else: cdict = {} cdict['__name__'] = name cdict['__page_attribute__'] = attribute new_class = type(class_.__name__, (class_, simple,), cdict) if hasattr(class_, '__implements__'): classImplements(new_class, IBrowserPublisher) else: # template new_class = SimpleViewClass(template, name=name) for n in (attribute, 'browserDefault', '__call__', 'publishTraverse'): required[n] = permission _handle_allowed_interface(_context, allowed_interface, permission, required) _handle_allowed_attributes(_context, allowed_attributes, permission, required) _handle_for(_context, for_) defineChecker(new_class, Checker(required)) _context.action( discriminator = ('view', (for_, layer), name, IBrowserRequest), callable = handler, args = ('registerAdapter', new_class, (for_, layer), Interface, name, _context.info), ) # pages, which are just a short-hand for multiple page directives. # Note that a class might want to access one of the defined # templates. If it does though, it should use getMultiAdapter. class pages(object): def __init__(self, _context, permission, for_=Interface, layer=IDefaultBrowserLayer, class_=None, allowed_interface=None, allowed_attributes=None, ): self.opts = dict(for_=for_, permission=permission, layer=layer, class_=class_, allowed_interface=allowed_interface, allowed_attributes=allowed_attributes, ) def page(self, _context, name, attribute='__call__', template=None, menu=None, title=None): return page(_context, name=name, attribute=attribute, template=template, menu=menu, title=title, **(self.opts)) def __call__(self): return () # view (named view with pages) # This is a different case. We actually build a class with attributes # for all of the given pages. class view(object): default = None def __init__(self, _context, permission, for_=Interface, name='', layer=IDefaultBrowserLayer, class_=None, allowed_interface=None, allowed_attributes=None, menu=None, title=None, provides=Interface, ): _handle_menu(_context, menu, title, [for_], name, permission, layer) permission = _handle_permission(_context, permission) self.args = (_context, name, (for_, layer), permission, class_, allowed_interface, allowed_attributes) self.pages = [] self.menu = menu self.provides = provides def page(self, _context, name, attribute=None, template=None): if template: template = os.path.abspath(_context.path(template)) if not os.path.isfile(template): raise ConfigurationError("No such file", template) else: if not attribute: raise ConfigurationError( "Must specify either a template or an attribute name") self.pages.append((name, attribute, template)) return () def defaultPage(self, _context, name): self.default = name return () def __call__(self): (_context, name, (for_, layer), permission, class_, allowed_interface, allowed_attributes) = self.args required = {} cdict = {} pages = {} for pname, attribute, template in self.pages: if template: cdict[pname] = ViewPageTemplateFile(template) if attribute and attribute != name: cdict[attribute] = cdict[pname] else: if not hasattr(class_, attribute): raise ConfigurationError("Undefined attribute", attribute) attribute = attribute or pname required[pname] = permission pages[pname] = attribute # This should go away, but noone seems to remember what to do. :-( if hasattr(class_, 'publishTraverse'): def publishTraverse(self, request, name, pages=pages, getattr=getattr): if name in pages: return getattr(self, pages[name]) view = queryMultiAdapter((self, request), name=name) if view is not None: return view m = class_.publishTraverse.__get__(self) return m(request, name) else: def publishTraverse(self, request, name, pages=pages, getattr=getattr): if name in pages: return getattr(self, pages[name]) view = queryMultiAdapter((self, request), name=name) if view is not None: return view raise NotFound(self, name, request) cdict['publishTraverse'] = publishTraverse if not hasattr(class_, 'browserDefault'): if self.default or self.pages: default = self.default or self.pages[0][0] cdict['browserDefault'] = ( lambda self, request, default=default: (self, (default, )) ) elif providesCallable(class_): cdict['browserDefault'] = ( lambda self, request: (self, ()) ) if class_ is not None: bases = (class_, simple) else: bases = (simple,) try: cname = str(name) except: cname = "GeneratedClass" cdict['__name__'] = name newclass = type(cname, bases, cdict) for n in ('publishTraverse', 'browserDefault', '__call__'): required[n] = permission _handle_allowed_interface(_context, allowed_interface, permission, required) _handle_allowed_attributes(_context, allowed_attributes, permission, required) _handle_for(_context, for_) defineChecker(newclass, Checker(required)) if self.provides is not None: _context.action( discriminator = None, callable = provideInterface, args = ('', self.provides) ) _context.action( discriminator = ('view', (for_, layer), name, self.provides), callable = handler, args = ('registerAdapter', newclass, (for_, layer), self.provides, name, _context.info), ) def _handle_menu(_context, menu, title, for_, name, permission, layer=IDefaultBrowserLayer): if menu or title: if not (menu and title): raise ConfigurationError( "If either menu or title are specified, they must " "both be specified.") if len(for_) != 1: raise ConfigurationError( "Menus can be specified only for single-view, not for " "multi-views.") if menuItemDirective is None: import warnings warnings.warn_explicit( 'Page directive used with "menu" argument, while "zope.browsermenu" ' 'package is not installed. Doing nothing.', UserWarning, _context.info.file, _context.info.line) return [] return menuItemDirective( _context, menu, for_[0], '@@' + name, title, permission=permission, layer=layer) return [] def _handle_permission(_context, permission): if permission == 'zope.Public': permission = CheckerPublic return permission def _handle_allowed_interface(_context, allowed_interface, permission, required): # Allow access for all names defined by named interfaces if allowed_interface: for i in allowed_interface: _context.action( discriminator = None, callable = provideInterface, args = (None, i) ) for name in i: required[name] = permission def _handle_allowed_attributes(_context, allowed_attributes, permission, required): # Allow access for all named attributes if allowed_attributes: for name in allowed_attributes: required[name] = permission def _handle_for(_context, for_): if for_ is not None: _context.action( discriminator = None, callable = provideInterface, args = ('', for_) ) @implementer(IBrowserPublisher) class simple(BrowserView): def publishTraverse(self, request, name): raise NotFound(self, name, request) def __call__(self, *a, **k): # If a class doesn't provide it's own call, then get the attribute # given by the browser default. attr = self.__page_attribute__ if attr == '__call__': raise AttributeError("__call__") meth = getattr(self, attr) return meth(*a, **k) def providesCallable(class_): if hasattr(class_, '__call__'): for c in class_.__mro__: if '__call__' in c.__dict__: return True return False def expressiontype(_context, name, handler): _context.action( discriminator = ("tales:expressiontype", name), callable = registerType, args = (name, handler) ) def registerType(name, handler): Engine.registerType(name, handler) TrustedEngine.registerType(name, handler) def clear(): Engine.__init__() _Engine(Engine) TrustedEngine.__init__() _TrustedEngine(TrustedEngine) try: from zope.testing.cleanup import addCleanUp except ImportError: pass else: addCleanUp(clear) zope.browserpage-4.0.0/src/zope/browserpage/namedtemplate.py0000664000175000017500000000427711775027036024215 0ustar tseavertseaver############################################################################## # # Copyright (c) 2005-2009 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """ """ from zope import component, interface import zope.traversing.interfaces class INamedTemplate(interface.Interface): """A template that is looked up by name """ class NamedTemplateImplementation: def __init__(self, descriptor, view_type=None): try: descriptor.__get__ except AttributeError: raise TypeError( "NamedTemplateImplementation must be passed a descriptor." ) self.descriptor = descriptor interface.implementer(INamedTemplate)(self) if view_type is not None: component.adapter(view_type)(self) def __call__(self, instance): return self.descriptor.__get__(instance, instance.__class__) class implementation: def __init__(self, view_type=None): self.view_type = view_type def __call__(self, descriptor): return NamedTemplateImplementation(descriptor, self.view_type) class NamedTemplate(object): def __init__(self, name): self.__name__ = name def __get__(self, instance, type=None): if instance is None: return self return component.getAdapter(instance, INamedTemplate, self.__name__) def __call__(self, instance, *args, **kw): self.__get__(instance)(*args, **kw) # TODO need test @interface.implementer(zope.traversing.interfaces.IPathAdapter) class NamedTemplatePathAdapter(object): def __init__(self, context): self.context = context def __getitem__(self, name): return component.getAdapter(self.context, INamedTemplate, name) zope.browserpage-4.0.0/src/zope/browserpage/configure.zcml0000664000175000017500000000120111775027036023653 0ustar tseavertseaver zope.browserpage-4.0.0/src/zope/browserpage/__init__.py0000664000175000017500000000010611775027036023117 0ustar tseavertseaverfrom zope.browserpage.viewpagetemplatefile import ViewPageTemplateFilezope.browserpage-4.0.0/src/zope.browserpage.egg-info/0000775000175000017500000000000011775027151022500 5ustar tseavertseaverzope.browserpage-4.0.0/src/zope.browserpage.egg-info/namespace_packages.txt0000664000175000017500000000000511775027151027026 0ustar tseavertseaverzope zope.browserpage-4.0.0/src/zope.browserpage.egg-info/PKG-INFO0000664000175000017500000000660711775027151023606 0ustar tseavertseaverMetadata-Version: 1.0 Name: zope.browserpage Version: 4.0.0 Summary: ZCML directives for configuring browser views for Zope. Home-page: http://pypi.python.org/pypi/zope.browserpage/ Author: Zope Foundation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: ======== Overview ======== *This package is at present not reusable without depending on a large chunk of the Zope Toolkit and its assumptions. It is maintained by the* `Zope Toolkit project `_. This package provides ZCML directives for configuring browser views. More specifically it defines the following ZCML directives: * browser:page * browser:pages * browser:view These directives also support menu item registration for pages, when ``zope.browsermenu`` package is installed. Otherwise, they simply ignore the menu attribute. ======= CHANGES ======= 4.0.0 (2012-07-04) =================== - When registering views, no longer pass the deprecated 'layer' agrument to ``zope.component.registerAdapter``. Instead, pass ``(for_, layer)`` as expected (forward-compatibility with ``zope.component`` 4.0.0). - Replaced deprecated ``zope.interface.implements`` usage with equivalent ``zope.interface.implementer`` decorator. - Dropped support for Python 2.4 and 2.5. 3.12.2 (2010-05-24) =================== - Fixed unit tests broken under Python 2.4 by the switch to the standard library ``doctest`` module. 3.12.1 (2010-04-30) =================== - Prefer the standard library's ``doctest`` module to the one from ``zope.testing``. 3.12.0 (2010-04-26) =================== - Move the implementation of ``tales:expressiontype`` here from ``zope.app.pagetemplate``. 3.11.0 (2009-12-22) =================== - Move the named template implementation here from ``zope.app.pagetemplate``. 3.10.1 (2009-12-22) =================== - Depend on the ``untrustedpython`` extra of ``zope.security``, since we import from ``zope.pagetemplate.engine``. 3.10.0 (2009-12-22) =================== - Remove the dependency on ``zope.app.pagetemplate`` by moving ``viewpagetemplatefile``, ``simpleviewclass`` and ``metaconfigure.registerType`` into this package. 3.9.0 (2009-08-27) ================== - Initial release. This package was split off from ``zope.app.publisher``. Platform: UNKNOWN Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Zope Public License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP Classifier: Framework :: Zope3 zope.browserpage-4.0.0/src/zope.browserpage.egg-info/not-zip-safe0000664000175000017500000000000111775027120024722 0ustar tseavertseaver zope.browserpage-4.0.0/src/zope.browserpage.egg-info/requires.txt0000664000175000017500000000034111775027151025076 0ustar tseavertseaversetuptools zope.pagetemplate zope.component>=3.7 zope.configuration zope.interface zope.publisher>=3.8 zope.schema zope.security [untrustedpython] zope.traversing [test] zope.testing zope.browsermenu [menu] zope.browsermenuzope.browserpage-4.0.0/src/zope.browserpage.egg-info/SOURCES.txt0000664000175000017500000000267511775027151024376 0ustar tseavertseaverCHANGES.txt COPYRIGHT.txt LICENSE.txt README.txt bootstrap.py buildout.cfg setup.py src/zope/__init__.py src/zope.browserpage.egg-info/PKG-INFO src/zope.browserpage.egg-info/SOURCES.txt src/zope.browserpage.egg-info/dependency_links.txt src/zope.browserpage.egg-info/namespace_packages.txt src/zope.browserpage.egg-info/not-zip-safe src/zope.browserpage.egg-info/requires.txt src/zope.browserpage.egg-info/top_level.txt src/zope/browserpage/__init__.py src/zope/browserpage/configure.zcml src/zope/browserpage/meta.zcml src/zope/browserpage/metaconfigure.py src/zope/browserpage/metadirectives.py src/zope/browserpage/namedtemplate.py src/zope/browserpage/namedtemplate.txt src/zope/browserpage/simpleviewclass.py src/zope/browserpage/viewpagetemplatefile.py src/zope/browserpage/tests/__init__.py src/zope/browserpage/tests/namedtemplate.pt src/zope/browserpage/tests/sample.py src/zope/browserpage/tests/simpletestview.py src/zope/browserpage/tests/test.pt src/zope/browserpage/tests/test_boundpagetemplate.py src/zope/browserpage/tests/test_expressiontype.py src/zope/browserpage/tests/test_namedtemplate.py src/zope/browserpage/tests/test_page.py src/zope/browserpage/tests/test_simpleviewclass.py src/zope/browserpage/tests/test_viewzpt.py src/zope/browserpage/tests/testsimpleviewclass.pt src/zope/browserpage/tests/testxml.pt src/zope/browserpage/tests/testfiles/test.pt src/zope/browserpage/tests/testfiles/test2.pt src/zope/browserpage/tests/testfiles/test3.ptzope.browserpage-4.0.0/src/zope.browserpage.egg-info/top_level.txt0000664000175000017500000000000511775027151025225 0ustar tseavertseaverzope zope.browserpage-4.0.0/src/zope.browserpage.egg-info/dependency_links.txt0000664000175000017500000000000111775027151026546 0ustar tseavertseaver zope.browserpage-4.0.0/README.txt0000664000175000017500000000107611775027036016427 0ustar tseavertseaver======== Overview ======== *This package is at present not reusable without depending on a large chunk of the Zope Toolkit and its assumptions. It is maintained by the* `Zope Toolkit project `_. This package provides ZCML directives for configuring browser views. More specifically it defines the following ZCML directives: * browser:page * browser:pages * browser:view These directives also support menu item registration for pages, when ``zope.browsermenu`` package is installed. Otherwise, they simply ignore the menu attribute. zope.browserpage-4.0.0/setup.cfg0000664000175000017500000000007311775027151016544 0ustar tseavertseaver[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 zope.browserpage-4.0.0/COPYRIGHT.txt0000664000175000017500000000004011775027036017030 0ustar tseavertseaverZope Foundation and Contributorszope.browserpage-4.0.0/PKG-INFO0000664000175000017500000000660711775027151016031 0ustar tseavertseaverMetadata-Version: 1.0 Name: zope.browserpage Version: 4.0.0 Summary: ZCML directives for configuring browser views for Zope. Home-page: http://pypi.python.org/pypi/zope.browserpage/ Author: Zope Foundation and Contributors Author-email: zope-dev@zope.org License: ZPL 2.1 Description: ======== Overview ======== *This package is at present not reusable without depending on a large chunk of the Zope Toolkit and its assumptions. It is maintained by the* `Zope Toolkit project `_. This package provides ZCML directives for configuring browser views. More specifically it defines the following ZCML directives: * browser:page * browser:pages * browser:view These directives also support menu item registration for pages, when ``zope.browsermenu`` package is installed. Otherwise, they simply ignore the menu attribute. ======= CHANGES ======= 4.0.0 (2012-07-04) =================== - When registering views, no longer pass the deprecated 'layer' agrument to ``zope.component.registerAdapter``. Instead, pass ``(for_, layer)`` as expected (forward-compatibility with ``zope.component`` 4.0.0). - Replaced deprecated ``zope.interface.implements`` usage with equivalent ``zope.interface.implementer`` decorator. - Dropped support for Python 2.4 and 2.5. 3.12.2 (2010-05-24) =================== - Fixed unit tests broken under Python 2.4 by the switch to the standard library ``doctest`` module. 3.12.1 (2010-04-30) =================== - Prefer the standard library's ``doctest`` module to the one from ``zope.testing``. 3.12.0 (2010-04-26) =================== - Move the implementation of ``tales:expressiontype`` here from ``zope.app.pagetemplate``. 3.11.0 (2009-12-22) =================== - Move the named template implementation here from ``zope.app.pagetemplate``. 3.10.1 (2009-12-22) =================== - Depend on the ``untrustedpython`` extra of ``zope.security``, since we import from ``zope.pagetemplate.engine``. 3.10.0 (2009-12-22) =================== - Remove the dependency on ``zope.app.pagetemplate`` by moving ``viewpagetemplatefile``, ``simpleviewclass`` and ``metaconfigure.registerType`` into this package. 3.9.0 (2009-08-27) ================== - Initial release. This package was split off from ``zope.app.publisher``. Platform: UNKNOWN Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Zope Public License Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Operating System :: OS Independent Classifier: Topic :: Internet :: WWW/HTTP Classifier: Framework :: Zope3 zope.browserpage-4.0.0/bootstrap.py0000664000175000017500000000733011775027036017317 0ustar tseavertseaver############################################################################## # # Copyright (c) 2006 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """Bootstrap a buildout-based project Simply run this script in a directory containing a buildout.cfg. The script accepts buildout command-line options, so you can use the -c option to specify an alternate configuration file. """ import os, shutil, sys, tempfile, urllib2 from optparse import OptionParser tmpeggs = tempfile.mkdtemp() is_jython = sys.platform.startswith('java') # parsing arguments parser = OptionParser() parser.add_option("-v", "--version", dest="version", help="use a specific zc.buildout version") parser.add_option("-d", "--distribute", action="store_true", dest="distribute", default=False, help="Use Disribute rather than Setuptools.") parser.add_option("-c", None, action="store", dest="config_file", help=("Specify the path to the buildout configuration " "file to be used.")) options, args = parser.parse_args() # if -c was provided, we push it back into args for buildout' main function if options.config_file is not None: args += ['-c', options.config_file] if options.version is not None: VERSION = '==%s' % options.version else: VERSION = '' USE_DISTRIBUTE = options.distribute args = args + ['bootstrap'] to_reload = False try: import pkg_resources if not hasattr(pkg_resources, '_distribute'): to_reload = True raise ImportError except ImportError: ez = {} if USE_DISTRIBUTE: exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py' ).read() in ez ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True) else: exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' ).read() in ez ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) if to_reload: reload(pkg_resources) else: import pkg_resources if sys.platform == 'win32': def quote(c): if ' ' in c: return '"%s"' % c # work around spawn lamosity on windows else: return c else: def quote (c): return c cmd = 'from setuptools.command.easy_install import main; main()' ws = pkg_resources.working_set if USE_DISTRIBUTE: requirement = 'distribute' else: requirement = 'setuptools' if is_jython: import subprocess assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', quote(tmpeggs), 'zc.buildout' + VERSION], env=dict(os.environ, PYTHONPATH= ws.find(pkg_resources.Requirement.parse(requirement)).location ), ).wait() == 0 else: assert os.spawnle( os.P_WAIT, sys.executable, quote (sys.executable), '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION, dict(os.environ, PYTHONPATH= ws.find(pkg_resources.Requirement.parse(requirement)).location ), ) == 0 ws.add_entry(tmpeggs) ws.require('zc.buildout' + VERSION) import zc.buildout.buildout zc.buildout.buildout.main(args) shutil.rmtree(tmpeggs) zope.browserpage-4.0.0/LICENSE.txt0000664000175000017500000000402611775027036016552 0ustar tseavertseaverZope Public License (ZPL) Version 2.1 A copyright notice accompanies this license document that identifies the copyright holders. This license has been certified as open source. It has also been designated as GPL compatible by the Free Software Foundation (FSF). Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the accompanying copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Names of the copyright holders must not be used to endorse or promote products derived from this software without prior written permission from the copyright holders. 4. The right to distribute this software or to use it for any purpose does not give you the right to use Servicemarks (sm) or Trademarks (tm) of the copyright holders. Use of them is covered by separate agreement with the copyright holders. 5. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. Disclaimer THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. zope.browserpage-4.0.0/setup.py0000664000175000017500000000470411775027036016444 0ustar tseavertseaver############################################################################## # # Copyright (c) 2007 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## """zope.browserpage setup """ from setuptools import setup, find_packages long_description = (open('README.txt').read() + '\n\n' + open('CHANGES.txt').read()) setup(name='zope.browserpage', version = '4.0.0', url='http://pypi.python.org/pypi/zope.browserpage/', author='Zope Foundation and Contributors', author_email='zope-dev@zope.org', classifiers = ['Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: Zope Public License', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Operating System :: OS Independent', 'Topic :: Internet :: WWW/HTTP', 'Framework :: Zope3', ], description='ZCML directives for configuring browser views for Zope.', long_description=long_description, license='ZPL 2.1', packages=find_packages('src'), package_dir={'': 'src'}, namespace_packages=['zope'], include_package_data=True, install_requires=['setuptools', 'zope.pagetemplate', 'zope.component>=3.7', 'zope.configuration', 'zope.interface', 'zope.publisher>=3.8', 'zope.schema', 'zope.security [untrustedpython]', 'zope.traversing', ], extras_require={ 'menu': ['zope.browsermenu'], 'test': ['zope.testing', 'zope.browsermenu'], }, zip_safe = False, ) zope.browserpage-4.0.0/buildout.cfg0000664000175000017500000000061611775027036017240 0ustar tseavertseaver[buildout] develop = . parts = test coverage-test coverage-report [test] recipe = zc.recipe.testrunner eggs = zope.browserpage [test] [coverage-test] recipe = zc.recipe.testrunner eggs = zope.browserpage [test] defaults = ['--coverage', '../../coverage'] [coverage-report] recipe = zc.recipe.egg eggs = z3c.coverage scripts = coverage=coverage-report arguments = ('coverage', 'coverage/report') zope.browserpage-4.0.0/CHANGES.txt0000664000175000017500000000266611775027036016550 0ustar tseavertseaver======= CHANGES ======= 4.0.0 (2012-07-04) =================== - When registering views, no longer pass the deprecated 'layer' agrument to ``zope.component.registerAdapter``. Instead, pass ``(for_, layer)`` as expected (forward-compatibility with ``zope.component`` 4.0.0). - Replaced deprecated ``zope.interface.implements`` usage with equivalent ``zope.interface.implementer`` decorator. - Dropped support for Python 2.4 and 2.5. 3.12.2 (2010-05-24) =================== - Fixed unit tests broken under Python 2.4 by the switch to the standard library ``doctest`` module. 3.12.1 (2010-04-30) =================== - Prefer the standard library's ``doctest`` module to the one from ``zope.testing``. 3.12.0 (2010-04-26) =================== - Move the implementation of ``tales:expressiontype`` here from ``zope.app.pagetemplate``. 3.11.0 (2009-12-22) =================== - Move the named template implementation here from ``zope.app.pagetemplate``. 3.10.1 (2009-12-22) =================== - Depend on the ``untrustedpython`` extra of ``zope.security``, since we import from ``zope.pagetemplate.engine``. 3.10.0 (2009-12-22) =================== - Remove the dependency on ``zope.app.pagetemplate`` by moving ``viewpagetemplatefile``, ``simpleviewclass`` and ``metaconfigure.registerType`` into this package. 3.9.0 (2009-08-27) ================== - Initial release. This package was split off from ``zope.app.publisher``.