[Zope-Checkins] CVS: Zope3/lib/python/Zope/I18n - Domain.py:1.2 IDomain.py:1.2 ILanguageAvailability.py:1.2 IMessageCatalog.py:1.2 INegotiator.py:1.2 ITranslationService.py:1.2 IUserPreferedLanguages.py:1.2 MessageCatalog.py:1.2 Negotiator.py:1.2 Translate.py:1.2 TranslationService.py:1.2 __init__.py:1.2 i18n.zcml:1.2

Jim Fulton jim@zope.com
Mon, 10 Jun 2002 19:29:59 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/I18n
In directory cvs.zope.org:/tmp/cvs-serv20468/lib/python/Zope/I18n

Added Files:
	Domain.py IDomain.py ILanguageAvailability.py 
	IMessageCatalog.py INegotiator.py ITranslationService.py 
	IUserPreferedLanguages.py MessageCatalog.py Negotiator.py 
	Translate.py TranslationService.py __init__.py i18n.zcml 
Log Message:
Merged Zope-3x-branch into newly forked Zope3 CVS Tree.

=== Zope3/lib/python/Zope/I18n/Domain.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Zope.I18n.IDomain import IDomain
+
+class Domain:
+
+    __implements__ =  IDomain
+
+    def __init__(self, place, domain):
+        self._place = place
+        self.domain = domain
+
+
+    def getPlace(self):
+        """Return the place this domain was created for."""
+        return self._place
+
+
+    def getDomainName(self):
+        """Return the domain name"""
+        return self._domain
+    
+
+    ############################################################
+    # Implementation methods for interface
+    # IDomain.py
+
+    def translate(self, source, mapping=None, context=None,
+                  target_language=None):
+        'See Zope.I18n.IDomain.IDomain'
+
+        # lookup the correct translation service
+        service_manager = getServiceManager(self.place)
+        service = service_manager.getBoundService('Translation Service')
+
+        return service.translate(self.domain, source, mapping, context,
+                                 target_language)
+
+    #
+    ############################################################


=== Zope3/lib/python/Zope/I18n/IDomain.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Interface import Interface
+
+class IDomain(Interface):
+    """Since it is often tedious to always specify a domain and place for a
+       particular translation, the idea of a Domain object was created, which
+       allows to save the place and domain for a set of translations.
+
+       Usage:
+
+       domain = Domain(self, 'MyProduct')
+       domain.translate('MyProductTitle', context)
+
+       Constructor Arguments:
+
+         place -- A location where the Domain should look for the translation
+                  service.
+
+         domain -- Secifies the domain to look up for the translation. See
+                   ITranslationService for more details on domains.
+    """
+
+
+    def translate(msgid, mapping=None, context=None, target_language=None):
+        """Translate the the source to its appropriate language.
+
+        See ITranslationService for details.
+        """


=== Zope3/lib/python/Zope/I18n/ILanguageAvailability.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Interface import Interface
+
+class ILanguageAvailability(Interface):
+    
+    def availableLanguages():
+        """Return a sequence of language tags for available languages
+        """
+
+        


=== Zope3/lib/python/Zope/I18n/IMessageCatalog.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Interface import Interface
+
+
+class IMessageCatalog(Interface):
+    """Translation Service
+
+    This interface provides a method for translating a message or message id,
+    including text with interpolation. The message catalog basically serves as
+    a fairly simple mapping object.
+
+    A single Message Catalog represents a particular language and
+    domain. Therefore you will have the following constructor arguments:
+
+    language -- The language of the returning language. This is a read-only
+                attribute.
+
+    domain -- The translation domain for this messages. This is a read-only
+              attribute. See ITranslationService.
+
+    When we refer to text here, we mean text that follows the standard
+    Zope 3 text representation.
+    """
+
+    def getMessage(id):
+        """Return the appropriate text for the given id. As all get methods,
+           this will raise an error, if the id is not found
+        """
+
+    def queryMessage(id, default=None):
+        """Return the appropriate test for the given id, but if the id is not
+           found, it should not raise an error, instead returning default. If
+           default is None, then the id itself is returned.
+        """
+        
+    def getLanguage():
+        """Return the langauge this message catalog is representing.
+        """
+        
+    def getDomain():
+        """Return the domain this message catalog is serving.
+        """
+
+    def getIdentifier():
+        """Return a identifier for this message catalog. Note that this
+           identifier does not have to be unique as several message catalog
+           could serve the same domain and language.
+        """


=== Zope3/lib/python/Zope/I18n/INegotiator.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Interface import Interface
+
+class INegotiator(Interface):
+
+    """ The INegotiater defines an interface for a service for language 
+       negotiation
+    """
+  
+    def getLanguage(object_langs,  env):
+        """getLanguage implements a decision making algorithm to decide
+           what language should be used based on the available languages
+           for an object and a list of user prefered languages.
+
+        Arguments:
+
+        object_langs -- sequence of languages (not necessarily ordered)
+
+        env  -- environment passed to the service to determine a sequence
+                of user prefered languages
+
+        """
+


=== Zope3/lib/python/Zope/I18n/ITranslationService.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Interface import Interface
+
+
+class ITranslationService(Interface):
+    """Translation Service
+
+    This interface provides methods for translating text, including
+    text with interpolation.
+
+    When we refer to text here, we mean text that follows the standard
+    Zope 3 text representation.
+
+    Standard arguments:
+
+        domain -- The domain is used to specify which translation to use.
+                  Different products will often use a specific domain naming
+                  translations supplied with the product.
+                  Stephan's (my) favorite example is: How do you translate
+                  "Sun"? Is it our star, the abbreviation of Sunday or the
+                  company? Specifying the domain, such as "Stars" will solve
+                  this problem for us.
+
+        source -- The source message or message id that should be translated.
+
+        mapping -- The object to get the interpolation data from.
+
+        target_language -- The language to translate to.
+
+        context -- An object that provides contextual information for
+                   determining client language preferences. It must
+                   implement or have an adapter that implements
+                   IUserPreferedLanguages.
+
+        Note that one of destination_language or context must be
+        passed. Otherwise a TypeError will be raised.
+
+        Also note that language tags are defined by RFC 1766.
+    """
+
+
+    def translate(domain, source, mapping=None, 
+                  context=None, target_language=None):
+        """Translate source text. Translated text is returned.
+
+           However, the method does a little more than a vanilla
+           translation. The method also looks for a possible language to
+           translate to.
+           After a translation it also replaces any variables inside the 
+           
+           Note: The TranslationService interface does not support simplified
+                 translation methods, since it is totally hidden by ZPT and in
+                 Python you should use a Domain object, since it supports all
+                 the simplifications.
+        """
+
+
+    def getDomain(domain):
+        """Get the domain for the passed domain name"""
+        


=== Zope3/lib/python/Zope/I18n/IUserPreferedLanguages.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Interface import Interface
+
+class IUserPreferedLanguages(Interface):
+
+    """ This interfaces allows to obtain language negotiation dependant 
+        informations about user prefered languages.
+    """
+  
+    def getLanguages():
+
+        """getLanguages returns a sequence of user prefered languages
+
+        Arguments:
+        
+        None
+
+        """
+


=== Zope3/lib/python/Zope/I18n/MessageCatalog.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""A simple implementation of a Message Catalog. 
+
+$Id$
+"""
+
+from Zope.I18n.IMessageCatalog import IMessageCatalog
+
+
+class MessageCatalog:
+
+    __implements__ =  IMessageCatalog
+
+
+    def __init__(self, language, domain="global"):
+        """Initialize the message catalog"""
+        self._language = language
+        self._domain = domain
+        self._messages = {}
+    
+
+    def setMessage(self, id, message):
+        """Set a message to the catalog."""
+        self._messages[id] = message
+        
+
+    ############################################################
+    # Implementation methods for interface
+    # Zope.I18n.IMessageCatalog.
+
+    def getMessage(self, id):
+        'See Zope.I18n.IMessageCatalog.IMessageCatalog'
+        return self._messages[id]
+
+    def queryMessage(self, id, default=None):
+        'See Zope.I18n.IMessageCatalog.IMessageCatalog'
+        if default is None:
+            default = id
+        return self._messages.get(id, default)
+
+    def getLanguage(self):
+        'See Zope.I18n.IMessageCatalog.IMessageCatalog'
+        return self._language
+        
+    def getDomain(self):
+        'See Zope.I18n.IMessageCatalog.IMessageCatalog'
+        return self._domain
+
+    def getIdentifier(self):
+        'See Zope.I18n.IMessageCatalog.IMessageCatalog'
+        return (self._language, self._domain)
+        
+    #
+    ############################################################


=== Zope3/lib/python/Zope/I18n/Negotiator.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Zope.I18n.INegotiator import INegotiator
+from Zope.I18n.IUserPreferedLanguages import IUserPreferedLanguages
+from Zope.ComponentArchitecture import getAdapter
+
+class Negotiator:
+
+    __implements__ = INegotiator
+
+    def getLanguage(self, object_langs, env):
+
+        adapter  = getAdapter(env, IUserPreferedLanguages)
+        user_langs = adapter.getLanguages()
+
+        for lang in user_langs:
+            if lang in object_langs:
+                return lang
+
+        return None
+
+
+negotiator = Negotiator()


=== Zope3/lib/python/Zope/I18n/Translate.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+
+def translate(place, domain, source, mapping=None, context=None,
+              target_language=None):
+    """Translates a source text based on a location in the Zope architecture
+       and a domain."""
+
+    # Lookup service...
+    service = None
+
+    return service.translate(domain, source, mapping, context,
+                             target_language):


=== Zope3/lib/python/Zope/I18n/TranslationService.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+import re
+from types import StringTypes, TupleType
+
+import Persistence
+from Persistence.BTrees.OOBTree import OOBTree
+
+from Zope.App.OFS.Container.BTreeContainer import BTreeContainer
+from Zope.App.OFS.Container.IContainer import IContainer
+from Zope.App.OFS.Container.IContainer import IHomogenousContainer
+
+from Negotiator import negotiator
+from IMessageCatalog import IMessageCatalog
+from ITranslationService import ITranslationService
+
+
+# Setting up some regular expressions for finding interpolation variables in
+# the text.
+NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
+_interp_regex = re.compile(r'(?<!\$)(\$(?:%(n)s|{%(n)s}))' %({'n': NAME_RE}))
+_get_var_regex = re.compile(r'%(n)s' %({'n': NAME_RE}))
+
+
+class ILocalTranslationService(ITranslationService,
+                               IContainer, IHomogenousContainer):
+    """TTW manageable translation service"""
+
+
+class TranslationService(BTreeContainer):
+    ''' '''
+
+    __implements__ =  ILocalTranslationService
+
+
+    def __init__(self, default_domain='global'):
+        ''' '''
+        self.__data = OOBTree()
+        self._catalogs = OOBTree()
+
+
+    def _registerMessageCatalog(self, language, domain, catalog_name):
+        ''' '''
+        if (language, domain) not in self._catalogs.keys():
+            self._catalogs[(language, domain)] = []
+
+        mc = self._catalogs[(language, domain)]
+        mc.append(catalog_name)
+
+
+    def _unregisterMessageCatalog(self, language, domain, catalog_name):
+        ''' '''
+        mc = self._catalogs.get((language, domain), [])
+        mc.append(catalog_name)
+
+
+    ############################################################
+    # Implementation methods for interface
+    # Zope.App.OFS.Container.IContainer.IWriteContainer
+
+    def setObject(self, name, object):
+        'See Zope.App.OFS.Container.IContainer.IWriteContainer'
+        if type(name) in StringTypes and len(name)==0:
+            raise ValueError
+        if not self.isAddable(getattr(object,'__implements__', None)):
+            raise UnaddableError (self, object, name)
+        self.__data[name] = object
+        self._registerMessageCatalog(object.getLanguage(), object.getDomain(),
+                                     name)
+        return name
+
+    def __delitem__(self, name):
+        'See Zope.App.OFS.Container.IContainer.IWriteContainer'
+        del self.__data[name]
+        self._unregisterMessageCatalog(object.language, object.domain, name)
+        
+
+    def isAddable(self, interfaces):
+        'See Zope.App.OFS.Container.IContainer.IWriteContainer'
+        if type(interfaces) != TupleType:
+            interfaces = (interfaces,)
+        if IMessageCatalog in interfaces:
+            return 1
+        return 0
+
+    #
+    ############################################################
+
+
+    ############################################################
+    # Implementation methods for interface
+    # Zope.I18n.ITranslationService.
+
+    def translate(self, domain, source, mapping=None, context=None,  
+                  target_language=None):
+        '''See interface ITranslationService'''
+
+        if domain is None:
+            domain = self.default_domain
+
+        if target_language is None:
+            if context is None:
+                raise TypeError, 'No destination language'
+            else:
+                avail_langs = self.getAvailableLanguages(domain)
+                target_language = negotiator.getLanguage(avail_langs, context)
+
+        # Get the translation. Default is the source text itself.
+        catalog_names = self._catalogs.get((target_language, domain), {})
+
+        text = source
+        for name in catalog_names:
+            catalog = self.__data[name]
+            try:
+                text = catalog.getMessage(source)
+                break
+            except:
+                pass
+
+        # Now we need to do the interpolation
+        return self.interpolate(text, mapping)
+
+    #
+    ############################################################
+
+
+    def interpolate(self, text, mapping):
+        """Insert the data passed from mapping into the text"""
+
+        to_replace = _interp_regex.findall(text)
+
+        for string in to_replace:
+            var = _get_var_regex.findall(string)[0]
+            text = text.replace(string, mapping.get(var))
+
+        return text
+
+
+    def getAvailableLanguages(self, domain):
+        """Find all the languages that are available for this domain"""
+        identifiers = self._catalogs.keys()
+        identifiers = filter(lambda x, d=domain: x[1] == domain, identifiers)
+        languages = map(lambda x: x[0], identifiers)
+        return languages


=== Zope3/lib/python/Zope/I18n/__init__.py 1.1 => 1.2 ===
+#
+# 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.
+# 
+##############################################################################


=== Zope3/lib/python/Zope/I18n/i18n.zcml 1.1 => 1.2 ===
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:security='http://namespaces.zope.org/security'
+   xmlns:zmi='http://namespaces.zope.org/zmi'
+   xmlns:browser='http://namespaces.zope.org/browser'
+   xmlns:service='http://namespaces.zope.org/service'
+>
+
+  <serviceType
+      id="LanguageNegotiation" 
+      interface=".INegotiator." />
+  <service
+      serviceType="LanguageNegotiation" 
+      component=".Negotiator.negotiator" />
+
+<!-- Language negotiation adapter 
+<adapter factory="Zope.Publisher.Browser.BrowserLanguages."
+         for="Zope.Publisher.Browser.IHTTPRequest."
+         provides="Zope.I18n.IUserPreferedLanguages"
+         />
+-->
+
+<content class=".TranslationService.">
+   <security:require permission="Zope.I18n"
+                     interface="Zope.I18n.ITranslationService." 
+                     />
+   <security:require permission="Zope.ManageServices"
+                     interface="Zope.App.OFS.Container.IContainer." 
+                     />
+</content>
+
+<content class=".MessageCatalog.">
+   <security:require permission="Zope.Security"
+                     interface=".IMessageCatalog." 
+                     />
+
+</content>
+
+    <service:factoryFromClass id="TranslationService"
+                     class=".MessageCatalog."
+                     permission="Zope.ManageServices"
+                     title="Translation Service" />
+
+<!--factory component=".MessageCatalog." /-->
+
+<!--include package=".Views" file="views.zcml" /-->
+
+
+
+</zopeConfigure>