[Zope3-checkins] CVS: Zope3/src/zope/app/publisher/browser - __init__.py:1.2 configure.zcml:1.2 fileresource.py:1.2 globalbrowsermenuservice.py:1.2 i18nfileresource.py:1.2 i18nresourcemeta.py:1.2 meta.zcml:1.2 metaconfigure.py:1.2 resource.py:1.2 resourcemeta.py:1.2 resources.py:1.2 viewmeta.py:1.2
Jim Fulton
jim@zope.com
Wed, 25 Dec 2002 09:14:11 -0500
Update of /cvs-repository/Zope3/src/zope/app/publisher/browser
In directory cvs.zope.org:/tmp/cvs-serv15352/src/zope/app/publisher/browser
Added Files:
__init__.py configure.zcml fileresource.py
globalbrowsermenuservice.py i18nfileresource.py
i18nresourcemeta.py meta.zcml metaconfigure.py resource.py
resourcemeta.py resources.py viewmeta.py
Log Message:
Grand renaming:
- Renamed most files (especially python modules) to lower case.
- Moved views and interfaces into separate hierarchies within each
project, where each top-level directory under the zope package
is a separate project.
- Moved everything to src from lib/python.
lib/python will eventually go away. I need access to the cvs
repository to make this happen, however.
There are probably some bits that are broken. All tests pass
and zope runs, but I haven't tried everything. There are a number
of cleanups I'll work on tomorrow.
=== Zope3/src/zope/app/publisher/browser/__init__.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:10 2002
+++ Zope3/src/zope/app/publisher/browser/__init__.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,2 @@
+#
+# This file is necessary to make this directory a package.
=== Zope3/src/zope/app/publisher/browser/configure.zcml 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:10 2002
+++ Zope3/src/zope/app/publisher/browser/configure.zcml Wed Dec 25 09:13:09 2002
@@ -0,0 +1,39 @@
+<zopeConfigure
+ xmlns='http://namespaces.zope.org/zope'
+ xmlns:browser='http://namespaces.zope.org/browser'
+>
+
+
+<serviceType id="BrowserMenu"
+ interface="zope.app.interfaces.publisher.browser.IBrowserMenuService" />
+<service serviceType="BrowserMenu"
+ permission="zope.Public"
+ component="zope.app.publisher.browser.globalbrowsermenuservice.globalBrowserMenuService" />
+
+
+<content class="zope.publisher.browser.BrowserRequest">
+ <allow
+ interface="zope.publisher.interfaces.browser.IBrowserApplicationRequest" />
+ <allow
+ interface="zope.component.interfaces.IPresentationRequest" />
+</content>
+
+<content class="zope.app.publisher.browser.fileresource.FileResource">
+ <allow interface="zope.publisher.interfaces.browser.IBrowserPublisher" />
+ <allow attributes="GET HEAD __call__" />
+</content>
+
+<content class="zope.app.publisher.browser.i18nfileresource.I18nFileResource">
+ <allow interface="zope.publisher.interfaces.browser.IBrowserPublisher" />
+ <allow attributes="GET HEAD __call__" />
+</content>
+
+
+<browser:view name=""
+ factory="zope.app.publisher.browser.resources.Resources"
+ for="zope.app.interfaces.services.service.IServiceManagerContainer"
+ permission="zope.Public"
+ allowed_interface="zope.publisher.interfaces.browser.IBrowserPublisher"
+ />
+
+</zopeConfigure>
=== Zope3/src/zope/app/publisher/browser/fileresource.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:10 2002
+++ Zope3/src/zope/app/publisher/browser/fileresource.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,128 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__metaclass__ = type # All classes are new style when run with Python 2.2+
+
+from zope.exceptions import NotFoundError
+
+from zope.publisher.browser import BrowserView
+from zope.publisher.interfaces.browser import IBrowserResource
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from zope.app.publisher.fileresource import File, Image
+from zope.app.publisher.browser.resource import Resource
+from zope.app.datetimeutils import time as timeFromDateTimeString
+
+from zope.security.proxy import ProxyFactory
+
+class FileResource(BrowserView, Resource):
+
+ __implements__ = IBrowserResource, IBrowserPublisher
+
+ def publishTraverse(self, request, name):
+ '''See interface IBrowserPublisher'''
+ raise NotFoundError(name)
+
+ def browserDefault(self, request):
+ '''See interface IBrowserPublisher'''
+ method = request.get('REQUEST_METHOD', 'GET').upper()
+ return getattr(self, method), ()
+
+ #
+ ############################################################
+
+ # for unit tests
+ def _testData(self):
+ file = self.chooseContext()
+ f=open(self.context.path,'rb')
+ data=f.read()
+ f.close()
+ return data
+
+
+ def chooseContext(self):
+ """Choose the appropriate context"""
+ return self.context
+
+
+ def GET(self):
+ """Default document"""
+
+ file = self.chooseContext()
+ request = self.request
+ response = request.response
+
+ # HTTP If-Modified-Since header handling. This is duplicated
+ # from OFS.Image.Image - it really should be consolidated
+ # somewhere...
+ header = request.getHeader('If-Modified-Since', None)
+ if header is not None:
+ header = header.split(';')[0]
+ # Some proxies seem to send invalid date strings for this
+ # header. If the date string is not valid, we ignore it
+ # rather than raise an error to be generally consistent
+ # with common servers such as Apache (which can usually
+ # understand the screwy date string as a lucky side effect
+ # of the way they parse it).
+ try: mod_since=long(timeFromDateTimeString(header))
+ except: mod_since=None
+ if mod_since is not None:
+ if getattr(file, 'lmt', None):
+ last_mod = long(file.lmt)
+ else:
+ last_mod = long(0)
+ if last_mod > 0 and last_mod <= mod_since:
+ response.setStatus(304)
+ return ''
+
+ response.setHeader('Content-Type', file.content_type)
+ response.setHeader('Last-Modified', file.lmh)
+
+ # Cache for one day
+ response.setHeader('Cache-Control', 'public,max-age=86400')
+ f=open(file.path,'rb')
+ data=f.read()
+ f.close()
+
+ return data
+
+ def HEAD(self):
+ file = self.chooseContext()
+ response = self.request.response
+ response = self.request.response
+ response.setHeader('Content-Type', file.content_type)
+ response.setHeader('Last-Modified', file.lmh)
+ # Cache for one day
+ response.setHeader('Cache-Control', 'public,max-age=86400')
+ return ''
+
+
+class FileResourceFactory:
+
+ def __init__(self, path):
+ self.__file = File(path)
+
+ def __call__(self, request):
+ return ProxyFactory(FileResource(self.__file, request))
+
+class ImageResourceFactory:
+
+ def __init__(self, path):
+ self.__file = Image(path)
+
+ def __call__(self, request):
+ return ProxyFactory(FileResource(self.__file, request))
=== Zope3/src/zope/app/publisher/browser/globalbrowsermenuservice.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/globalbrowsermenuservice.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,178 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.app.interfaces.publisher.browser import IBrowserMenuService
+from zope.interfaces.configuration import INonEmptyDirective
+from zope.interfaces.configuration import ISubdirectiveHandler
+from zope.configuration.action import Action
+from zope.interface.type import TypeRegistry
+from zope.exceptions import DuplicationError, Unauthorized, Forbidden
+from zope.app.pagetemplate.engine import Engine
+from zope.app.publication.browser \
+ import PublicationTraverser
+from zope.app.component.metaconfigure import handler
+
+class GlobalBrowserMenuService:
+ """Global Browser Menu Service
+ """
+
+ __implements__ = IBrowserMenuService
+
+ def __init__(self):
+ self._registry = {}
+
+ _clear = __init__
+
+ def menu(self, menu_id, title, description=''):
+ # XXX we have nothing to do with the title and description. ;)
+
+ if menu_id in self._registry:
+ raise DuplicationError("Menu %s is already defined." % menu_id)
+
+ self._registry[menu_id] = TypeRegistry()
+
+ def menuItem(self, menu_id, interface,
+ action, title, description='', filter_string=None):
+
+ registry = self._registry[menu_id]
+
+ if filter_string:
+ filter = Engine.compile(filter_string)
+ else:
+ filter = None
+
+ data = registry.get(interface) or []
+ data.append((action, title, description, filter))
+ registry.register(interface, data)
+
+ def getMenu(self, menu_id, object, request, max=999999):
+ registry = self._registry[menu_id]
+ traverser = PublicationTraverser()
+
+ result = []
+ seen = {}
+
+ for items in registry.getAllForObject(object):
+ for action, title, description, filter in items:
+
+ # Make sure we don't repeat a specification for a given title
+ if title in seen:
+ continue
+ seen[title] = 1
+
+ if filter is not None:
+
+ try:
+ include = filter(Engine.getContext(
+ context = object,
+ nothing = None))
+ except Unauthorized:
+ include = 0
+
+ if not include:
+ continue
+
+ if action:
+ try:
+ v = traverser.traverseRelativeURL(
+ request, object, action)
+ # XXX
+ # tickle the security proxy's checker
+ # we're assuming that view pages are callable
+ # this is a pretty sound assumption
+ v.__call__
+ except (Unauthorized, Forbidden):
+ continue # Skip unauthorized or forbidden
+
+ if request.getURL().endswith(action):
+ selected='selected'
+ else:
+ selected=''
+
+ result.append({
+ 'title': title,
+ 'description': description,
+ 'action': "%s" % action,
+ 'selected': selected
+ })
+
+ if len(result) >= max:
+ return result
+
+ return result
+
+ def getFirstMenuItem(self, menu_id, object, request):
+ r = self.getMenu(menu_id, object, request, max=1)
+ if r:
+ return r[0]
+ return None
+
+def menuDirective(_context, id, title, description=''):
+ return [Action(
+ discriminator = ('browser:menu', id),
+ callable = globalBrowserMenuService.menu,
+ args = (id, title, description),
+ )]
+
+def menuItemDirective(_context, menu, for_,
+ action, title, description='', filter=None):
+ return menuItemsDirective(_context, menu, for_).menuItem(
+ _context, action, title, description, filter)
+
+
+class menuItemsDirective:
+
+ __class_implements__ = INonEmptyDirective
+ __implements__ = ISubdirectiveHandler
+
+ def __init__(self, _context, menu, for_):
+ self.menu = menu
+ self.interface = _context.resolve(for_)
+
+ def menuItem(self, _context, action, title, description='', filter=None):
+ return [
+ Action(
+ discriminator = ('browser:menuItem',
+ self.menu, self.interface, title),
+ callable = globalBrowserMenuService.menuItem,
+ args = (self.menu, self.interface,
+ action, title, description, filter),
+ ),
+ ]
+
+ def __call__(self):
+ return [
+ Action(
+ discriminator = None,
+ callable = handler,
+ args = ('Interfaces', 'provideInterface',
+ self.interface.__module__+'.'+self.interface.__name__,
+ self.interface)
+ )
+ ]
+
+
+globalBrowserMenuService = GlobalBrowserMenuService()
+
+_clear = globalBrowserMenuService._clear
+
+# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
+from zope.testing.cleanup import addCleanUp
+addCleanUp(_clear)
+del addCleanUp
+
+__doc__ = GlobalBrowserMenuService.__doc__ + """
+
+$Id$
+"""
=== Zope3/src/zope/app/publisher/browser/i18nfileresource.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/i18nfileresource.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,94 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+Internationalized file resource.
+
+$Id$
+"""
+__metaclass__ = type # All classes are new style when run with Python 2.2+
+
+from zope.publisher.interfaces.browser import IBrowserResource
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from zope.app.publisher.fileresource import File, Image
+
+from zope.app.publisher.browser.fileresource import FileResource
+
+from zope.i18n.negotiator import negotiator
+from zope.interfaces.i18n import II18nAware
+
+
+class I18nFileResource(FileResource):
+
+ __implements__ = IBrowserResource, IBrowserPublisher, II18nAware
+
+ def __init__(self, data, request, defaultLanguage='en'):
+ """Creates an internationalized file resource. data should be
+ a mapping from languages to File or Image objects.
+ """
+ self._data = data
+ self.request = request
+ self.defaultLanguage = defaultLanguage
+
+
+ def chooseContext(self):
+ """Choose the appropriate context according to language"""
+ langs = self.getAvailableLanguages()
+ language = negotiator.getLanguage(langs, self.request)
+ try:
+ return self._data[language]
+ except KeyError:
+ return self._data[self.defaultLanguage]
+
+
+ # for unit tests
+ def _testData(self, language):
+ file = self._data[language]
+ f=open(file.path,'rb')
+ data=f.read()
+ f.close()
+ return data
+
+
+ ############################################################
+ # Implementation methods for interface
+ # II18nAware.py
+
+ def getDefaultLanguage(self):
+ 'See II18nAware'
+ return self.defaultLanguage
+
+ def setDefaultLanguage(self, language):
+ 'See II18nAware'
+ if not self._data.has_key(language):
+ raise ValueError, \
+ 'cannot set nonexistent language (%s) as default' % language
+ self.defaultLanguage = language
+
+ def getAvailableLanguages(self):
+ 'See II18nAware'
+ return self._data.keys()
+
+ #
+ ############################################################
+
+
+class I18nFileResourceFactory:
+
+ def __init__(self, data, defaultLanguage):
+ self.__data = data
+ self.__defaultLanguage = defaultLanguage
+
+ def __call__(self, request):
+ return I18nFileResource(self.__data, request, self.__defaultLanguage)
=== Zope3/src/zope/app/publisher/browser/i18nresourcemeta.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/i18nresourcemeta.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,133 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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 configuration code
+
+$Id$
+"""
+
+from zope.security.proxy import Proxy
+from zope.security.checker \
+ import CheckerPublic, NamesChecker, Checker
+
+from zope.interfaces.configuration import ISubdirectiveHandler
+from zope.interfaces.configuration import INonEmptyDirective
+from zope.configuration.action import Action
+from zope.configuration.exceptions import ConfigurationError
+
+from zope.publisher.interfaces.browser import IBrowserPresentation
+
+from zope.app.component.metaconfigure import handler
+
+from zope.app.publisher.fileresource import File, Image
+from zope.app.publisher.browser.i18nfileresource \
+ import I18nFileResourceFactory
+
+class I18nResource(object):
+
+ __class_implements__ = INonEmptyDirective
+ __implements__ = ISubdirectiveHandler
+
+ type = IBrowserPresentation
+ default_allowed_attributes = '__call__'
+
+ def __init__(self, _context, name=None, defaultLanguage='en',
+ layer='default', permission=None):
+ self.name = name
+ self.defaultLanguage = defaultLanguage
+ self.layer = layer
+ self.permission = permission
+ self.__data = {}
+ self.__format = None
+
+
+ def translation(self, _context, language, file=None, image=None):
+
+ if file is not None and image is not None:
+ raise ConfigurationError(
+ "Can't use more than one of file, and image "
+ "attributes for resource directives"
+ )
+ elif file is not None:
+ if self.__format is not None and self.__format != File:
+ raise ConfigurationError(
+ "Can't use both files and images in the same "
+ "i18n-resource directive"
+ )
+ self.__data[language] = File(_context.path(file))
+ self.__format = File
+ elif image is not None:
+ if self.__format is not None and self.__format != Image:
+ raise ConfigurationError(
+ "Can't use both files and images in the same "
+ "i18n-resource directive"
+ )
+ self.__data[language] = Image(_context.path(image))
+ self.__format = Image
+ else:
+ raise ConfigurationError(
+ "At least one of the file, and image "
+ "attributes for resource directives must be specified"
+ )
+
+ return ()
+
+
+ def __call__(self, require = None):
+ if self.name is None:
+ return ()
+
+ if not self.__data.has_key(self.defaultLanguage):
+ raise ConfigurationError(
+ "A translation for the default language (%s) "
+ "must be specified" % self.defaultLanguage
+ )
+
+ permission = self.permission
+ factory = I18nFileResourceFactory(self.__data, self.defaultLanguage)
+
+ if permission:
+ if require is None:
+ require = {}
+
+ if permission == 'zope.Public':
+ permission = CheckerPublic
+
+ if require:
+ checker = Checker(require.get)
+
+ factory = self._proxyFactory(factory, checker)
+
+ return [
+ Action(
+ discriminator = ('i18n-resource', self.name, self.type,
+ self.layer),
+ callable = handler,
+ args = ('Resources', 'provideResource', self.name, self.type,
+ factory, self.layer)
+ )
+ ]
+
+
+ def _proxyFactory(self, factory, checker):
+ def proxyView(request,
+ factory=factory, checker=checker):
+ resource = factory(request)
+
+ # We need this in case the resource gets unwrapped and
+ # needs to be rewrapped
+ resource.__Security_checker__ = checker
+
+ return Proxy(resource, checker)
+
+ return proxyView
=== Zope3/src/zope/app/publisher/browser/meta.zcml 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/meta.zcml Wed Dec 25 09:13:09 2002
@@ -0,0 +1,302 @@
+<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
+
+ <directives namespace="http://namespaces.zope.org/browser">
+
+ <directive
+ name="view"
+ handler="zope.app.publisher.browser.metaconfigure.view" >
+ <attribute
+ name="name"
+ description="The name of the view.
+
+ 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." />
+ <attribute
+ name="for"
+ description="The interface this view applies to.
+
+ The view will be for all objects that implement this interface.
+ If 'for' is not supplied, the view applies to all objects
+ (XXX this ought to change)." />
+ <attribute
+ name="factory"
+ description="A callable that realizes the view.
+
+ The view factory interface is documented in IViewFactory. View
+ factories are passed two arguments, the context object
+ and the request object. You must specify either 'factory' or
+ 'template'. If it not allowed to use 'class' when you use
+ the 'factory' attribute. Attributes of the view can be exposed
+ as pages with the 'page' subdirective." />
+ <attribute
+ name="template"
+ description="The name of a page template.
+
+ Refers to a file containing a page template (must end in
+ extension '.pt'). You must specify either 'template' or
+ 'factory'. If you supply a template, you must
+ also supply a name. You can also optionally supply a
+ 'class' attribute which contains a view class that has
+ methods that can be used by the template.
+
+ You cannot have sub pages if you use 'template'." />
+ <attribute
+ name="class"
+ description="A class to use with the template.
+
+ If you use the 'template' attribute you can optionally use
+ the 'class' attribute. This should point to a class that
+ provides methods that can be used in the template. This class
+ will be mixed in with the page template. From the template
+ you can refer to the methods using 'view/method_name'.
+
+ You cannot use the 'class' attribute in combination with the
+ 'factory' attribute." />
+ <attribute
+ name="permission"
+ description="The permission needed to use the view.
+
+ This attribute is required." />
+ <attribute
+ name="layer"
+ description="The layer the view is in.
+
+ A skin is composed of layers. It is common to put skin specific
+ views in a layer named after the skin. If the 'layer' attribute
+ is not supplied, it defaults to 'default'." />
+ <attribute
+ name="allowed_interface"
+ description="Interface that is also allowed if user has permission.
+
+ By default, 'permission' only applies to viewing the view and
+ any possible sub views. By specifying this attribute, you can
+ make the permission also apply to everything described in the
+ supplied interface." />
+ <attribute
+ name="allowed_attributes"
+ description="View attributes that are also allowed if user has permission.
+
+ By default, 'permission' only applies to viewing the view and any
+ possible sub views. By specifying 'allowed_attributes', you can
+ make the permission also apply to the extra attributes on the
+ view object." />
+ <subdirective name="page">
+ <attribute
+ name="name"
+ description="The name of a sub page of a view.
+
+ The name attribute is always required for the 'page'
+ directive. It is common to use an extension for the name,
+ such as '.html'." />
+ <attribute
+ name="attribute"
+ description="The name of the view attribute implementing the page.
+
+ This refers to the attribute (method) on the view that is
+ implementing a specific sub page." />
+ <attribute
+ name="permission"
+ description="The permission needed to use this page.
+
+ XXX Should we deprecate this? Could always be the same as
+ the main view." />
+ <attribute
+ name="layer"
+ description="XXX deprecated" />
+ </subdirective>
+ <subdirective name="defaultPage">
+ <attribute
+ name="name"
+ description="The name of the page that is the default.
+
+ 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." />
+ <attribute
+ name="attribute"
+ description="XXX deprecated" />
+ <attribute
+ name="permission"
+ description="XXX deprecated" />
+ </subdirective>
+ </directive>
+
+ <directive
+ name="defaultView"
+ handler="zope.app.publisher.browser.metaconfigure.defaultView">
+ <attribute
+ name="name"
+ description="The name of the view that should be the default.
+
+ This name refers to another view that should be the
+ view used by default (if no view name is supplied
+ explicitly)." />
+ <attribute
+ name="for"
+ description="The interface this view is the default for.
+
+ The view is the default view for the supplied interface." />
+ <attribute
+ name="layer"
+ description="The layer the named view is the default view.
+
+ The named view is only the default view in the supplied
+ layer" />
+ <attribute
+ name="factory"
+ description="XXX deprecated" />
+ <attribute
+ name="template"
+ description="XXX deprecated" />
+ <attribute
+ name="permission"
+ description="XXX deprecated" />
+ <attribute
+ name="allowed_interface"
+ description="XXX deprecated" />
+ <attribute
+ name="allowed_attributes"
+ description="XXX deprecated" />
+ </directive>
+
+ <directive
+ name="resource"
+ handler="zope.app.publisher.browser.metaconfigure.resource">
+ <attribute
+ name="name" />
+ <attribute
+ name="factory" />
+ <attribute
+ name="layer" />
+ <attribute
+ name="file" />
+ <attribute
+ name="image" />
+ <attribute
+ name="permission" />
+ <attribute
+ name="allowed_interface" />
+ <attribute
+ name="allowed_attributes" />
+ <subdirective name="page">
+ <attribute
+ name="name" />
+ <attribute
+ name="attribute" />
+ <attribute
+ name="permission" />
+ <attribute
+ name="layer" />
+ </subdirective>
+ </directive>
+
+ <directive
+ name="i18n-resource"
+ attributes="name default_language"
+ handler="zope.app.publisher.browser.metaconfigure.I18nResource">
+ <attribute
+ name="name" />
+ <attribute
+ name="default_language" />
+ <subdirective name="translation">
+ <attribute
+ name="language" />
+ <attribute
+ name="file" />
+ <attribute
+ name="image" />
+ </subdirective>
+ </directive>
+
+ <directive
+ name="skin"
+ handler="zope.app.publisher.browser.metaconfigure.skin">
+ <attribute
+ name="name"
+ description="The name of the skin." />
+ <attribute
+ name="layers"
+ description="A list of names of layers.
+
+ This should be in order of lookup. Usually one of the layers
+ has the same name as the skin, and the last skin should be
+ 'default', unless you want to completely override all views." />
+ </directive>
+
+ <directive
+ name="menu"
+ handler="
+ zope.app.publisher.browser.globalbrowsermenuservice.menuDirective">
+ <attribute
+ name="name" />
+ <attribute
+ name="title" />
+ <attribute
+ name="description" />
+ </directive>
+
+ <directive
+ name="menuItems"
+ attributes="menu for"
+ handler="
+ zope.app.publisher.browser.globalbrowsermenuservice.menuItemsDirective"
+ >
+ <subdirective
+ name="menuItem"
+ >
+ <attribute
+ name="action" />
+ <attribute
+ name="title" />
+ <attribute
+ name="description" />
+ <attribute
+ name="filter" />
+ </subdirective>
+ </directive>
+
+ <directive
+ name="menuItem"
+ handler="
+ zope.app.publisher.browser.globalbrowsermenuservice.menuItemDirective"
+ >
+ <attribute
+ name="menu" />
+ <attribute
+ name="for" />
+ <attribute
+ name="action" />
+ <attribute
+ name="title" />
+ <attribute
+ name="description" />
+ <attribute
+ name="filter" />
+ </directive>
+
+ <directive
+ name="icon"
+ handler="zope.app.interfaces.publisher.browser.IconDirective"
+ >
+ <attribute
+ name="name" />
+ <attribute
+ name="for" />
+ <attribute
+ name="file" />
+ <attribute
+ name="resource" />
+ <attribute
+ name="alt" />
+ <attribute
+ name="layer" />
+ </directive>
+
+ </directives>
+
+</zopeConfigure>
=== Zope3/src/zope/app/publisher/browser/metaconfigure.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/metaconfigure.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,68 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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 configuration code
+
+$Id$
+"""
+
+from zope.configuration.action import Action
+
+from zope.publisher.interfaces.browser import IBrowserPresentation
+
+from zope.app.component.metaconfigure \
+ import defaultView as _defaultView, skin as _skin, handler
+
+from zope.app.publisher.browser.resourcemeta import resource
+from zope.app.publisher.browser.i18nresourcemeta import I18nResource
+from zope.app.publisher.browser.viewmeta import view
+from zope.interface import Interface
+
+def skin(_context, **__kw):
+ return _skin(_context,
+ type='zope.publisher.interfaces.browser.IBrowserPresentation',
+ **__kw)
+
+def defaultView(_context, name, for_=None, **__kw):
+
+ if __kw:
+ actions = view(_context, name=name, for_=for_, **__kw)()
+ else:
+ actions = []
+
+ if for_ is not None:
+ for_ = _context.resolve(for_)
+
+ type = IBrowserPresentation
+
+ actions += [
+ Action(
+ discriminator = ('defaultViewName', for_, type, name),
+ callable = handler,
+ args = ('Views','setDefaultViewName', for_, type, name),
+ )
+ ]
+ if for_ is not None:
+ actions.append
+ (
+ Action(
+ discriminator = None,
+ callable = handler,
+ args = ('Interfaces', 'provideInterface',
+ for_.__module__+'.'+for_.__name__,
+ for_)
+ )
+ )
+
+
+ return actions
=== Zope3/src/zope/app/publisher/browser/resource.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/resource.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,55 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__metaclass__ = type # All classes are new style when run with Python 2.2+
+
+from zope.component import queryView
+from zope.proxy.context import getWrapperContainer, getInnerWrapperData
+from zope.proxy.context import ContextMethod
+
+class Resource:
+
+ def __init__(self, request):
+ self.request = request
+
+ def __call__(wrapped_self):
+ name = getInnerWrapperData(wrapped_self)['name']
+ if name.startswith('++resource++'):
+ name = name[12:]
+
+ service = getWrapperContainer(wrapped_self)
+ site = getWrapperContainer(service)
+
+ skin = wrapped_self.request.getPresentationSkin()
+ if skin:
+ skin = "++skin++%s/" % skin
+
+ if site is None:
+ return "/%s@@/%s" % (skin, name)
+
+ absolute_url = queryView(service,
+ 'absolute_url',
+ wrapped_self.request)
+
+ if absolute_url is None:
+ return "/%s@@/%s" % (skin, name)
+
+ site_url = absolute_url()
+
+ return "%s/%s@@/%s" % (site_url, skin, name)
+
+ __call__ = ContextMethod(__call__)
=== Zope3/src/zope/app/publisher/browser/resourcemeta.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/resourcemeta.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,193 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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 configuration code
+
+$Id$
+"""
+
+from zope.security.proxy import Proxy
+from zope.security.checker \
+ import CheckerPublic, NamesChecker, Checker
+
+from zope.interfaces.configuration import INonEmptyDirective
+from zope.interfaces.configuration import ISubdirectiveHandler
+from zope.configuration.action import Action
+from zope.configuration.exceptions import ConfigurationError
+
+from zope.publisher.interfaces.browser import IBrowserPresentation
+
+from zope.app.component.metaconfigure import handler
+
+from zope.app.publisher.browser.fileresource \
+ import FileResourceFactory, ImageResourceFactory
+
+class resource(object):
+
+ __class_implements__ = INonEmptyDirective
+ __implements__ = ISubdirectiveHandler
+
+ type = IBrowserPresentation
+ default_allowed_attributes = '__call__' # space separated string
+
+ def __init__(self, _context, factory=None, name=None, layer='default',
+ permission=None,
+ allowed_interface=None, allowed_attributes=None,
+ file=None, image=None):
+
+ if ((allowed_attributes or allowed_interface)
+ and ((name is None) or not permission)):
+ raise ConfigurationError(
+ "Must use name attribute with allowed_interface or "
+ "allowed_attributes"
+ )
+
+ if allowed_interface is not None:
+ allowed_interface = _context.resolve(allowed_interface)
+
+ self.__file = file
+ self.__image = image
+
+ self.factory = self._factory(_context, factory)
+ self.layer = layer
+ self.name = name
+ self.permission = permission
+ self.allowed_attributes = allowed_attributes
+ self.allowed_interface = allowed_interface
+ self.pages = 0
+
+ def _factory(self, _context, factory):
+ if ((factory is not None)
+ + (self.__file is not None)
+ + (self.__image is not None)
+ ) > 1:
+ raise ConfigurationError(
+ "Can't use more than one of factory, file, and image "
+ "attributes for resource directives"
+ )
+
+ if factory is not None:
+ return _context.resolve(factory)
+
+ if self.__file is not None:
+ return FileResourceFactory(_context.path(self.__file))
+
+ if self.__image is not None:
+ return ImageResourceFactory(_context.path(self.__image))
+
+ raise ConfigurationError(
+ "At least one of the factory, file, and image "
+ "attributes for resource directives must be specified"
+ )
+
+
+ def page(self, _context, name, attribute, permission=None,
+ layer=None, factory=None):
+
+ permission = permission or self.permission
+
+ factory = self._pageFactory(factory or self.factory,
+ attribute, permission)
+
+ self.pages += 1
+
+ if layer is None:
+ layer = self.layer
+
+ return [
+ Action(
+ discriminator = self._discriminator(name, layer),
+ callable = handler,
+ args = self._args(name, factory, layer),
+ )
+ ]
+
+ def _discriminator(self, name, layer):
+ return ('resource', name, self.type, layer)
+
+ def _args(self, name, factory, layer):
+ return ('Resources', 'provideResource',
+ name, self.type, factory, layer)
+
+ def _pageFactory(self, factory, attribute, permission):
+ if permission:
+ if permission == 'zope.Public':
+ permission = CheckerPublic
+
+ def pageView(request,
+ factory=factory, attribute=attribute,
+ permission=permission):
+ return Proxy(getattr(factory(request), attribute),
+ NamesChecker(__call__ = permission))
+
+ else:
+
+ def pageView(request,
+ factory=factory, attribute=attribute):
+ return getattr(factory(request), attribute)
+
+ return pageView
+
+ def __call__(self, require=None):
+ if self.name is None:
+ return ()
+
+ permission = self.permission
+ allowed_interface = self.allowed_interface
+ allowed_attributes = self.allowed_attributes
+ factory = self.factory
+
+ if permission:
+ if require is None:
+ require = {}
+
+ if permission == 'zope.Public':
+ permission = CheckerPublic
+
+ if ((not allowed_attributes) and (allowed_interface is None)
+ and (not self.pages)):
+ allowed_attributes = self.default_allowed_attributes
+
+ for name in (allowed_attributes or '').split():
+ require[name] = permission
+
+ if allowed_interface:
+ for name in allowed_interface.names(1):
+ require[name] = permission
+
+ if require:
+ checker = Checker(require.get)
+
+ factory = self._proxyFactory(factory, checker)
+
+
+ return [
+ Action(
+ discriminator = self._discriminator(self.name, self.layer),
+ callable = handler,
+ args = self._args(self.name, factory, self.layer),
+ )
+ ]
+
+ def _proxyFactory(self, factory, checker):
+ def proxyView(request,
+ factory=factory, checker=checker):
+ resource = factory(request)
+
+ # We need this in case the resource gets unwrapped and
+ # needs to be rewrapped
+ resource.__Security_checker__ = checker
+
+ return Proxy(resource, checker)
+
+ return proxyView
=== Zope3/src/zope/app/publisher/browser/resources.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/resources.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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.
+#
+##############################################################################
+"""Resource URL acess
+
+$Id$
+"""
+__metaclass__ = type # All classes are new style when run with Python 2.2+
+
+from zope.publisher.browser import BrowserView
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.component import getService
+from zope.proxy.context import ContextWrapper
+from zope.proxy.context import ContextMethod
+from zope.exceptions import NotFoundError
+
+class Resources(BrowserView):
+ """Provide a URL-accessible resource namespace
+ """
+
+ __implements__ = BrowserView.__implements__, IBrowserPublisher
+
+ def publishTraverse(wrapped_self, request, name):
+ '''See interface IBrowserPublisher'''
+
+ resource_service = getService(wrapped_self, 'Resources')
+ resource = resource_service.queryResource(wrapped_self, name, request)
+ if resource is None:
+ raise NotFoundError(wrapped_self, name)
+ return ContextWrapper(resource, resource_service)
+
+ publishTraverse = ContextMethod(publishTraverse)
+
+ def browserDefault(self, request):
+ '''See interface IBrowserPublisher'''
+ return empty, ()
+
+ #
+ ############################################################
+
+def empty():
+ return ''
=== Zope3/src/zope/app/publisher/browser/viewmeta.py 1.1 => 1.2 ===
--- /dev/null Wed Dec 25 09:14:11 2002
+++ Zope3/src/zope/app/publisher/browser/viewmeta.py Wed Dec 25 09:13:09 2002
@@ -0,0 +1,303 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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 configuration code
+
+$Id$
+"""
+
+# XXX this will need to be refactored soon. :)
+
+from zope.security.proxy import Proxy
+from zope.security.checker import CheckerPublic, NamesChecker
+
+from zope.interfaces.configuration import INonEmptyDirective
+from zope.interfaces.configuration import ISubdirectiveHandler
+from zope.configuration.action import Action
+from zope.configuration.exceptions import ConfigurationError
+
+from zope.publisher.interfaces.browser import IBrowserPresentation
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from zope.app.component.metaconfigure import handler
+
+from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+
+from zope.app.publisher.browser.resourcemeta import resource
+
+from zope.proxy.context import ContextMethod
+
+
+class view(resource):
+
+ __class_implements__ = INonEmptyDirective
+ __implements__ = ISubdirectiveHandler
+
+ __pages = None
+ __default = None
+
+ def __init__(self, _context, factory=None, name=None, for_=None,
+ layer='default',
+ permission=None,
+ allowed_interface=None, allowed_attributes=None,
+ template=None, class_=None):
+
+ if class_ and factory:
+ raise ConfigurationError("Can't specify a class and a factory")
+
+ factory = factory or class_
+
+ if template:
+ if name is None:
+ raise ConfigurationError(
+ "Must specify name for template view")
+
+ self.default_allowed_attributes = (
+ '__call__ __getitem__ browserDefault')
+
+ template = _context.path(template)
+
+ self.template = template
+
+ if for_ is not None:
+ for_ = _context.resolve(for_)
+ self.for_ = for_
+
+ resource.__init__(self, _context, factory, name, layer,
+ permission, allowed_interface, allowed_attributes)
+
+ if name:
+ self.__pages = {}
+
+
+ def page(self, _context, name, attribute=None, permission=None,
+ layer=None, template=None):
+
+ if self.template:
+ raise ConfigurationError(
+ "Can't use page or defaultPage subdirectives for simple "
+ "template views")
+
+ if self.name:
+ # Named view with pages.
+
+ if layer is not None:
+ raise ConfigurationError(
+ "Can't specify a separate layer for pages of named "
+ "templates.")
+
+ if template is not None:
+ template = _context.path(template)
+
+ self.__pages[name] = attribute, permission, template
+ if self.__default is None:
+ self.__default = name
+
+ # Call super(view, self).page() in order to get the side
+ # effects. (At the time of writing, this is to increment
+ # self.pages by one.)
+ # Throw away the result, as all the pages are accessed by
+ # traversing the PageTraverser subclass.
+ super(view, self).page(_context, name, attribute)
+ return ()
+
+ factory = self.factory
+
+ if template is not None:
+ attribute = attribute or '__template__'
+ klass = factory[-1]
+ klass = type(klass.__name__, (klass, object), {
+ attribute:
+ ViewPageTemplateFile(_context.path(template))
+ })
+ factory = factory[:]
+ factory[-1] = klass
+
+ return super(view, self).page(
+ _context, name, attribute, permission, layer,
+ factory=factory)
+
+ def defaultPage(self, _context, name):
+ if self.name:
+ self.__default = name
+ return ()
+
+ return [Action(
+ discriminator = ('defaultViewName', self.for_, self.type, name),
+ callable = handler,
+ args = ('Views','setDefaultViewName', self.for_, self.type, name),
+ )]
+
+
+ def _factory(self, _context, factory):
+ if self.template:
+ if factory:
+ factory = map(_context.resolve, factory.strip().split())
+ bases = (factory[-1], )
+ klass = SimpleViewClass(
+ str(_context.path(self.template)),
+ used_for=self.for_, bases=bases
+ )
+ factory[-1] = klass
+ return factory
+
+ return [SimpleViewClass(
+ str(_context.path(self.template)),
+ used_for = self.for_
+ )]
+ else:
+ return map(_context.resolve, factory.strip().split())
+
+ def _discriminator(self, name, layer):
+ return ('view', self.for_, name, self.type, layer)
+
+ def _args(self, name, factory, layer):
+ return ('Views', 'provideView',
+ self.for_, name, self.type, factory, layer)
+
+ def _pageFactory(self, factory, attribute, permission):
+ factory = factory[:]
+ if permission:
+ if permission == 'zope.Public':
+ permission = CheckerPublic
+
+ def pageView(context, request,
+ factory=factory[-1], attribute=attribute,
+ permission=permission):
+ return Proxy(getattr(factory(context, request), attribute),
+ NamesChecker(__call__ = permission))
+ else:
+ def pageView(context, request,
+ factory=factory[-1], attribute=attribute):
+ return getattr(factory(context, request), attribute)
+ factory[-1] = pageView
+ return factory
+
+ def _proxyFactory(self, factory, checker):
+ factory = factory[:]
+
+ def proxyView(context, request,
+ factory=factory[-1], checker=checker):
+
+ view = factory(context, request)
+
+ # We need this in case the resource gets unwrapped and
+ # needs to be rewrapped
+ view.__Security_checker__ = checker
+
+ return Proxy(view, checker)
+
+ factory[-1] = proxyView
+
+ return factory
+
+ def __call__(self):
+ if not self.__pages:
+ return super(view, self).__call__()
+
+ # OK, we have named pages on a named view.
+ # We'll replace the original class with a new subclass that
+ # can traverse to the necessary pages.
+
+ require = {}
+
+ factory = self.factory[:]
+ klass = factory[-1]
+
+ klassdict = {'_PageTraverser__pages': {},
+ '_PageTraverser__default': self.__default,
+ '__implements__':
+ (klass.__implements__, PageTraverser.__implements__),
+ }
+ for name in self.__pages:
+ attribute, permission, template = self.__pages[name]
+
+ # We need to set the default permission on pages if the pages
+ # don't already have a permission explicitly set
+ permission = permission or self.permission
+ if permission == 'zope.Public':
+ permission = CheckerPublic
+
+ if not attribute:
+ attribute = name
+
+ require[attribute] = permission
+
+ if template:
+ klassdict[attribute] = ViewPageTemplateFile(template)
+
+ klassdict['_PageTraverser__pages'][name] = attribute, permission
+
+ klass = type(klass.__name__,
+ (klass, PageTraverser, object),
+ klassdict)
+ factory[-1] = klass
+ self.factory = factory
+
+ permission_for_browser_publisher = self.permission
+ if permission_for_browser_publisher == 'zope.Public':
+ permission_for_browser_publisher = CheckerPublic
+ for name in IBrowserPublisher.names(all=1):
+ require[name] = permission_for_browser_publisher
+
+ return super(view, self).__call__(require=require)
+
+
+class PageTraverser:
+
+ __implements__ = IBrowserPublisher
+
+ def publishTraverse(self, request, name):
+ attribute, permission = self._PageTraverser__pages[name]
+ return Proxy(getattr(self, attribute),
+ NamesChecker(__call__=permission)
+ )
+ publishTraverse = ContextMethod(publishTraverse)
+
+ def browserDefault(self, request):
+ return self, (self._PageTraverser__default, )
+ browserDefault = ContextMethod(browserDefault)
+
+
+def defaultView(_context, name, for_=None, **__kw):
+
+ if __kw:
+ actions = view(_context, name=name, for_=for_, **__kw)()
+ else:
+ actions = []
+
+ if for_ is not None:
+ for_ = _context.resolve(for_)
+
+ type = IBrowserPresentation
+
+ actions += [
+ Action(
+ discriminator = ('defaultViewName', for_, type, name),
+ callable = handler,
+ args = ('Views','setDefaultViewName', for_, type, name),
+ )]
+
+ if for_ is not None:
+ actions += [
+ Action(
+ discriminator = None,
+ callable = handler,
+ args = ('Interfaces', 'provideInterface',
+ for_.__module__+'.'+for_.__name__,
+ for_)
+ )
+ ]
+
+ return actions