[Checkins] SVN: zope.i18nmessage/trunk/ Initial implementation

Hanno Schlichting hannosch at hannosch.eu
Sat Aug 22 11:58:55 EDT 2009


Log message for revision 103085:
  Initial implementation
  

Changed:
  A   zope.i18nmessage/trunk/CHANGES.txt
  A   zope.i18nmessage/trunk/README.txt
  A   zope.i18nmessage/trunk/buildout.cfg
  A   zope.i18nmessage/trunk/setup.py
  A   zope.i18nmessage/trunk/src/
  A   zope.i18nmessage/trunk/src/zope/
  A   zope.i18nmessage/trunk/src/zope/__init__.py
  A   zope.i18nmessage/trunk/src/zope/i18nmessage/
  A   zope.i18nmessage/trunk/src/zope/i18nmessage/__init__.py
  A   zope.i18nmessage/trunk/src/zope/i18nmessage/message.py
  A   zope.i18nmessage/trunk/src/zope/i18nmessage/messages.txt
  A   zope.i18nmessage/trunk/src/zope/i18nmessage/tests.py

-=-
Added: zope.i18nmessage/trunk/CHANGES.txt
===================================================================
--- zope.i18nmessage/trunk/CHANGES.txt	                        (rev 0)
+++ zope.i18nmessage/trunk/CHANGES.txt	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,8 @@
+CHANGES
+=======
+
+1.0 (unreleased)
+----------------
+
+- Initial implementation based on zope.i18nmessageid but following the newer
+  gettext semantics as provided by the msgctxt support.


Property changes on: zope.i18nmessage/trunk/CHANGES.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/README.txt
===================================================================
--- zope.i18nmessage/trunk/README.txt	                        (rev 0)
+++ zope.i18nmessage/trunk/README.txt	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,49 @@
+Overview
+========
+
+To translate any text, we must be able to discover the source domain of the
+text. A source domain is an identifier that identifies a project that produces
+program source strings. Source strings occur as literals in python programs,
+text in templates, and some text in XML data. The project implies a source
+language and an application context.
+
+We can think of a source domain as a collection of messages and associated
+translation strings.
+
+We often need to create unicode strings that will be displayed by separate
+views. The view cannot translate the string without knowing its source domain.
+A string or unicode literal carries no domain information, therefore we use
+messages. Messages are unicode strings which carry a translation source domain
+and possibly a more specific translation context. They are created by a message
+factory. The message factory is created by calling ``MessageFactory`` with the
+source domain.
+
+This package provides facilities for *declaring* such messages within program
+source text; translation of the messages is the responsibility of the
+'zope.i18n' package.
+
+Relationship to zope.i18nmessageid
+----------------------------------
+
+This packages has a number of semantic differences to zope.i18nmessageid.
+
+Instead of advertising to use the msgid as a cryptic unique id for
+disambiguation of messages in the same domain, we provide an optional context
+attribute to do the same. This follows more modern gettext semantics and works
+with the msgctxt feature.
+
+So instead of doing::
+
+  Message(u'some-id', default=u'Some text')
+
+You write::
+
+  Message(u'Some text', context=u'some-id')
+
+but most often you will not provide a context at all::
+
+  Message(u'Some text')
+
+Messages created by this package also don't try to provide immutability or care
+about security concerns. This allows the package to avoid a C dependency. Use
+it with care in environments using zope.security proxies.


Property changes on: zope.i18nmessage/trunk/README.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/buildout.cfg
===================================================================
--- zope.i18nmessage/trunk/buildout.cfg	                        (rev 0)
+++ zope.i18nmessage/trunk/buildout.cfg	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,12 @@
+[buildout]
+develop = .
+parts = test python
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = zope.i18nmessage
+
+[python]
+recipe = zc.recipe.egg
+eggs = zope.i18nmessage
+interpreter = python


Property changes on: zope.i18nmessage/trunk/buildout.cfg
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/setup.py
===================================================================
--- zope.i18nmessage/trunk/setup.py	                        (rev 0)
+++ zope.i18nmessage/trunk/setup.py	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,54 @@
+##############################################################################
+#
+# Copyright (c) 2009 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.
+#
+##############################################################################
+"""Setup for zope.i18nmessage package
+"""
+
+import os
+
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(name='zope.i18nmessage',
+    version = '1.0dev',
+    author='Zope Corporation and Contributors',
+    author_email='zope-dev at zope.org',
+    description='Message Identifiers for internationalization',
+    long_description=(
+        read('README.txt')
+        + '\n\n' +
+        read('CHANGES.txt')
+        ),
+    keywords = "i18n message factory",
+    classifiers = [
+        'Development Status :: 5 - Production/Stable',
+        'Environment :: Web Environment',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: Zope Public License',
+        'Programming Language :: Python',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Topic :: Internet :: WWW/HTTP',
+        ],
+    license='ZPL 2.1',
+    url='http://pypi.python.org/pypi/zope.i18nmessage',
+    packages=find_packages('src'),
+    package_dir = {'': 'src'},
+    namespace_packages=['zope',],
+    tests_require = ['zope.testing'],
+    install_requires=['setuptools'],
+    include_package_data = True,
+    zip_safe = False,
+)


Property changes on: zope.i18nmessage/trunk/setup.py
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/src/zope/__init__.py
===================================================================
--- zope.i18nmessage/trunk/src/zope/__init__.py	                        (rev 0)
+++ zope.i18nmessage/trunk/src/zope/__init__.py	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)


Property changes on: zope.i18nmessage/trunk/src/zope/__init__.py
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/src/zope/i18nmessage/__init__.py
===================================================================
--- zope.i18nmessage/trunk/src/zope/i18nmessage/__init__.py	                        (rev 0)
+++ zope.i18nmessage/trunk/src/zope/i18nmessage/__init__.py	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2009 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.
+#
+##############################################################################
+"""i18n messages
+"""
+from zope.i18nmessage.message import Message, MessageFactory
+
+# import this as _ to create i18n messages in the zope domain
+ZopeMessageFactory = MessageFactory(u'zope')


Property changes on: zope.i18nmessage/trunk/src/zope/i18nmessage/__init__.py
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/src/zope/i18nmessage/message.py
===================================================================
--- zope.i18nmessage/trunk/src/zope/i18nmessage/message.py	                        (rev 0)
+++ zope.i18nmessage/trunk/src/zope/i18nmessage/message.py	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2009 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.
+#
+##############################################################################
+"""i18n messages
+"""
+
+class Message(unicode):
+
+    __slots__ = ('domain', 'context', 'mapping')
+
+    def __new__(cls, ustr, domain=None, context=None, mapping=None):
+        self = unicode.__new__(cls, ustr)
+        if isinstance(ustr, self.__class__):
+            domain = ustr.domain and ustr.domain[:] or domain
+            context = ustr.context and ustr.context[:] or context
+            mapping = ustr.mapping and ustr.mapping.copy() or mapping
+            ustr = unicode(ustr)
+        self.domain = domain
+        self.context = context
+        self.mapping = mapping
+        return self
+
+    def __reduce__(self):
+        return self.__class__, self.__getstate__()
+
+    def __getstate__(self):
+        return unicode(self), self.domain, self.context, self.mapping
+
+
+class MessageFactory(object):
+    """Factory for creating i18n messages."""
+
+    def __init__(self, domain):
+        self._domain = domain
+
+    def __call__(self, ustr, context=None, mapping=None):
+        return Message(ustr, self._domain, context, mapping)


Property changes on: zope.i18nmessage/trunk/src/zope/i18nmessage/message.py
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/src/zope/i18nmessage/messages.txt
===================================================================
--- zope.i18nmessage/trunk/src/zope/i18nmessage/messages.txt	                        (rev 0)
+++ zope.i18nmessage/trunk/src/zope/i18nmessage/messages.txt	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,115 @@
+I18n Messages
+=============
+
+Rationale
+---------
+
+To translate any text, we must be able to discover the source domain of the
+text. A source domain is an identifier that identifies a project that produces
+program source strings. Source strings occur as literals in python programs,
+text in templates, and some text in XML data. The project implies a source
+language and an application context.
+
+We can think of a source domain as a collection of messages and associated
+translation strings.
+
+We often need to create unicode strings that will be displayed by separate
+views. The view cannot translate the string without knowing its source domain.
+A string or unicode literal carries no domain information, therefore we use
+messages. Messages are unicode strings which carry a translation source domain
+and possibly a more specific translation context. They are created by a message
+factory. The message factory is created by calling ``MessageFactory`` with the
+source domain.
+
+ZopeMessageFactory
+------------------
+
+  >>> from zope.i18nmessage import ZopeMessageFactory as _z_
+  >>> foo = _z_(u'foo')
+  >>> foo.domain
+  u'zope'
+
+
+Example
+-------
+
+In this example, we create a message factory and assign it to _. By convention,
+we use _ as the name of our factory to be compatible with translatable string
+extraction tools such as xgettext. We then call _ with a string that needs to
+be translatable:
+
+  >>> from zope.i18nmessage import MessageFactory, Message
+  >>> _ = MessageFactory(u"futurama")
+  >>> robot = _(u"${name} is a robot.")
+
+Messages at first seem like they are unicode strings:
+
+  >>> robot
+  u'${name} is a robot.'
+  >>> isinstance(robot, unicode)
+  True
+
+The additional domain, context and mapping information is available through
+attributes:
+
+  >>> robot.domain
+  u'futurama'
+  >>> robot.context is None
+  True
+  >>> robot.mapping
+
+You can make a new message object from an existing one:
+
+  >>> new_robot = Message(robot, mapping={u'name': u'Bender'})
+  >>> new_robot
+  u'${name} is a robot.'
+  >>> new_robot.domain
+  u'futurama'
+  >>> new_robot.context is None
+  True
+  >>> new_robot.mapping
+  {u'name': u'Bender'}
+
+Last but not least, messages are reduceable for pickling:
+
+  >>> callable, args = new_robot.__reduce__()
+  >>> callable is Message
+  True
+  >>> args
+  (u'${name} is a robot.', u'futurama', None, {u'name': u'Bender'})
+
+  >>> fembot = Message(u'fembot')
+  >>> callable, args = fembot.__reduce__()
+  >>> callable is Message
+  True
+  >>> args
+  (u'fembot', None, None, None)
+
+
+More specific message context
+-----------------------------
+
+Sometimes a translation domain can be very broad, so we might need to
+differentiate between the same message text based on a narrower context.
+
+  >>> from zope.i18nmessage import MessageFactory, Message
+  >>> _ = MessageFactory(u"shopping")
+
+Especially if we have very short labels like for example in menu entries or on
+button labels, it is sometimes hard to differentiate them.
+
+  >>> money = _(u'Save', context=u'Save some money')
+
+  >>> money
+  u'Save'
+  >>> money.context
+  u'Save some money'
+
+Or in the same domain we might have:
+
+  >>> change = _(u'Save', context=u'Save the changes')
+
+  >>> change
+  u'Save'
+  >>> change.context
+  u'Save the changes'


Property changes on: zope.i18nmessage/trunk/src/zope/i18nmessage/messages.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zope.i18nmessage/trunk/src/zope/i18nmessage/tests.py
===================================================================
--- zope.i18nmessage/trunk/src/zope/i18nmessage/tests.py	                        (rev 0)
+++ zope.i18nmessage/trunk/src/zope/i18nmessage/tests.py	2009-08-22 15:58:55 UTC (rev 103085)
@@ -0,0 +1,22 @@
+##############################################################################
+#
+# Copyright (c) 2009 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.
+#
+##############################################################################
+"""Message tests.
+"""
+import unittest
+from zope.testing.doctestunit import DocFileSuite
+
+def test_suite():
+    return unittest.TestSuite((
+        DocFileSuite('messages.txt', package='zope.i18nmessage'),
+        ))


Property changes on: zope.i18nmessage/trunk/src/zope/i18nmessage/tests.py
___________________________________________________________________
Added: svn:eol-style
   + native



More information about the Checkins mailing list