Commit 4f7df40f authored by Hanno Schlichting's avatar Hanno Schlichting

Removed bridging code from Product.Five for PlacelessTranslationService and...

Removed bridging code from Product.Five for PlacelessTranslationService and Localizer. Neither of the two is actually using this anymore.
parent 19cb96ff
......@@ -23,6 +23,9 @@ Known issues
Restructuring
+++++++++++++
- Removed bridging code from Product.Five for PlacelessTranslationService
and Localizer. Neither of the two is actually using this anymore.
- Removed the specification of `SOFTWARE_HOME` and `ZOPE_HOME` from the
standard instance scripts.
[hannosch]
......
......@@ -5,8 +5,6 @@ TODO
v1.2
----
* backport r22057 from Five-1.3 branch: fix Localizer unit test problem
* i18n and translation of utilities/browser/*pt
* can we stop using zLOG and use the logging package? please?
......
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a Localizer domain -->
<p i18n:domain="fivetest" i18n:translate="">This is a message</p>
<p i18n:domain="default" i18n:translate="">Object actions</p>
</body>
</html>
##############################################################################
#
# Copyright (c) 2005 Zope Corporation 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.
#
##############################################################################
"""Test the Localizer language integration for CPS. This test
requires a full blown CPS installation to run. It is therefore
prefixed with ``cps_`` so it won't be picked up by the test runner.
$Id$
"""
def test_suite():
from Testing.ZopeTestCase import installProduct, FunctionalDocFileSuite
installProduct('Five')
installProduct('BTreeFolder2')
installProduct('CMFCalendar')
installProduct('CMFCore')
installProduct('CMFDefault')
installProduct('CMFTopic')
installProduct('DCWorkflow')
installProduct('Localizer')
installProduct('MailHost')
installProduct('CPSCore')
installProduct('CPSDefault')
installProduct('CPSDirectory')
installProduct('CPSUserFolder')
installProduct('TranslationService')
installProduct('SiteAccess')
# these products should (and used to be) be optional, but they
# aren't right now.
installProduct('CPSForum')
installProduct('CPSSubscriptions')
installProduct('CPSNewsLetters')
installProduct('CPSSchemas')
installProduct('CPSDocument')
installProduct('PortalTransforms')
installProduct('Epoz')
# optional products, but apparently still needed...
installProduct('CPSRSS')
installProduct('CPSChat')
installProduct('CPSCalendar')
installProduct('CPSCollector')
installProduct('CPSMailBoxer')
return FunctionalDocFileSuite('cps_test_localizer.txt',
package='Products.Five.browser.tests')
Localizer languages
===================
Before we start, we need to set up a manager user to be able to create
the portal:
>>> uf = self.folder.acl_users
>>> uf._doAddUser('manager', 'r00t', ['Manager'], [])
We need to 1) configure the Zope 3 i18n message catalogs, 2) make the
CPS portal traversable, 3) register the Localizer languagees adapter
and 4) register our test page:
>>> configure_zcml = """
... <configure
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser"
... xmlns:five="http://namespaces.zope.org/five"
... xmlns:i18n="http://namespaces.zope.org/i18n"
... >
... <configure package="Products.Five.tests">
... <i18n:registerTranslations directory="locales" />
... </configure>
...
... <adapter
... for="zope.publisher.interfaces.http.IHTTPRequest"
... provides="zope.i18n.interfaces.IUserPreferredLanguages"
... factory="Products.Five.i18n.LocalizerLanguages"
... />
...
... <configure package="Products.Five.browser.tests">
... <browser:page
... for="*"
... template="cps_test_localizer.pt"
... name="cps_test_localizer.html"
... permission="zope2.View"
... />
... </configure>
... </configure>
... """
>>> from Products.Five import zcml
>>> zcml.load_string(configure_zcml)
Create a CPS portal. We print an additional line before creating it
because PortalTransforms might print stuff to stdout and doctest
doesn't allow us to ellide a first line.
>>> print "Ignore lines after me"; print http(r"""
... POST /test_folder_1_/manage_addProduct/CPSDefault/manage_addCPSDefaultSite HTTP/1.1
... Authorization: Basic manager:r00t
... Content-Length: 269
... Content-Type: application/x-www-form-urlencoded
...
... id=cps&title=CPS+Portal&description=&manager_id=manager&manager_sn=CPS+manager&manager_givenName=Manager&manager_email=root%40localhost&manager_password=root&manager_password_confirmation=root&langs_list%3Alist=en&langs_list%3Alist=fr&langs_list%3Alist=de&submit=Create""")
Ignore lines after me
...
HTTP/1.1 200 OK
...
Now for some actual testing... Our test page is a simple ZPT
translating two messages from different domains. The first domain is
a Zope 3 style one, the second one comes from Localizer.
Both systems should yield the same default language (English) when no
language is specified whatsoever:
>>> print http(r"""
... GET /test_folder_1_/cps/cps_test_localizer.html HTTP/1.1
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a Localizer domain -->
<p>This is a message</p>
<p>Object actions</p>
</body>
</html>
Both systems should honour the HTTP ``Accept-Language`` header in the
same way:
>>> print http(r"""
... GET /test_folder_1_/cps/cps_test_localizer.html HTTP/1.1
... Accept-Language: de
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a Localizer domain -->
<p>Dies ist eine Nachricht</p>
<p>Objekt Aktionen</p>
</body>
</html>
Both systems should also honour Localizer-specific ways of determining
the language, for example the ``LOCALIZER_LANGUAGE`` cookie:
>>> print http(r"""
... GET /test_folder_1_/cps/cps_test_localizer.html HTTP/1.1
... Accept-Language: de
... Cookie: LOCALIZER_LANGUAGE=en
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a Localizer domain -->
<p>This is a message</p>
<p>Object actions</p>
</body>
</html>
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a PTS domain -->
<p i18n:domain="fivetest" i18n:translate="">This is a message</p>
<p i18n:domain="PlacelessTranslationService" i18n:translate="">Reload this catalog</p>
</body>
</html>
##############################################################################
#
# Copyright (c) 2005 Zope Corporation 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.
#
##############################################################################
"""Test the PTS language integration.
$Id$
"""
def test_suite():
from Testing.ZopeTestCase import installProduct, FunctionalDocFileSuite
installProduct('Five')
installProduct('PlacelessTranslationService')
return FunctionalDocFileSuite('pts_test_languages.txt',
package='Products.Five.browser.tests')
PTS languages
=============
Before we start, we need to set up a manager user to be able to create
the portal:
>>> uf = self.folder.acl_users
>>> uf._doAddUser('manager', 'r00t', ['Manager'], [])
We need to 1) configure the Zope 3 i18n message catalogs, 3) register
the PTS languagees adapter and 3) register our test page:
>>> configure_zcml = """
... <configure
... xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser"
... xmlns:i18n="http://namespaces.zope.org/i18n"
... >
... <configure package="Products.Five.tests">
... <i18n:registerTranslations directory="locales" />
... </configure>
...
... <adapter
... for="zope.publisher.interfaces.http.IHTTPRequest"
... provides="zope.i18n.interfaces.IUserPreferredLanguages"
... factory="Products.Five.i18n.PTSLanguages"
... />
...
... <configure package="Products.Five.browser.tests">
... <browser:page
... for="Products.Five.interfaces.IFolder"
... template="pts_test_languages.pt"
... name="pts_test_languages.html"
... permission="zope2.View"
... />
... </configure>
... </configure>
... """
>>> from Products.Five import zcml
>>> zcml.load_string(configure_zcml)
Finally, we need a traversable folder so that the test page we
registered is found:
>>> from Products.Five.tests.testing import manage_addFiveTraversableFolder
>>> manage_addFiveTraversableFolder(self.folder, 'ftf')
Now for some actual testing... Our test page is a simple ZPT
translating two messages from different domains. The first domain is
a Zope 3 style one, the second one comes from PTS.
Both systems should yield the same default language (English) when no
language is specified whatsoever:
>>> print http(r"""
... GET /test_folder_1_/ftf/pts_test_languages.html HTTP/1.1
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a PTS domain -->
<p>This is a message</p>
<p>Reload this catalog</p>
</body>
</html>
Both systems should honour the HTTP ``Accept-Language`` header in the
same way:
>>> print http(r"""
... GET /test_folder_1_/ftf/pts_test_languages.html HTTP/1.1
... Accept-Language: de
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a PTS domain -->
<p>Dies ist eine Nachricht</p>
<p>Diesen Katalog neu einlesen</p>
</body>
</html>
Both systems should also honour Localizer-specific ways of determining
the language, for example the ``pts_language`` cookie...
>>> print http(r"""
... GET /test_folder_1_/ftf/pts_test_languages.html HTTP/1.1
... Accept-Language: de
... Cookie: pts_language=en
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a PTS domain -->
<p>This is a message</p>
<p>Reload this catalog</p>
</body>
</html>
... and the ``language`` form field...
>>> print http(r"""
... GET /test_folder_1_/ftf/pts_test_languages.html?language=en HTTP/1.1
... Accept-Language: de
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a PTS domain -->
<p>This is a message</p>
<p>Reload this catalog</p>
</body>
</html>
... and both the ``pts_language`` cookie and the ``language`` form field:
>>> print http(r"""
... GET /test_folder_1_/ftf/pts_test_languages.html?language=de HTTP/1.1
... Accept-Language: en
... Cookie: pts_language=fr
... """)
HTTP/1.1 200 OK
...
<html>
<body>
<!-- fivetest is a Zope 3 style i18n domain, default is a PTS domain -->
<p>Dies ist eine Nachricht</p>
<p>Diesen Katalog neu einlesen</p>
</body>
</html>
......@@ -10,8 +10,7 @@ That means, Five always assumes control over ZPT i18n. When a certain
domain has not been registered the Zope 3 way, Five's translation
service will see that the utility lookup fails and use the next
available fallback translation service. In case of no other
translation service installed, that is just a dummy fallback. In case
you have Localizer and PTS installed, it falls back to that.
translation service installed, that is just a dummy fallback.
To register Zope 3 style translation domains, use the following ZCML
statement::
......@@ -24,53 +23,3 @@ http://namespaces.zope.org/i18n namespace identifier. The directory
locale directory layout`__.
.. __: http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC148
Preferred languages and negotiation
-----------------------------------
Fallback translation services such as PTS and Localizer have their own
way of determining the user-preferred languages and negotiating that
with the available languages in the respective domain. Zope 3
translation domains typically adapt the request to
IUserPreferredLanguages to get a list of preferred languages; then
they use the INegotiator utility to negotiate between the preferred
and available languages.
The goal of the sprint was to allow both fallback translation services
(PTS, Localizer) and Zope 3 translation domains come to the same
conclusion regarding which language should be chosen. The use case is
that you have a site running Localizer or PTS and a bunch of "old"
products using either one of those for translation. Now you have an
additional, "new" Five-based product using Zope 3 translation domains.
Most of the time, a page contains user messages from more than one
domain, so you would all domains be translated to the same language.
Adjusting behaviour to your environment
---------------------------------------
The default behaviour for choosing languages in Five is the one of
Zope 3: analyze the Accept-Language HTTP header and nothing more. In
addition, Five providees ``IUserPreferredLanguages`` adapters for
Localizer and PTS that choose languages the exact same way Localizer
or PTS would. So, if you're using Five in a Localizer-environment,
you need this in your product's ``overrides.zcml``::
<adapter
for="zope.publisher.interfaces.http.IHTTPRequest"
provides="zope.i18n.interfaces.IUserPreferredLanguages"
factory="Products.Five.i18n.LocalizerLanguages"
/>
If you're using PTS::
<adapter
for="zope.publisher.interfaces.http.IHTTPRequest"
provides="zope.i18n.interfaces.IUserPreferredLanguages"
factory="Products.Five.i18n.PTSLanguages"
/>
That way Zope 3 translation domains will always come to the same
conclusion regarding the language as your original translation service
would.
......@@ -16,11 +16,8 @@
$Id$
"""
from Acquisition import aq_get
from zope.interface import implements
from zope.i18n.interfaces import IFallbackTranslationDomainFactory
from zope.i18n.interfaces import ITranslationDomain
from zope.i18n.interfaces import IUserPreferredLanguages
from zope.i18n.negotiator import normalize_lang
from zope.component import queryUtility
from zope.i18nmessageid import Message
from zope.publisher.interfaces.browser import IBrowserRequest
......@@ -69,44 +66,5 @@ class FiveTranslationService:
return util.translate(msgid, mapping=mapping, context=context,
target_language=target_language, default=default)
class LocalizerLanguages(object):
"""Languages adapter that chooses languages according to Localizer
settings."""
implements(IUserPreferredLanguages)
def __init__(self, context):
self.context = context
def getPreferredLanguages(self):
if not hasattr(self.context, 'AcceptLanguage'):
return []
accept_language = self.context.AcceptLanguage
langs = []
for lang, node in accept_language.children.items():
# Localizer may use xx_YY and xx-YY as language codes,
# while Zope expect xx-yy only, so we normalize the code here.
langs.append((node.get_quality(), normalize_lang(lang)))
langs.extend([(n.get_quality(), l) for l, n
in node.children.items()])
langs.sort()
langs.reverse()
langs = [l for q, l in langs]
if '' in langs:
langs.remove('')
return langs
class PTSLanguages(object):
"""Languages adapter that chooses languages like
PlacelessTranslationService."""
implements(IUserPreferredLanguages)
def __init__(self, context):
self.context = context
def getPreferredLanguages(self):
from Products.PlacelessTranslationService.Negotiator import getLangPrefs
return getLangPrefs(self.context)
# Hook that will be used by Products.PageTemplates.GlobalTranslationService
_fallback_translation_service = None
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment