[Checkins] SVN: z3c.language/trunk/src/z3c/language/ Added language package

Roger Ineichen roger at projekt01.ch
Mon Aug 21 07:20:40 EDT 2006


Log message for revision 69715:
  Added language package
  
  The package contains a local negotiator,
  some base classes with a i18n switch adapter
  and a library for session handling support.
  
  This packages allows you to implement simply
  i18n aware content types and configure the 
  server (negotiator) for handling language 
  policies. Such a policy could be, that the server 
  will lookup for a fix language or language settings
  set on a session or the setting from the browser.
  
  See for more information inthe different README.txt 
  files or in the included tests

Changed:
  A   z3c.language/trunk/src/z3c/language/
  A   z3c.language/trunk/src/z3c/language/__init__.py
  A   z3c.language/trunk/src/z3c/language/negotiator/
  A   z3c.language/trunk/src/z3c/language/negotiator/README.txt
  A   z3c.language/trunk/src/z3c/language/negotiator/SETUP.cfg
  A   z3c.language/trunk/src/z3c/language/negotiator/__init__.py
  A   z3c.language/trunk/src/z3c/language/negotiator/app.py
  A   z3c.language/trunk/src/z3c/language/negotiator/browser/
  A   z3c.language/trunk/src/z3c/language/negotiator/browser/__init__.py
  A   z3c.language/trunk/src/z3c/language/negotiator/browser/configure.zcml
  A   z3c.language/trunk/src/z3c/language/negotiator/browser/views.py
  A   z3c.language/trunk/src/z3c/language/negotiator/configure.zcml
  A   z3c.language/trunk/src/z3c/language/negotiator/ftests.py
  A   z3c.language/trunk/src/z3c/language/negotiator/generations/
  A   z3c.language/trunk/src/z3c/language/negotiator/generations/__init__.py
  A   z3c.language/trunk/src/z3c/language/negotiator/generations/configure.zcml
  A   z3c.language/trunk/src/z3c/language/negotiator/interfaces.py
  A   z3c.language/trunk/src/z3c/language/negotiator/tests.py
  A   z3c.language/trunk/src/z3c/language/negotiator/vocabulary.py
  A   z3c.language/trunk/src/z3c/language/negotiator/z3c.language.negotiator-configure.zcml
  A   z3c.language/trunk/src/z3c/language/session/
  A   z3c.language/trunk/src/z3c/language/session/SETUP.cfg
  A   z3c.language/trunk/src/z3c/language/session/__init__.py
  A   z3c.language/trunk/src/z3c/language/session/app.py
  A   z3c.language/trunk/src/z3c/language/session/browser/
  A   z3c.language/trunk/src/z3c/language/session/browser/__init__.py
  A   z3c.language/trunk/src/z3c/language/session/browser/configure.zcml
  A   z3c.language/trunk/src/z3c/language/session/browser/views.py
  A   z3c.language/trunk/src/z3c/language/session/configure.zcml
  A   z3c.language/trunk/src/z3c/language/session/generations/
  A   z3c.language/trunk/src/z3c/language/session/generations/__init__.py
  A   z3c.language/trunk/src/z3c/language/session/generations/configure.zcml
  A   z3c.language/trunk/src/z3c/language/session/interfaces.py
  A   z3c.language/trunk/src/z3c/language/session/tests.py
  A   z3c.language/trunk/src/z3c/language/session/z3c.language.session-configure.zcml
  A   z3c.language/trunk/src/z3c/language/switch/
  A   z3c.language/trunk/src/z3c/language/switch/README.txt
  A   z3c.language/trunk/src/z3c/language/switch/SETUP.cfg
  A   z3c.language/trunk/src/z3c/language/switch/__init__.py
  A   z3c.language/trunk/src/z3c/language/switch/adapters.py
  A   z3c.language/trunk/src/z3c/language/switch/app.py
  A   z3c.language/trunk/src/z3c/language/switch/browser/
  A   z3c.language/trunk/src/z3c/language/switch/browser/__init__.py
  A   z3c.language/trunk/src/z3c/language/switch/browser/configure.zcml
  A   z3c.language/trunk/src/z3c/language/switch/browser/views.py
  A   z3c.language/trunk/src/z3c/language/switch/configure.zcml
  A   z3c.language/trunk/src/z3c/language/switch/generations/
  A   z3c.language/trunk/src/z3c/language/switch/generations/__init__.py
  A   z3c.language/trunk/src/z3c/language/switch/generations/configure.zcml
  A   z3c.language/trunk/src/z3c/language/switch/interfaces.py
  A   z3c.language/trunk/src/z3c/language/switch/property.py
  A   z3c.language/trunk/src/z3c/language/switch/testing.py
  A   z3c.language/trunk/src/z3c/language/switch/tests.py
  A   z3c.language/trunk/src/z3c/language/switch/vocabulary.py
  A   z3c.language/trunk/src/z3c/language/switch/z3c.language.switch-configure.zcml

-=-
Added: z3c.language/trunk/src/z3c/language/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,17 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""
+$Id$
+"""
+


Property changes on: z3c.language/trunk/src/z3c/language/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/README.txt
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/README.txt	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/README.txt	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,77 @@
+==========
+Negotiator
+==========
+
+Setup testbrowser for Negotiator functional tests.
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> browser.handleErrors = False
+
+Start Zope3 an go to the root.
+
+  >>> browser.open('http://localhost/@@contents.html')
+  >>> browser.url
+  'http://localhost/@@contents.html'
+
+Add a negotiator.
+
+  >>> browser.open('http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__z3c.language.negotiator.app.Negotiator')
+  >>> browser.url
+  'http://localhost/++etc++site/default/@@contents.html?type_name=BrowserAdd__z3c.language.negotiator.app.Negotiator'
+  >>> browser.getControl(name='new_value').value = ''
+  >>> browser.getControl('Apply').click()
+  >>> browser.url
+  'http://localhost/++etc++site/default/Negotiator/@@registration.html'
+
+And register the added negotiator utility.
+
+  >>> browser.handleErrors = False
+  >>> "This object isn't yet registered." in browser.contents
+  True
+  >>> browser.getLink('Registration').click()
+  >>> browser.getControl('Register this object').click()
+  >>> browser.url
+  'http://localhost/++etc++site/default/Negotiator/@@addRegistration.html'
+  >>> browser.getControl(
+  ...     'Provided interface').value = ['zope.i18n.interfaces.INegotiator']
+  >>> browser.getControl('Register As').value = ''
+  >>> browser.getControl('Comment').value = 'A local negotiator'
+  >>> browser.getControl('Register', index=1).click()
+  >>> browser.url
+  'http://localhost/++etc++site/default/Negotiator/@@registration.html'
+
+Now we see the edit form of the added and registred negotiator instance called
+Negotiator. Set the language lookup policy to 'server'.
+
+  >>> browser.open('http://localhost/++etc++site/default/Negotiator/'
+  ...    '@@edit.html')
+  >>> browser.getControl(name='field.policy').value = ['server']
+
+and set a default server language called 'de'.
+
+  >>> browser.getControl(name='field.serverLanguage').value = 'de'
+
+and save this part.
+
+  >>> browser.getControl(name='UPDATE_SUBMIT').click()
+
+Now we add a session language via the used sequence list widget.
+
+  >>> browser.getControl(name='field.sessionLanguages.add').click()
+  >>> browser.getControl(name='field.sessionLanguages.0.').value = 'fr'
+
+And we also add a offered language.
+
+  >>> browser.getControl(name='field.offeredLanguages.add').click()
+  >>> browser.getControl(name='field.offeredLanguages.0.').value = 'de'
+
+And as last, we save the changes.
+
+  >>> browser.getControl(name='UPDATE_SUBMIT').click()
+
+Now check if the set language is german. See the label at the submit button.
+
+  >>> browser.getControl(name='UPDATE_SUBMIT').value
+  'Abschicken'


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/SETUP.cfg
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/SETUP.cfg	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/SETUP.cfg	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  z3c.language.negotiator-*.zcml
+</data-files>


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from z3c.language.negotiator.interfaces import *


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/app.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/app.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/app.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,139 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+from zope.interface import implements
+
+from zope.i18n.interfaces import IUserPreferredLanguages
+from zope.i18n.interfaces import INegotiator
+from zope.i18n.negotiator import negotiator
+
+from zope.app.container.contained import Contained
+
+from z3c.language.session.interfaces import ILanguageSession
+
+from z3c.language.negotiator.interfaces import INegotiatorManager
+from z3c.language.negotiator.interfaces import language_policies
+
+
+
+class Negotiator(Persistent, Contained):
+    """Loacal negotiator implementation.
+
+    The negotiator let you change the policy, which is a alias
+    for the lookup mechanism. 
+
+    'server' -- The server defines the language
+
+    'session' -- The session defines the language (usefull for testing)
+
+    'browser' -- The browser defines the language (usefull for testing)
+
+    'browser --> session --> server' -- Left criteria first
+
+    'browser --> server' -- Left criteria first
+
+    'session --> browser --> server' -- Left criteria first (default use case)
+
+    'session --> server' -- Left criteria first
+
+    The 'server' criteria is used as a fallback criteria in most use cases.
+
+    """
+
+    implements(INegotiator, INegotiatorManager)
+
+    def __init__(self):
+        self._policy = 'session --> browser --> server'
+        self._serverLanguage = None
+        self._sessionLanguages = []
+        self._offeredLanguages = []
+
+    def _getLanguagePolicy(self):
+        """Returns the language policy."""
+        return self._policy
+
+    def _setLanguagePolicy(self, policy):
+        """Set the language policy."""
+        if policy not in language_policies:
+            policies = str(language_policies)
+            msg = "Only %s are valide policy names." % policies
+            raise ValueError(msg, policy)
+        self._policy = policy
+
+    policy = property(_getLanguagePolicy, _setLanguagePolicy)
+
+    def _getServerLanguage(self):
+        """Returns the language for server policy."""
+        return self._serverLanguage
+
+    def _setServerLanguage(self, language):
+        """Set the language for server policy."""
+        self._serverLanguage = language
+
+    serverLanguage = property(_getServerLanguage, _setServerLanguage)
+
+    def _getSessionLanguages(self):
+        """Returns the language for server policy."""
+        return self._sessionLanguages
+
+    def _setSessionLanguages(self, languages):
+        """Set the language for server policy."""
+        self._sessionLanguages = languages
+
+    sessionLanguages = property(_getSessionLanguages, _setSessionLanguages)
+
+    # TODO: 
+    # perhaps we can make a relation to the translation domains
+    # and dymanicly find out what language we support in the domains.
+    def _getOfferedLanguages(self):
+        """Returns the language for server policy."""
+        return self._offeredLanguages
+
+    def _setOfferedLanguages(self, languages):
+        """Set the language for server policy."""
+        self._offeredLanguages = languages
+
+    offeredLanguages = property(_getOfferedLanguages, _setOfferedLanguages)
+
+    def getLanguage(self, languages, request):
+        """Returns the language dependent on the policy."""
+        policyList = self._policy.split(' --> ')
+
+        for policy in policyList:
+            
+            # the server is handling the language
+            if policy == 'server':
+                if self.serverLanguage:
+                    return self.serverLanguage
+
+            # the language is handled by a session 
+            elif policy == 'session':
+                session = ILanguageSession(request)
+                lang = session.getLanguage()
+                if lang != None:
+                    return lang
+
+            # the language is handled by the browsers language settings
+            elif policy == 'browser':
+                lang = negotiator.getLanguage(languages, request)
+                if lang != None:
+                    return lang
+
+        return None


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/app.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/browser/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/browser/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/browser/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,17 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/browser/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/browser/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/browser/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/browser/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,39 @@
+<configure
+    xmlns:zope="http://namespaces.zope.org/zope"
+    xmlns="http://namespaces.zope.org/browser"
+    i18n_domain="z3c.language">
+
+  <!-- local negotiator -->
+  <addMenuItem
+      title="Negotiator"
+      description="Negotiator returns the i18n language for translation."
+      class="z3c.language.negotiator.app.Negotiator"
+      permission="zope.ManageSite"
+      />
+
+  <editform
+      name="edit.html"
+      label="Negotiator for i18n language lookup."
+      schema="..INegotiatorManager"
+      menu="zmi_views" title="Edit"
+      permission="zope.ManageContent"
+      />
+
+  <!-- negotiator views -->
+  <page
+      for="*"
+      name="offered_languages"
+      permission="zope.Public"
+      class=".views.NegotiatorView"
+      attribute="getOfferedLanguages"
+      />
+
+  <page
+      for="*"
+      name="hasOfferedLanguages"
+      permission="zope.Public"
+      class=".views.NegotiatorView"
+      attribute="hasOfferedLanguages"
+      />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/browser/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/browser/views.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/browser/views.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/browser/views.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+from zope.i18n.interfaces import INegotiator
+from zope.publisher.browser import BrowserView
+
+from zope.app.zapi import getUtility
+
+from z3c.language.negotiator import IOfferedLanguages
+
+
+
+class NegotiatorView(BrowserView):
+
+    implements(IOfferedLanguages)
+
+    def getOfferedLanguages(self):
+        """View for listing  available (offered) languages."""
+
+        negotiator = getUtility(INegotiator, '', self.context)
+
+        try:
+            offeredLanguages = negotiator.offeredLanguages
+        except:
+            # we don't have a Negotiator instance
+            # we got the global zope.i18n Negotiator
+            offeredLanguages = []
+
+        return offeredLanguages
+
+    def hasOfferedLanguages(self):
+        """View for to check if we have i18n session support."""
+
+        negotiator = getUtility(INegotiator, '', self.context)
+
+        try:
+            offeredLanguages = negotiator.offeredLanguages
+            return True
+        except:
+            # we don't have a Negotiator instance
+            # we got the global zope.i18n Negotiator
+            return False


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/browser/views.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,42 @@
+<configure 
+    xmlns="http://namespaces.zope.org/zope"
+    i18n_domain="z3c.language">
+
+  <include package=".generations" />
+
+  <interface
+      interface=".IAvailableTranslationDomainLanguagesVocabulary"
+      />
+
+  <!-- local Negotiator -->
+  <localUtility class=".app.Negotiator">
+    <factory
+        id="z3c.language.negotiator.interfaces.INegotiator"
+        />
+    <implements
+        interface="zope.annotation.interfaces.IAttributeAnnotatable"
+        />
+    <require
+        permission="zope.Public"
+        interface="zope.i18n.interfaces.INegotiator"
+        />
+    <require
+        permission="zope.ManageSite"
+        interface=".interfaces.INegotiatorManager"
+        />
+    <require
+        permission="zope.ManageSite"
+        set_schema=".interfaces.INegotiatorManager"
+        />
+  </localUtility>
+
+  <utility
+      provides="zope.schema.interfaces.IVocabularyFactory"
+      component="
+          .vocabulary.AvailableTranslationDomainLanguagesVocabularyForZ3C"
+      name="available z3c languages"
+      />
+
+  <include package=".browser" />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/ftests.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/ftests.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/ftests.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,36 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+import unittest
+
+from zope.testing import doctest
+from zope.app.testing.functional import FunctionalDocFileSuite
+from zope.app.testing.functional import BrowserTestCase
+
+
+
+def test_suite():
+    return unittest.TestSuite((
+        FunctionalDocFileSuite(
+            "README.txt",
+            optionflags=doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE),
+        ))
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
\ No newline at end of file


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/ftests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/generations/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/generations/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/generations/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+__docformat__ = "reStructuredText"
+
+from zope.app.generations.generations import SchemaManager
+
+pkg = 'z3c.language.negotiator.generations'
+
+
+schemaManager = SchemaManager(
+    minimum_generation=0,
+    generation=0,
+    package_name=pkg)


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/generations/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/generations/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/generations/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/generations/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,9 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <utility
+      name="z3c.language.negotiator" 
+      provides="zope.app.generations.interfaces.ISchemaManager"
+      component=".schemaManager"
+      />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/generations/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/interfaces.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/interfaces.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/interfaces.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,90 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+
+from zope.schema.interfaces import IVocabularyTokenized
+from zope.schema import TextLine
+from zope.schema import List
+from zope.schema import Choice
+from zope.i18n.interfaces import INegotiator
+
+from zope.app.session.interfaces import ISession
+
+from z3c.i18n import MessageFactory as _
+
+language_policies = ['server', 'session', 'browser', 
+    'browser --> session --> server', 'browser --> server', 
+    'session --> browser --> server', 'session --> server']
+
+
+
+class INegotiatorManager(Interface):
+    """Local negotiator utility manager interface."""
+
+    policy = Choice(
+        title=_("Language lookup policy"),
+        description=_("Defines how the language lookup is working."),
+        values=language_policies,
+        default='session --> browser --> server',
+        required=True)
+
+    serverLanguage = TextLine(
+        title=_(u"Server language"),
+        description=_(u"The language used for server policy."),
+        default=u"en",
+        required=True,
+        )
+
+    sessionLanguages = List(
+        title=_(u"Session languages"),
+        description=_(u"A list of available languages in session policy."),
+        value_type = TextLine(title=_(u"A i18n language."),
+            description=_(u"""A i18n language definition string used in 
+                sessions.""")),
+        required=False,
+        )
+
+    offeredLanguages = List(
+        title=_(u"Offered languages"),
+        description=_(u"""A list of offered languages in the skin for the 
+            user to select."""),
+        value_type = TextLine(title=_(u"A i18n language."),
+            description=_(u"""
+                A i18n language definition string offerd in the skin for the 
+                user to select.""")),
+        required=False,
+        )
+
+
+
+class IOfferedLanguages(Interface):
+
+
+    def getOfferedLanguages():
+        """View for listing  available (offered) languages."""
+
+
+    def hasOfferedLanguages():
+        """View for to check if we have i18n session support."""
+
+
+
+class IAvailableTranslationDomainLanguagesVocabulary(IVocabularyTokenized):
+    """Available languages."""


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/tests.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/tests.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/tests.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,119 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+import unittest
+
+from zope.app.testing import ztapi
+
+from zope.i18n.interfaces import IUserPreferredLanguages
+from zope.component.testing import PlacelessSetup
+from zope.interface import implements
+
+from z3c.language.session.interfaces import ILanguageSession
+from z3c.language.negotiator.app import Negotiator
+
+
+
+class TestLanguageSession(object):
+    
+    implements(ILanguageSession)
+
+    def __init__(self, request):
+        pass
+
+    def getLanguage(self):
+        return 'fr'
+
+
+class Env(object):
+    implements(IUserPreferredLanguages)
+
+    def __init__(self, langs=()):
+        self.langs = langs
+
+    def getPreferredLanguages(self):
+        return self.langs
+
+
+class NegotiatorTest(PlacelessSetup, unittest.TestCase):
+
+    def setUp(self):
+        super(NegotiatorTest, self).setUp()
+        self.negotiator = Negotiator()
+        ztapi.provideAdapter(IUserPreferredLanguages, ILanguageSession,
+            TestLanguageSession)
+
+#    def test__getLanguagePolicy(self):
+#        default = 'session --> browser --> server'
+#        self.assertEqual(self.negotiator._getLanguagePolicy(), default)
+#
+#    def test__setLanguagePolicy(self):
+#        self.negotiator.policy = 'server'
+#        self.assertEqual(self.negotiator.policy, 'server')
+#        self.assertRaises(
+#            ValueError, self.negotiator._setLanguagePolicy, 'undefined')
+#
+#    def test_policy(self):
+#        default = 'session --> browser --> server'
+#        self.assertEqual(self.negotiator.policy, default)
+#        self.negotiator.policy = 'server'
+#        self.assertEqual(self.negotiator.policy, 'server')
+#
+#    def test_serverLanguage(self):
+#        self.assertEqual(self.negotiator.serverLanguage, None)
+#        self.negotiator.serverLanguage = 'de'
+#        self.assertEqual(self.negotiator.serverLanguage, 'de')
+#
+#    def test_sessionLanguages(self):
+#        self.assertEqual(self.negotiator.sessionLanguages, [])
+#        self.negotiator.sessionLanguages = ['de', 'en']
+#        self.assertEqual(self.negotiator.sessionLanguages, ['de', 'en'])
+#
+#    def test_offeredLanguages(self):
+#        self.assertEqual(self.negotiator.offeredLanguages, [])
+#        self.negotiator.offeredLanguages = ['de', 'en']
+#        self.assertEqual(self.negotiator.offeredLanguages, ['de', 'en'])
+
+#    def test_getLanguages(self):
+#        # first set the default policy to 'browser'
+#        self.negotiator.policy = 'browser'
+#        self.assertEqual(self.negotiator.policy, 'browser')
+#
+#        _cases = (
+#            (('en','de'), ('en','de','fr'),  'en'),
+#            (('en'),      ('it','de','fr'),  None),
+#            (('pt-br','de'), ('pt_BR','de','fr'),  'pt_BR'),
+#            (('pt-br','en'), ('pt', 'en', 'fr'),  'pt'),
+#            (('pt-br','en-us', 'de'), ('de', 'en', 'fr'),  'en'),
+#            )
+#
+#        for user_pref_langs, obj_langs, expected in _cases:
+#            env = Env(user_pref_langs)
+#            self.assertEqual(self.negotiator.getLanguage(obj_langs, env),
+#                             expected)
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(NegotiatorTest),
+                           ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/vocabulary.py
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/vocabulary.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/vocabulary.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,65 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import classProvides
+from zope.interface.declarations import implements
+
+from zope.schema.interfaces import IVocabularyFactory
+from zope.schema.vocabulary import SimpleTerm
+from zope.schema.vocabulary import SimpleVocabulary
+
+from zope.app.zapi import getUtility
+from zope.app.i18n.interfaces import ILocalTranslationDomain
+
+from z3c.language.negotiator import \
+    IAvailableTranslationDomainLanguagesVocabulary
+
+
+
+class AvailableTranslationDomainLanguagesVocabulary(SimpleVocabulary):
+    """A vocabular of available languages from a translation domain."""
+
+    implements(IAvailableTranslationDomainLanguagesVocabulary)
+
+    def __init__(self, context, domain='zope'):
+        terms = []
+        
+        # collect languages from translation domain
+        trans_domain = getUtility(ILocalTranslationDomain, domain)
+        languages = trans_domain.getAvailableLanguages()
+
+        for lang in languages:
+            terms.append(SimpleTerm(lang, lang, lang))
+
+        terms.sort(lambda lhs, rhs: cmp(lhs.title, rhs.title))
+        super(AvailableTranslationDomainLanguagesVocabulary, self).__init__(
+            terms)
+
+
+
+class AvailableTranslationDomainLanguagesVocabularyForZ3C(
+    AvailableTranslationDomainLanguagesVocabulary):
+    """AvailableTranslationDomainLanguagesVocabulary for z3c domain."""
+
+    classProvides(IVocabularyFactory)
+
+    def __init__(self, context, ):
+        super(AvailableTranslationDomainLanguagesVocabulary,self).__init__(
+            context, domain='z3c')
+    


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/vocabulary.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/negotiator/z3c.language.negotiator-configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/negotiator/z3c.language.negotiator-configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/negotiator/z3c.language.negotiator-configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="z3c.language.negotiator" />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/negotiator/z3c.language.negotiator-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/SETUP.cfg
===================================================================
--- z3c.language/trunk/src/z3c/language/session/SETUP.cfg	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/SETUP.cfg	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  z3c.language.session-*.zcml
+</data-files>


Property changes on: z3c.language/trunk/src/z3c/language/session/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/session/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from z3c.language.session.interfaces import *


Property changes on: z3c.language/trunk/src/z3c/language/session/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/app.py
===================================================================
--- z3c.language/trunk/src/z3c/language/session/app.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/app.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,95 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+from zope.interface import implements
+
+from zope.component import ComponentLookupError
+
+from zope.i18n.interfaces import IUserPreferredLanguages
+from zope.i18n.negotiator import negotiator
+
+from zope.app.zapi import getUtility
+from zope.app.container.contained import Contained
+
+from zope.app.session.session import Session
+from zope.app.session.interfaces import ISession
+from zope.app.session.interfaces import IClientId
+from zope.app.session.interfaces import ISessionDataContainer
+from zope.app.session.session import SessionData
+from zope.app.session.session import SessionPkgData
+
+from z3c.language.session import ILanguageSession
+from z3c.language.session import IGetLanguage
+from z3c.language.session import ISetLanguage
+from z3c.language.session import sessionPkgDataId
+
+
+
+class LanguageSession(Session):
+    """Handles i18n language via server session.
+
+    >>> from zope.app.session.interfaces import ISession
+    >>> from zope.app.session.session import PersistentSessionDataContainer
+    >>> from zope.app.session import tests
+    >>> request = tests.setUp(PersistentSessionDataContainer)
+    >>> request2 = tests.HTTPRequest(None, {}, None)
+
+    >>> ILanguageSession.providedBy(LanguageSession(request))
+    True
+
+    >>> ISession.providedBy(LanguageSession(request))
+    True
+
+    Setup a language sessions:
+
+    >>> sessionLanguage = LanguageSession(request)
+
+    Test getLanguage, if no language is set, it should be None:
+
+    >>> sessionLanguage.getLanguage()
+
+    Test setLanguage:
+
+    >>> sessionLanguage.setLanguage('de')
+    >>> sessionLanguage.getLanguage()
+    'de'
+
+    >>> tests.tearDown()
+
+    """
+
+    implements(ILanguageSession, IGetLanguage, ISetLanguage)
+
+    def __init__(self, request):
+        super(LanguageSession, self).__init__(request)
+
+    def getLanguage(self):
+        """Returns the language form the session."""
+        spd = self.__getitem__(sessionPkgDataId)
+        lang = spd.get('language', None)
+        if lang:
+            return lang
+        else:
+            return None
+
+    def setLanguage(self, language):
+        """Set the language to the session."""
+        spd = self.__getitem__(sessionPkgDataId)
+        spd['language'] = language


Property changes on: z3c.language/trunk/src/z3c/language/session/app.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/browser/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/session/browser/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/browser/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,17 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""


Property changes on: z3c.language/trunk/src/z3c/language/session/browser/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/browser/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/session/browser/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/browser/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,30 @@
+<configure
+    xmlns:zope="http://namespaces.zope.org/zope"
+    xmlns="http://namespaces.zope.org/browser"
+    i18n_domain="z3c.language">
+
+  <page
+      for="*"
+      name="hasLanguage"
+      permission="zope.Public"
+      class=".views.LanguageSessionView"
+      attribute="hasLanguage"
+      />
+
+  <page
+      for="*"
+      name="getLanguage"
+      permission="zope.Public"
+      class=".views.LanguageSessionView"
+      attribute="getLanguage"
+      />
+
+  <page
+      for="*"
+      name="setLanguage"
+      permission="zope.Public"
+      class=".views.LanguageSessionView"
+      attribute="setLanguage"
+      />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/session/browser/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/browser/views.py
===================================================================
--- z3c.language/trunk/src/z3c/language/session/browser/views.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/browser/views.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,86 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+
+from zope.publisher.browser import BrowserView
+
+from z3c.language.session import IGetLanguage
+from z3c.language.session import IHasLanguage
+from z3c.language.session import ILanguageSession
+from z3c.language.session import ISetLanguage
+
+
+
+
+class LanguageSessionView(BrowserView):
+
+    implements(IHasLanguage, IGetLanguage, ISetLanguage)
+
+    def hasLanguage(self):
+        """View for to check if a session has a i18n language value."""
+        
+        try:
+            session = ILanguageSession(self.request)
+            lang = session.getLanguage()
+            if lang:
+                return True
+            else:
+                return False
+        except:
+            return False
+
+
+    def getLanguage(self):
+        """View for to check if a session has a i18n language value."""
+
+        _fallback = 'en'
+        
+        try:
+            session = ILanguageSession(self.request)
+            return session.getLanguage()
+        except:
+            return _fallback
+
+
+    def setLanguage(self):
+        """Set the given language in the request to the session.
+        
+        You can do it via the javascript sessionlanguage.js with the
+        javascript method setLanguage:
+        
+        javascript:setLanguage('@@setLanguage','de')
+        
+        Or send the request to the view '@@setLanguage'. There has to be a 
+        variable 'language' and 'nextURL' in the request like
+        """
+
+        nextURL = '.'
+
+        if "language" in self.request:
+            lang = self.request['language']
+        
+        if "nextURL" in self.request:
+            nextURL = self.request['nextURL']
+
+        if lang:
+            session = ILanguageSession(self.request)
+            session.setLanguage(lang)
+
+        self.request.response.redirect(nextURL)


Property changes on: z3c.language/trunk/src/z3c/language/session/browser/views.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/session/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,16 @@
+<configure 
+    xmlns="http://namespaces.zope.org/zope"
+    i18n_domain="z3c.language">
+
+  <include package=".generations" />
+
+  <adapter
+      for="zope.publisher.interfaces.IRequest"
+      provides=".ILanguageSession"
+      factory=".app.LanguageSession"
+      permission="zope.Public"
+      />
+
+  <include package=".browser" />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/session/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/generations/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/session/generations/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/generations/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+__docformat__ = "reStructuredText"
+
+from zope.app.generations.generations import SchemaManager
+
+pkg = 'z3c.language.session.generations'
+
+
+schemaManager = SchemaManager(
+    minimum_generation=0,
+    generation=0,
+    package_name=pkg)


Property changes on: z3c.language/trunk/src/z3c/language/session/generations/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/generations/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/session/generations/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/generations/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,9 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <utility
+      name="z3c.language.session" 
+      provides="zope.app.generations.interfaces.ISchemaManager"
+      component=".schemaManager"
+      />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/session/generations/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/interfaces.py
===================================================================
--- z3c.language/trunk/src/z3c/language/session/interfaces.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/interfaces.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,67 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+
+from zope.schema.interfaces import IVocabularyTokenized
+
+from zope.app.session.interfaces import ISession
+
+from z3c.i18n import MessageFactory as _
+
+sessionPkgDataId = 'z3c.language.session.SessionDataContainer'
+
+
+
+class ILanguageSession(ISession):
+    """Session containing the language for a session."""
+
+
+
+class IHasLanguage(Interface):
+    """Has language API"""
+
+    def hasLanguage():
+        """View for to check if a session has a i18n language value."""
+
+
+
+class IGetLanguage(Interface):
+    """Get language API"""
+
+    def getLanguage():
+        """View for to check if a session has a i18n language value."""
+
+
+
+class ISetLanguage(Interface):
+    """Set language API"""
+
+    def setLanguage():
+        """Set the given language in the request to the session.
+        
+        You can do it via the javascript sessionlanguage.js with the
+        javascript method setLanguage:
+        
+        javascript:setLanguage('@@setLanguage','de')
+        
+        Or send the request to the view '@@setLanguage'. There has to be a 
+        variable 'language' and 'nextURL' in the request like
+        """
+


Property changes on: z3c.language/trunk/src/z3c/language/session/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/tests.py
===================================================================
--- z3c.language/trunk/src/z3c/language/session/tests.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/tests.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+
+from zope.testing.doctestunit import DocTestSuite
+
+
+def test_suite():
+    return unittest.TestSuite((
+        DocTestSuite('z3c.language.session.app'),
+        ))
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.language/trunk/src/z3c/language/session/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/session/z3c.language.session-configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/session/z3c.language.session-configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/session/z3c.language.session-configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="z3c.language.session" />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/session/z3c.language.session-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/README.txt
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/README.txt	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/README.txt	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,104 @@
+======
+README
+======
+
+Let's show how z3c.language.switch works:
+
+Imports and placeless setup:
+
+    >>> from zope.app.testing import placelesssetup, ztapi
+    >>> from z3c.language.switch import II18nLanguageSwitch
+    >>> from z3c.language.switch.testing import IContentObject
+    >>> from z3c.language.switch.testing import II18nContentObject
+    >>> from z3c.language.switch.testing import I18nContentObject
+    >>> from z3c.language.switch.testing import I18nContentObjectLanguageSwitch
+    >>> from z3c.language.switch.testing import ContentObject
+    >>> placelesssetup.setUp()
+
+Setup test object:
+
+    >>> en_title = u'en_title'
+    >>> obj = I18nContentObject(en_title)
+    >>> obj.title
+    u'en_title'
+
+Add additional languages:
+
+    >>> de_title = u'de_title'
+    >>> fr_title = u'fr_title'
+    >>> deObj = obj.addLanguage('de', de_title)
+    >>> frObj = obj.addLanguage('fr', fr_title)
+
+Switch default language:
+
+    >>> obj.title
+    u'en_title'
+
+    >>> obj.setDefaultLanguage('de')
+    >>> obj.title
+    u'de_title'
+
+Remove the 'en' language object:
+
+    >>> obj._data.keys()
+    ['de', 'en', 'fr']
+    >>> obj.removeLanguage('en')
+    >>> obj._data.keys()
+    ['de', 'fr']
+
+Remove default language object will end in a ValueError error:
+
+    >>> obj.removeLanguage('de')
+    Traceback (most recent call last):
+    ...
+    ValueError: cannot remove default language (de)
+
+Remove nonexistent language object will end in a ValueError error:
+
+    >>> obj.removeLanguage('undefined')
+    Traceback (most recent call last):
+    ...
+    ValueError: cannot remove nonexistent language (undefined)
+
+Set default language to a non existent language will end in a ValueError:
+
+    >>> obj.setDefaultLanguage('en')
+    Traceback (most recent call last):
+    ...
+    ValueError: cannot set nonexistent language (en) as default
+
+Access the language directly via the II18nLanguageSwitch adapter,
+first register the adapter for the I18nContentObject:
+
+    >>> ztapi.provideAdapter(I18nContentObject, II18nLanguageSwitch, 
+    ...     I18nContentObjectLanguageSwitch)
+
+The adapter is set to the default language in the init method:
+
+    >>> adapted = II18nLanguageSwitch(obj)
+    >>> adapted.title
+    u'de_title'
+
+Change the default language and access the title again, the title should not 
+switch to another language:
+
+    >>> obj.setDefaultLanguage('fr')
+    >>> adapted.title
+    u'de_title'
+    
+Switch the language to 'fr'  via the adapter:
+
+    >>> adapted.setLanguage('fr')
+    >>> adapted.title
+    u'fr_title'
+
+Finally, clean up::
+
+    >>> placelesssetup.tearDown()
+
+
+AvailableLanguagesVocabulary
+----------------------------
+
+Use this vocabulary for getting the available languages from the object 
+itself.


Property changes on: z3c.language/trunk/src/z3c/language/switch/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/SETUP.cfg
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/SETUP.cfg	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/SETUP.cfg	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  z3c.language.switch-*.zcml
+</data-files>


Property changes on: z3c.language/trunk/src/z3c/language/switch/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,18 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+from z3c.language.switch.interfaces import *


Property changes on: z3c.language/trunk/src/z3c/language/switch/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/adapters.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/adapters.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/adapters.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,102 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+
+from z3c.language.switch import II18n
+from z3c.language.switch import II18nLanguageSwitch
+
+
+
+class I18nLanguageSwitch(object):
+    """Mixing class for switch a language on a object.
+    
+    Use the method _getI18n for set the i18n object.
+    """
+
+    _language = 'en'
+
+    implements(II18nLanguageSwitch)
+
+    def __init__(self, context):
+        self.context = context
+        self.i18n = self._getI18n()
+        self._language = self._getDefaultLanguage()
+
+    def _getDefaultLanguage(self):
+        """Subclasses may overwrite this method."""
+        return self.i18n.getDefaultLanguage()
+
+    def _getI18n(self):
+        """Subclasses may overwrite this method."""
+        return self.context
+
+    # II18nLanguageSwitch interface
+    def getLanguage(self):
+        """See `z3c.langauge.switch.interfaces.II18nLanguageSwitch`"""
+        return self._language
+
+    def setLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.II18nLanguageSwitch`"""
+        self._language = language
+
+
+
+class I18nAdapter(object):
+    """Mixing class for i18n adapters which must provide the adapted object 
+       under the attribute 'self.i18n'.
+    """
+
+    implements(II18n)
+
+    # z3c.langauge.switch.IReadI18n
+    def getAvailableLanguages(self):
+        """See `z3c.langauge.switch.interfaces.IReadI18n`"""
+        return self.i18n.getAvailableLanguages()
+
+    def getDefaultLanguage(self):
+        """See `z3c.langauge.switch.interfaces.IReadI18n`"""
+        return self.i18n.getDefaultLanguage()
+
+    def getPreferedLanguage(self):
+        """See `z3c.langauge.switch.interfaces.IReadI18n`"""
+        return self.i18n.getPreferedLanguage()
+
+    def getAttribute(self, name, language=None):
+        return self.i18n.getAttribute(name, language)
+        
+    def queryAttribute(self, name, language=None, default=None):
+        return self.i18n.queryAttribute(name, language, default)
+
+    # z3c.langauge.switch.IWriteI18n interface
+    def setDefaultLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        return self.i18n.setDefaultLanguage(language)
+
+    def addLanguage(self, language, *args, **kw):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        return self.i18n.addLanguage(language, *args, **kw)
+
+    def removeLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        self.i18n.removeLanguage(language)
+
+    def setAttributes(self, language, **kws):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        self.i18n.setAttributes(language, **kws)


Property changes on: z3c.language/trunk/src/z3c/language/switch/adapters.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/app.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/app.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/app.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,295 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+
+from zope.event import notify
+from zope.i18n.interfaces import INegotiator
+from zope.interface import implements
+from zope.lifecycleevent import ObjectCreatedEvent
+from zope.lifecycleevent import ObjectModifiedEvent
+from zope.security.management import getInteraction
+
+from zope.app import zapi
+
+from z3c.language.switch import II18n
+
+
+
+def getRequest():
+    try:
+        interaction = getInteraction()
+        request = interaction.participations[0]
+    except:
+        request = None
+
+    return request
+
+
+
+class I18n(Persistent, object):
+    """Mixin implementation of II18n.
+    
+    Set a factory class in our implementation. The _create method will initalize 
+    this class and use it as a child object providing the attributes without 
+    languages.
+
+    You can use this class as mixin for i18n implementations:
+
+        >>> from z3c.language.switch.app import I18n
+        >>> class Person(object):
+        ...     def __init__(self, firstname, lastname):
+        ...         self.firstname = firstname
+        ...         self.lastname = lastname
+
+        >>> class I18nPerson(I18n):
+        ...     _defaultLanguage = 'en'
+        ...     _factory = Person
+
+    Now you can initialize the default translation:
+
+        >>> i18n = I18nPerson(firstname='Bob', lastname='Miller')
+        >>> i18n.getDefaultLanguage()
+        'en'
+        >>> i18n.getPreferedLanguage()
+        'en'
+
+    You can access the attributes of the default translation:
+
+        >>> i18n.getAttribute('firstname')
+        'Bob'
+        >>> i18n.getAttribute('lastname')
+        'Miller'
+        
+    That is the same as accessing the attribute using a language parameter:
+
+        >>> i18n.getAttribute('firstname', 'en')
+        'Bob'
+
+    If an attribute is not available a AttributeError is raised. The queryAttribute
+    method offers a save way for unsecure access:
+
+        >>> i18n.getAttribute('name')
+        Traceback (most recent call last):
+        ...
+        AttributeError: 'Person' object has no attribute 'name'
+
+        >>> i18n.queryAttribute('name') is None
+        True
+
+    You can set the attributes an other time:
+
+        >>> i18n.setAttributes('en', firstname='Foo', lastname='Bar')
+        >>> i18n.getAttribute('firstname')
+        'Foo'
+        >>> i18n.getAttribute('lastname')
+        'Bar'
+
+    You can initialize the default translation using a specific language:
+
+        >>> i18n = I18nPerson(defaultLanguage='fr', firstname='Robert', lastname='Moulin')
+        >>> i18n.getDefaultLanguage()
+        'fr'
+        >>> i18n.getPreferedLanguage()
+        'fr'
+
+    """
+
+    _data = None
+    # sublclasses should overwrite this attrubute.
+    _defaultLanguage = None
+    _factory = None
+
+    # private method (subclasses might overwrite this method)
+    def _defaultArgs(self):
+        return None
+
+    implements(II18n)
+
+
+    def __init__(self, defaultLanguage=None, *args, **kws):
+        # preconditions
+        if self._defaultLanguage is None:
+            raise NotImplementedError('_defaultLanguage')
+
+        if self._factory is None:
+            raise NotImplementedError('_factory')
+
+        # essentials
+        if defaultLanguage is None:
+            defaultLanguage = self._defaultLanguage
+
+        # initialize data store for translations
+        self._setDataOnce()
+
+        # initialize default translation
+        self._get_or_add(defaultLanguage, *args, **kws)
+
+        # set default language
+        self.setDefaultLanguage(defaultLanguage)
+
+    # private method
+    def _setDataOnce(self):
+        if self._data is None:
+            self._data = {}
+
+    # private method: access self._data only using this method
+    def _getData(self):
+        return self._data
+        
+    # z3c.langauge.switch.IReadI18n
+    def getAvailableLanguages(self):
+        """See `z3c.langauge.switch.interfaces.IReadI18n`"""
+        keys = self._getData().keys()
+        keys.sort()
+        return keys
+
+    def getDefaultLanguage(self):
+        """See `z3c.langauge.switch.interfaces.IReadI18n`"""
+        return self._defaultLanguage
+
+    def getPreferedLanguage(self):
+        # evaluate the negotiator
+        language = None
+        request = getRequest()
+        negotiator = None
+        try:
+            negotiator = zapi.getUtility(INegotiator, name='', context=self)
+        except:
+            # can happens during tests without a site and sitemanager
+            pass
+        if request and negotiator:
+            language = negotiator.getLanguage(self.getAvailableLanguages(), request)
+        if language is None:
+            language = self.getDefaultLanguage()
+        if language is None:
+            # fallback language for functional tests, there we have a cookie request
+            language = 'en'
+        return language
+
+    def getAttribute(self, name, language=None):
+        # preconditions
+        if language is None:
+            language = self.getDefaultLanguage()
+
+        if not language in self.getAvailableLanguages():
+            raise KeyError(language)
+
+        # essentials
+        data = self._getData()[language]
+        return getattr(data, name)
+        
+    def queryAttribute(self, name, language=None, default=None):
+        try:
+            return self.getAttribute(name, language)
+        except:
+            return default
+
+    # z3c.langauge.switch.IReadI18n
+    def setDefaultLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        data = self._getData()
+        if language not in data:
+            raise ValueError(
+                'cannot set nonexistent language (%s) as default' % language)
+        self._defaultLanguage = language
+
+    def addLanguage(self, language, *args, **kw):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        if not args and not kw:
+            if self._defaultArgs() is not None:
+                args = self._defaultArgs()
+
+        self._get_or_add(language, *args, **kw)
+        notify(ObjectModifiedEvent(self))
+
+    def removeLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        data = self._getData()
+        if language == self.getDefaultLanguage():
+            raise ValueError('cannot remove default language (%s)' % language)
+        elif language not in data:
+            raise ValueError('cannot remove nonexistent language (%s)' 
+                % language)
+        else:
+            del data[language]
+            self._p_changed = True
+        notify(ObjectModifiedEvent(self))
+
+    def setAttributes(self, language, **kws):
+        # preconditions
+        if not language in self.getAvailableLanguages():
+            raise KeyError(language)
+
+        data = self._getData()
+        obj = data[language]
+        
+        for key in kws:
+            if not hasattr(obj, key):
+                raise KeyError(key)
+
+        # essentials
+        for key in kws:
+            setattr(obj, key, kws[key])
+        else:
+            self._p_changed = True           
+        notify(ObjectModifiedEvent(self))
+
+    # private helper methods
+    def _create(self, *args, **kw):
+        """Create a new subobject of the type document."""
+        factory = self._factory
+        obj = factory(*args, **kw)
+        notify(ObjectCreatedEvent(obj))
+        return obj
+
+    def _get(self, language):
+        """Helper function -- return a subobject for a given language,
+        and if it does not exist, return a subobject for the default
+        language.
+        """
+        data = self._getData()
+        obj = data.get(language, None)
+        if obj is None:
+            obj = data[self.getDefaultLanguage()]
+        return obj
+
+    def _get_or_add(self, language, *args, **kw):
+        """Helper function -- return a subobject for a given language,
+        and if it does not exist, create and return a new subobject.
+        """
+        data = self._getData()
+        language = self._getLang(language)
+        obj = data.get(language, None)
+        if obj is None:
+            obj = self._create(*args, **kw)
+            data[language] = obj
+            # this (ILocation info) is needed for the pickler used by the
+            # locationCopy method in the ObjectCopier class
+            obj.__parent__ = self
+            obj.__name__ = language
+            self._p_changed = 1
+        return obj
+
+    def _getLang(self, language):
+        """Returns the given language or the default language."""
+        if language == None:
+            language = self.getDefaultLanguage()
+
+        return language


Property changes on: z3c.language/trunk/src/z3c/language/switch/app.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/browser/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/browser/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/browser/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from z3c.language.switch.browser.views import ContentView


Property changes on: z3c.language/trunk/src/z3c/language/switch/browser/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/browser/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/browser/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/browser/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,22 @@
+<configure
+    xmlns:zope="http://namespaces.zope.org/zope"
+    xmlns="http://namespaces.zope.org/browser"
+    i18n_domain="z3c.language">
+
+  <page
+      for="*"
+      name="available_languages"
+      permission="zope.Public"
+      class=".views.ContentView"
+      attribute="getAvailableLanguages"
+      />
+
+  <page
+      for="*"
+      name="hasAvailableLanguages"
+      permission="zope.Public"
+      class=".views.ContentView"
+      attribute="hasAvailableLanguages"
+      />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/switch/browser/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/browser/views.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/browser/views.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/browser/views.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+from zope.app.zapi import getUtility
+
+from zope.publisher.browser import BrowserView
+
+from z3c.language.switch import IReadI18n
+from z3c.language.switch import IAvailableLanguages
+
+
+
+class ContentView(BrowserView):
+
+    implements(IAvailableLanguages)
+
+    def getAvailableLanguages(self):
+        """Returns a list of available languages if we provide IReadI18n."""
+
+        if IReadI18n.providedBy(self.context):
+            return self.context.getAvailableLanguages()
+        else:
+            return []
+
+
+    def hasAvailableLanguages(self):
+        """View for to check if we have i18n support on a context."""
+
+        if IReadI18n.providedBy(self.context):
+            return True
+        else:
+            return False


Property changes on: z3c.language/trunk/src/z3c/language/switch/browser/views.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,30 @@
+<configure 
+    xmlns="http://namespaces.zope.org/zope"
+    i18n_domain="z3c.language">
+
+  <include package=".generations" />
+
+  <interface interface="z3c.language.switch.IAvailableLanguagesVocabulary" />
+  <interface interface="z3c.language.switch.II18nLanguageSwitch" />
+  <interface interface="z3c.language.switch.II18n" />
+  <interface interface="z3c.language.switch.IReadI18n" />
+  <interface interface="z3c.language.switch.IWriteI18n" />
+
+
+  <!-- session language adapter -->
+  <class class=".adapters.I18nLanguageSwitch">
+    <require
+        permission="zope.View"
+        interface=".II18nLanguageSwitch"
+        />
+  </class>
+
+  <!-- i18n vocabularies -->
+  <utility
+      name="available languages"
+      component=".vocabulary.AvailableLanguagesVocabulary"
+      />
+
+  <include package=".browser" />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/switch/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/generations/__init__.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/generations/__init__.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/generations/__init__.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+"""
+$Id$
+"""
+
+__docformat__ = "reStructuredText"
+
+from zope.app.generations.generations import SchemaManager
+
+pkg = 'z3c.language.switch.generations'
+
+
+schemaManager = SchemaManager(
+    minimum_generation=0,
+    generation=0,
+    package_name=pkg)


Property changes on: z3c.language/trunk/src/z3c/language/switch/generations/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/generations/configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/generations/configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/generations/configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,9 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <utility
+      name="z3c.language.switch" 
+      provides="zope.app.generations.interfaces.ISchemaManager"
+      component=".schemaManager"
+      />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/switch/generations/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/interfaces.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/interfaces.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/interfaces.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,151 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+
+from zope.schema.interfaces import IVocabularyTokenized
+
+from z3c.i18n import MessageFactory as _
+
+
+
+# replacement for the unuseable II18nAware interface
+class IReadI18n(Interface):
+    """Let the language switch to the desired language.
+    
+    Support add and remove objects of a language.
+    """
+
+    def getDefaultLanguage():
+        """Return the default language."""
+
+    def getPreferedLanguage():
+        """Return the best matching language."""
+
+    def getAvailableLanguages():
+        """Find all the languages that are available."""
+
+    def getAttribute(name, language=None):
+        """Get name attribute of the language specific translation.
+
+        Parameter:
+
+        name -- Attribute name.
+
+        language -- Language code for example 'de'. If None the default language
+        is returned.
+
+        Return Value:
+
+        object -- Evaluate of the language specific data object.
+
+        Exceptions:
+
+        KeyError -- If attribute or language code does not exists.
+
+        """
+
+    def queryAttribute(name, language=None, default=None):
+        """Get name attribute of the language specific translation or default.
+
+        Parameter:
+
+        name -- Attribute name.
+
+        language -- Language code for example 'de'. If None the default language
+        is returned.
+
+        default -- Any object.
+
+        Return Value:
+
+        object -- Evaluate of the language specific data object or return default
+        if not found.
+
+        """
+
+
+
+class IWriteI18n(Interface):
+    """Let the language switch to the desired language.
+    
+    Support add and remove objects of a language.
+    """
+
+    def setDefaultLanguage(language):
+        """Set the default language, which will be used if the language is not
+        specified, or not available.
+        """
+
+    def addLanguage(language, *args, **kw):
+        """Add a i18n base object of the i18n type. The ``*args``, ``**kw`` 
+        can be used for the constructor of a new sub object.
+        """
+
+    def removeLanguage(language):
+        """Remove the object under the given language."""
+
+    def setAttributes(language, **kws):
+        """Set the language specific attribute of the translation defined by kw.
+
+        Parameter:
+
+        language -- Language code for example ``'de'``
+
+        kws -- Attributes that have to be set as keyword value pairs.
+
+        Exceptions:
+
+        KeyError -- If attribute does not exists.
+        
+        """
+
+
+
+class II18n(IReadI18n, IWriteI18n):
+    """Read and write support for I18n objects."""
+
+
+
+
+class II18nLanguageSwitch(Interface):
+    """Let the language switch to the desired language."""
+
+    def getLanguage():
+        """Returns the used language."""
+
+    def setLanguage(language):
+        """Sets the language for useing in the adapter."""
+
+
+
+class IAvailableLanguages(Interface):
+
+
+    def getAvailableLanguages():
+        """Returns a list of available languages if we provide IReadI18n."""
+
+    def hasAvailableLanguages():
+        """View for to check if we have i18n support on a context."""
+
+
+
+class IAvailableLanguagesVocabulary(IVocabularyTokenized):
+    """Available languages."""
+


Property changes on: z3c.language/trunk/src/z3c/language/switch/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/property.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/property.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/property.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,117 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+_marker = object()
+
+
+
+class I18nFieldProperty(object):
+    """Computed attributes based on schema fields and i18n implementation.
+
+    Field properties provide default values, data validation and error messages
+    based on data found in field meta-data.
+
+    Note that I18nFieldProperties can only be used for attributes stored in
+    a translation object. The class using this I18nFieldProperty must implement
+    z3c.langauge.switch.II18n.
+    """
+
+    def __init__(self, field, name=None):
+        if name is None:
+            name = field.__name__
+
+        self.__field = field
+        self.__name = name
+
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+
+        value = inst.queryAttribute(self.__name, inst.getPreferedLanguage(), _marker)
+        if value is _marker:
+            field = self.__field.bind(inst)
+            value = getattr(field, 'default', _marker)
+            if value is _marker:
+                raise AttributeError, self.__name
+
+        return value
+
+    def __set__(self, inst, value):
+        field = self.__field.bind(inst)
+        field.validate(value)
+        # make kws dict
+        kws = {}
+        kws[self.__name] = value
+        inst.setAttributes(inst.getPreferedLanguage(), **kws)
+
+    def __getattr__(self, name):
+        return getattr(self.__field, name)
+
+
+
+class I18nLanguageSwitchFieldProperty(object):
+    """Computed attributes based on schema fields and i18n language switch implementation.
+
+    Field properties provide default values, data validation and error messages
+    based on data found in field meta-data.
+
+    Note that I18nLanguageSwitchFieldProperty can only be used for attributes stored in
+    self.i18n.
+    
+    If you use this field in simply object, there is a adapter called 
+    'I18nLanguageSwitch' where the context attribute is setting to i18n. 
+    """
+
+    def __init__(self, field, name=None):
+        if name is None:
+            name = field.__name__
+
+        self.__field = field
+        self.__name = name
+
+    def __get__(self, inst, klass):
+        # essentails
+        if inst is None:
+            return self
+        i18n = inst.i18n
+        lang = inst.getLanguage()
+
+        value = i18n.queryAttribute(self.__name, lang, _marker)
+        if value is _marker:
+            field = self.__field.bind(inst)
+            value = getattr(field, 'default', _marker)
+            if value is _marker:
+                raise AttributeError, self.__name
+
+        return value
+
+    def __set__(self, inst, value):
+        # essentails
+        i18n = inst.i18n
+        lang = inst.getLanguage()
+
+        field = self.__field.bind(inst)
+        field.validate(value)
+        # make kws dict
+        kws = {}
+        kws[self.__name] = value
+        i18n.setAttributes(lang, **kws)
+
+    def __getattr__(self, name):
+        return getattr(self.__field, name)


Property changes on: z3c.language/trunk/src/z3c/language/switch/property.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/testing.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/testing.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/testing.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,336 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+
+from zope.interface.verify import verifyClass
+from zope.interface import implements
+from zope.interface import Interface
+
+from zope.app.testing import ztapi, placelesssetup
+
+from z3c.language.switch import IReadI18n
+from z3c.language.switch import IWriteI18n
+from z3c.language.switch import II18n
+from z3c.language.switch import II18nLanguageSwitch
+from z3c.testing import InterfaceBaseTest
+from z3c.testing import marker_pos
+from z3c.testing import marker_kws
+
+def sorted(list):
+    list.sort()
+    return list
+
+
+
+################################################################################
+#
+# Public Test implementations
+#
+################################################################################
+
+class IContentObject(Interface):
+    """IContentObject interface."""
+
+
+
+class II18nContentObject(Interface):
+    """II18nContentObject interface."""
+
+
+
+class ContentObject(object):
+    """Content type."""
+
+    implements(IContentObject)
+
+    __parent__ = __name__ = None
+    
+    _title = u''
+
+    def __init__(self, title=''):
+        self._title = title
+
+    def getTitle(self):
+        """Get the title of the object."""
+        return self._title
+
+    def setTitle(self, title):
+        """Set the title of the object."""
+        self._title = title
+
+    title = property(getTitle, setTitle)
+
+
+
+class I18nContentObject(object):
+    """i18n content type."""
+
+    implements(II18nContentObject, IReadI18n, IWriteI18n)
+
+    def __init__(self, title='', defaultLanguage=None):
+        self._data = {}
+        if defaultLanguage == None:
+            self._defaultLanguage = 'en'
+        else:
+            self._defaultLanguage = defaultLanguage
+        document = self._create(title)
+        self._data[self._defaultLanguage] = document
+
+    def getTitle(self, language=None):
+        """Get the title of the object."""
+        document = self._get_or_add(language)
+        return document.title
+
+    def setTitle(self, title, language=None):
+        """Set the title of the object."""
+        document = self._get_or_add(language)
+        document.title = title
+
+    title = property(getTitle, setTitle)
+
+    # IReadI18n interface
+    def getAvailableLanguages(self):
+        """See `z3c.langauge.switch.interfaces.IReadI18n`"""
+        keys = self._data.keys()
+        keys.sort()
+        return keys
+
+    def getDefaultLanguage(self):
+        """See `z3c.langauge.switch.interfaces.IReadI18n`"""
+        return self._defaultLanguage
+
+    # IWriteI18n interface
+    def setDefaultLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        if language not in self._data:
+            raise ValueError(
+                  'cannot set nonexistent language (%s) as default' % language)
+        self._defaultLanguage = language
+
+    def addLanguage(self, language, title=''):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        return self._get_or_add(language, title)
+
+    def removeLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.IWriteI18n`"""
+        if language == self.getDefaultLanguage():
+            raise ValueError('cannot remove default language (%s)' % language)
+        elif language not in self._data:
+            raise ValueError('cannot remove nonexistent language (%s)' 
+                % language)
+        else:
+            del self._data[language]
+            self._p_changed = True
+
+    # helper methods
+    def _create(self, title=''):
+        """Create a new subobject of the type document."""
+        return ContentObject(title)
+
+    def _get(self, language):
+        """Helper function -- return a subobject for a given language,
+        and if it does not exist, return a subobject for the default
+        language.
+        """
+        document = self._data.get(language)
+        if not document:
+            document = self._data[self.getDefaultLanguage()]
+        return document
+
+    def _get_or_add(self, language, title=''):
+        """Helper function -- return a subobject for a given language,
+        and if it does not exist, create and return a new subobject.
+        """
+        language = self._getLang(language)
+        document = self._data.get(language)
+        if not document:
+            document = self._create(title)
+            self._data[language] = document
+            self._p_changed = 1
+        return document
+
+    def _getLang(self, language):
+        """Returns the given language or the default language."""
+        if language == None:
+            language = self.getDefaultLanguage()
+
+        return language
+
+
+
+class I18nContentObjectLanguageSwitch(object):
+    """Language switch for I18nContentObject."""
+    
+    implements(II18nLanguageSwitch, II18nContentObject)
+
+    _language = 'en'
+
+    def __init__(self, context):
+        self.context = context
+        self._language = context.getDefaultLanguage()
+
+    # II18nLanguageSwitch interface
+    def getLanguage(self):
+        """See `z3c.langauge.switch.interfaces.II18nLanguageSwitch`"""
+        return self._language
+
+    def setLanguage(self, language):
+        """See `z3c.langauge.switch.interfaces.II18nLanguageSwitch`"""
+        self._language = language
+
+    # II18nContentObject interface
+    def getTitle(self):
+        """Get the title of the object."""
+        return self.context.getTitle(self.getLanguage())
+
+    def setTitle(self, title):
+        """Set the title of the object."""
+        self.context.setTitle(title, self.getLanguage())
+
+    title = property(getTitle, setTitle)
+
+
+
+################################################################################
+#
+# Public Base Tests
+#
+################################################################################
+
+class BaseTestII18n(InterfaceBaseTest):
+
+    def getTestInterface(self):
+        raise NotImplementedError, \
+            'Subclasses has to implement getTestInterface()'
+
+    def makeI18nTestObject(self, **kws):
+        kws['defaultLanguage'] = kws.get('defaultLanguage', 'de')
+        return self.makeTestObject(**kws)
+
+    # IReadI18n tests
+    def test_getAvailableLanguages(self):
+        i18n = self.makeI18nTestObject()
+        res = ['de']
+        self.assertEqual(sorted(i18n.getAvailableLanguages()), res)
+
+    def test_getDefaultLanguage(self):
+        i18n = self.makeI18nTestObject()
+        self.assertEqual(i18n.getDefaultLanguage(), 'de')
+
+    # IWriteI18n tests
+    def test_setDefaultLanguage(self):
+        i18n = self.makeI18nTestObject()
+        self.assertEqual(i18n.getDefaultLanguage(), 'de')
+        i18n.addLanguage('en')
+        i18n.setDefaultLanguage('en')
+        self.assertEqual(i18n.getDefaultLanguage(), 'en')
+
+    def test_addLanguage(self):
+        i18n = self.makeI18nTestObject()
+        i18n.addLanguage('at')
+        res = ['at', 'de']
+        self.assertEqual(sorted(i18n.getAvailableLanguages()), res)
+
+    def test_removeLanguage(self):
+        i18n = self.makeI18nTestObject()
+        i18n.addLanguage('fr')
+        res = ['de', 'fr']
+        self.assertEqual(sorted(i18n.getAvailableLanguages()), res)
+        i18n.removeLanguage('fr')
+        res = ['de']
+        self.assertEqual(sorted(i18n.getAvailableLanguages()), res)
+        self.assertRaises(ValueError, i18n.removeLanguage, 'de')
+        self.assertRaises(ValueError, i18n.removeLanguage, 'undefined')
+
+    def test_II18n_Interface(self):
+        i18n = self.makeI18nTestObject()
+        class_ = self.getTestClass()
+        self.failUnless(IReadI18n.implementedBy(class_))
+        self.failUnless(IWriteI18n.implementedBy(class_))
+        self.failUnless(II18n.implementedBy(class_))
+        self.failUnless(verifyClass(IReadI18n, class_))
+        self.failUnless(verifyClass(IWriteI18n, class_))
+        self.failUnless(verifyClass(II18n, class_))
+
+
+
+class BaseTestI18nLanguageSwitch(InterfaceBaseTest):
+
+    def getTestClass(self):
+        raise NotImplementedError, \
+            'Subclasses has to implement getTestClass()'
+
+    def getTestInterface(self):
+        raise NotImplementedError, \
+            'Subclasses has to implement getTestInterface()'
+
+    def getAdaptedClass(self):
+        raise NotImplementedError, \
+            'Subclasses has to implement getAdaptedClass()'
+    
+    def makeTestObject(self, object=None, *pos, **kws):
+        # provide default positional or keyword arguments
+        if self.getTestPos() is not marker_pos and not pos:
+            pos = self.getTestPos()
+
+        if self.getTestKws() is not marker_kws and not kws:
+            kws = self.getTestKws()
+       
+        testclass = self.getAdaptedClass()
+        iface = self.getTestInterface()
+        
+        if object is None:
+            # a class instance itself is the object to be tested.         
+            obj = testclass(*pos, **kws)
+            return iface(obj)
+
+        else:
+            # an adapted instance is the object to be tested. 
+            obj = testclass(object, *pos, **kws)
+            return iface(obj)
+
+    def setUp(self):
+        placelesssetup.setUp()
+        factory = self.getTestClass()
+        iface = self.getTestInterface()
+        required = self.getAdaptedClass()
+        # register language switch for test interface adapter
+        ztapi.provideAdapter(required, iface, factory)
+
+    def tearDown(self):
+        placelesssetup.tearDown()
+
+    def test_getLanguage(self):
+        obj = self.makeTestObject()
+        self.assertEqual(obj.getLanguage(), 'de')
+
+    def test_setLanguage(self):
+        obj = self.makeTestObject()
+        obj.setLanguage('fr')
+        self.assertEqual(obj.getLanguage(), 'fr')
+
+    def test_i18n_II18nLanguageSwitch_Interface(self):
+        class_ = self.getTestClass()
+        obj = self.makeTestObject()
+        iface = self.getTestInterface()
+        adapter = iface(obj)
+        self.failUnless(II18nLanguageSwitch.implementedBy(class_))
+        self.failUnless(verifyClass(II18nLanguageSwitch, class_))
+        self.failUnless(iface.providedBy(adapter))


Property changes on: z3c.language/trunk/src/z3c/language/switch/testing.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/tests.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/tests.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/tests.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import doctest
+import unittest
+
+from zope.testing import doctestunit
+
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctestunit.DocFileSuite('README.txt'),
+        doctestunit.DocFileSuite('app.py')
+        ))
+
+if __name__=='__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.language/trunk/src/z3c/language/switch/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/vocabulary.py
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/vocabulary.py	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/vocabulary.py	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2005 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.interface.declarations import implements
+from zope.interface import classProvides
+
+from zope.schema.interfaces import IVocabularyFactory
+from zope.schema.vocabulary import SimpleTerm
+from zope.schema.vocabulary import SimpleVocabulary
+
+from z3c.language.switch import IAvailableLanguagesVocabulary
+
+
+
+class AvailableLanguagesVocabulary(SimpleVocabulary):
+    """A vocabular of available languages from the context object."""
+
+    implements(IAvailableLanguagesVocabulary)
+
+    classProvides(IVocabularyFactory)
+
+    def __init__(self, context):
+        terms = []
+        
+        # returns available languages form the object itself
+        # but just after creation of the object
+        try:
+            languages = context.getAvailableLanguages()
+        except:
+            languages = []
+
+        for lang in languages:
+            terms.append(SimpleTerm(lang, lang, lang))
+
+        terms.sort(lambda lhs, rhs: cmp(lhs.title, rhs.title))
+        super(AvailableLanguagesVocabulary, self).__init__(terms)


Property changes on: z3c.language/trunk/src/z3c/language/switch/vocabulary.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.language/trunk/src/z3c/language/switch/z3c.language.switch-configure.zcml
===================================================================
--- z3c.language/trunk/src/z3c/language/switch/z3c.language.switch-configure.zcml	2006-08-21 11:13:50 UTC (rev 69714)
+++ z3c.language/trunk/src/z3c/language/switch/z3c.language.switch-configure.zcml	2006-08-21 11:20:38 UTC (rev 69715)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="z3c.language.switch" />
+
+</configure>


Property changes on: z3c.language/trunk/src/z3c/language/switch/z3c.language.switch-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list