This add-on provides support for content in multiple languages
(multilingual). It's compatible with Plone 4.2 or better with
`Dexterity <http://plone.org/products/dexterity>`_ content only.
Skip to `history`_ to learn about other add-ons that provide a similar
functionality.
Found a bug? Please use the `issue tracker
<https://github.com/collective/collective.multilingual/issues>`_.
.. image:: https://secure.travis-ci.org/collective/collective.multilingual.png
:target: http://travis-ci.org/collective/collective.multilingual
Usage
=====
To make a content type multilingual-aware, enable the "Multilingual"
behavior using the control panel.
The primary interaction is through a new *translate* menu which is
available for content items for which the behavior is enabled.
.. note:: Plone only includes the default language in the list of
supported languages. Visit the *language tool* in the ZMI to
add more languages to the list.
The translate menu lists each of the supported languages and links to
either the default view (if already translated), or an add form.
If a language folder (see below) does not exist for the chosen
language, the user will first be prompted to create one, using the
"Setup language folder" form. In most cases, the user can click
straight through to the add form: sensible form defaults are provided.
Plone in multiple languages
===========================
Out of the box, Plone supports a language setup where language in the
default language lives in the root:
``/`` ⇐ *default content*
This is also the root for language-neutral content. For other
languages, content in this setup lives in:
``/<language-id>/`` ⇐ *content in other language*
The *language id* is the `two-letter country code
<http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2>`_. For instance, for
Denmark this is ``"da"``.
We'll call these *language folders*. Plone can be set up to
automatically change the language of the entire user interface to that
of the language folder when the user visits a page contained below it.
Setting up a language folder
----------------------------
You can either set up language folders manually, or use the "Setup
language folder" form which is shown when you try to add a translation
for a content in a language for which a language folder does not
exist.
In both cases, you can use any content type which is a "container" (it
can contain other items). This is typically a folder. The most common
container type will be suggested by the "Setup language folder" form.
Note that a language folder is a navigation root. The
``INavigationRoot`` interface is automatically added as a marker
interface to signal this to Plone's user interface. In practical
terms, this means for instance that the navigation portlet will use
the language folder as the "root" content item.
Translation of default pages
----------------------------
In Plone, a default page can be selected for a container in which case
the page is shown instead of the container as the *default view*.
Since Plone's user interface shows a single interface for the
composition of a container and a default page, we require that the
container is translated before the default page.
The translation relationship
----------------------------
The data structure that records the translation relationship between
content is a `directed acyclic graph
<http://en.wikipedia.org/wiki/Directed_acyclic_graph>`_:
Every vertex is a content item, and edges are a translation from one
language to another. For example, original content in English might
first be translated into German, and then from this translation, into
French. This would be a graph with three vertices and two edges.
In the content model, this is implemented as the ``translations`` set
relation where the UUID (universally unique identifier) is used as the
content item reference value.
Plone comes with a behavior that adds a language setting to content
items, and this behavior must be enabled in order to translate
content.
API
===
The interface ``ITranslationGraph`` provides a view into the
translation graph for a context that provides the ``IMultilingual``
interface (implemented by the "Multilingual" behavior).
For each content object (this will be referred to in the following as
the ``context``) We can turn the graph into a mapping from language
ids to content objects, each of which is the ``context`` in some
translation:
>>> graph = ITranslationGraph(context)
>>> translations = graph.getTranslations()
The ``translations`` returned are a list of ``(language_id, content)``
which we can pass to the ``dict`` constructor to turn it into a
mapping object. Note that ``context`` is omitted.
>>> mapping = dict(translations)
For some applications, we want to establish a relation for each of the
supported languages to allow a user or visitor to get to the *nearest*
content object appearing in a supported language of choice. In this
situation, nearest will be defined as the closest ancestor
translation:
>>> nearest = graph.getNearestTranslations()
The ``nearest`` mapping is used to generate the "Translate" menu that
let's a contributor or editor navigate between the different
translations of a content object.
It's also used in the language selection viewlet which appears in
Plone when cookie-based language selection is enabled (see the
language tool for more information).
History
=======
In 2004, Jarn (formerly Plone Solutions) released `LinguaPlone
<http://pypi.python.org/pypi/Products.LinguaPlone>`_ which, although
still compatible with recent Plone releases, is now in legacy
status. It's recommended that you use this package if you have
`Archetypes <http://plone.org/products/archetypes>`_ content only.
In 2005, Ramon Navarro Bosch <r.navarro@iskra.cat> organized a sprint
in Girona on the subject of multilingual content in Plone. The idea
was to take advantage of the component architecture
(i.e. ``zope.interface`` and ``zope.component``) from the `Zope
Toolkit <http://docs.zope.org/zopetoolkit/>`_ to model an architecture
that could realistically support the diverse requirements for
multilingual content. The implementation of this architecture has been
an on-going process, but as of this writing, beta releases are
available for testing. The `plone.app.multilingual
<http://pypi.python.org/pypi/plone.app.multilingual>`_ (or PAM) pulls
in the required dependencies.
Note that PAM supports both Archetypes and Dexterity content. It also
tries to provide the user experience from LinguaPlone so that users
familiar with this add-on from previous versions of Plone will quickly
be able to use it.
Frequently Asked Questions
==========================
How does *collective.multilingual* compare to *plone.multilingual*?
This add-on is a brand new implementation. It's an *alternative* to
the existing solutions.
The most important difference is that ``collective.multilingual`` is
built for Plone 4. It fully benefits from the new features included
in this release.
The newer platform arguably makes the implementation simple, and
this is not just a good thing, it also makes it much easier to
maintain the software as a community.
There's another key difference: *less features*. There is no compare
view, and no integration with external translation tools. It's not
that we don't want to be "feature complete", but some of these
features are already provided by the web browser and it's not
necessarily a good thing to try and implement these in Plone.
In short, if you're *not* using the Archetypes content type
framework (and you really shouldn't be, if you have a choice), then
``collective.multilingual`` is probably going to work well.
What's a *canonical item*?
This is an item that you have created using Plone's *add* menu and
which has been translated into one or more languages.
Must I set a language for my content?
No. If you don't set the language field, the language is considered
neutral. At any given time, this effectively means the site's
default language.
Can I have language-independent fields?
Yes. You can set a value of ``True`` for the tagged value
``"plone.autoform.languageindependent"`` or use the included utility
function::
from collective.multilingual.interfaces import setLanguageIndependent
from plone.app.dexterity.behaviors.metadata import IDublinCore
setLanguageIndependent(
IDublinCore['contributors'],
IDublinCore['creators'],
IDublinCore['rights'],
)
This is not just an example. These fields are actually set as
language-independent.
Note that when a field is language-independent, changes are copied
into all the content items in the corresponding translation graph.
What's the language of newly created content?
There's a setting in Plone which decides whether this is unset
(neutral), or set to the language which is currently the default.
If content is created using the translate menu, then the language
form default will be provided automatically.
Changes
=======
2.0 (unreleased)
----------------
- Fall back to English language names when the localized list offered
by Zope does not provide one.
[malthe]
- Plone 5.2 and Python 3 support.
[thet]
- Language switcher: Do not render a link for the current language.
[thet]
1.0.1 (2016-03-30)
------------------
- Fix issue where a widget that was updated multiple times would
result in a circular translation reference.
[malthe]
- Fix issue where translating _into_ the default language would ignore translated parents
and place the new translation in the site root.
[tmog]
- Always show "Clear..." and "This is a translation of..." menu items for context, even if context is a default page.
[tmog]
- check to make sure we do not add multiple translations for one language. Even if one is neutral and the other is not.
[tmog]
- Initial public release.
Raw data
{
"_id": null,
"home_page": "",
"name": "collective.multilingual",
"maintainer": "",
"docs_url": null,
"requires_python": ">=2.7,!=3.6.*,<=4.0",
"maintainer_email": "",
"keywords": "plone multilingual dexterity",
"author": "Malthe Borch",
"author_email": "mborch@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/1c/bf/b6298f696e6c31cd7031f3feae6c877f2b60d2773454e419501480e9a711/collective.multilingual-2.0.tar.gz",
"platform": null,
"description": "This add-on provides support for content in multiple languages\n(multilingual). It's compatible with Plone 4.2 or better with\n`Dexterity <http://plone.org/products/dexterity>`_ content only.\n\nSkip to `history`_ to learn about other add-ons that provide a similar\nfunctionality.\n\nFound a bug? Please use the `issue tracker\n<https://github.com/collective/collective.multilingual/issues>`_.\n\n.. image:: https://secure.travis-ci.org/collective/collective.multilingual.png\n :target: http://travis-ci.org/collective/collective.multilingual\n\n\nUsage\n=====\n\nTo make a content type multilingual-aware, enable the \"Multilingual\"\nbehavior using the control panel.\n\nThe primary interaction is through a new *translate* menu which is\navailable for content items for which the behavior is enabled.\n\n.. note:: Plone only includes the default language in the list of\n supported languages. Visit the *language tool* in the ZMI to\n add more languages to the list.\n\nThe translate menu lists each of the supported languages and links to\neither the default view (if already translated), or an add form.\n\nIf a language folder (see below) does not exist for the chosen\nlanguage, the user will first be prompted to create one, using the\n\"Setup language folder\" form. In most cases, the user can click\nstraight through to the add form: sensible form defaults are provided.\n\n\nPlone in multiple languages\n===========================\n\nOut of the box, Plone supports a language setup where language in the\ndefault language lives in the root:\n\n ``/`` \u21d0 *default content*\n\nThis is also the root for language-neutral content. For other\nlanguages, content in this setup lives in:\n\n ``/<language-id>/`` \u21d0 *content in other language*\n\nThe *language id* is the `two-letter country code\n<http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2>`_. For instance, for\nDenmark this is ``\"da\"``.\n\nWe'll call these *language folders*. Plone can be set up to\nautomatically change the language of the entire user interface to that\nof the language folder when the user visits a page contained below it.\n\nSetting up a language folder\n----------------------------\n\nYou can either set up language folders manually, or use the \"Setup\nlanguage folder\" form which is shown when you try to add a translation\nfor a content in a language for which a language folder does not\nexist.\n\nIn both cases, you can use any content type which is a \"container\" (it\ncan contain other items). This is typically a folder. The most common\ncontainer type will be suggested by the \"Setup language folder\" form.\n\nNote that a language folder is a navigation root. The\n``INavigationRoot`` interface is automatically added as a marker\ninterface to signal this to Plone's user interface. In practical\nterms, this means for instance that the navigation portlet will use\nthe language folder as the \"root\" content item.\n\n\nTranslation of default pages\n----------------------------\n\nIn Plone, a default page can be selected for a container in which case\nthe page is shown instead of the container as the *default view*.\n\nSince Plone's user interface shows a single interface for the\ncomposition of a container and a default page, we require that the\ncontainer is translated before the default page.\n\n\nThe translation relationship\n----------------------------\n\nThe data structure that records the translation relationship between\ncontent is a `directed acyclic graph\n<http://en.wikipedia.org/wiki/Directed_acyclic_graph>`_:\n\n Every vertex is a content item, and edges are a translation from one\n language to another. For example, original content in English might\n first be translated into German, and then from this translation, into\n French. This would be a graph with three vertices and two edges.\n\nIn the content model, this is implemented as the ``translations`` set\nrelation where the UUID (universally unique identifier) is used as the\ncontent item reference value.\n\nPlone comes with a behavior that adds a language setting to content\nitems, and this behavior must be enabled in order to translate\ncontent.\n\n\nAPI\n===\n\nThe interface ``ITranslationGraph`` provides a view into the\ntranslation graph for a context that provides the ``IMultilingual``\ninterface (implemented by the \"Multilingual\" behavior).\n\nFor each content object (this will be referred to in the following as\nthe ``context``) We can turn the graph into a mapping from language\nids to content objects, each of which is the ``context`` in some\ntranslation:\n\n>>> graph = ITranslationGraph(context)\n>>> translations = graph.getTranslations()\n\nThe ``translations`` returned are a list of ``(language_id, content)``\nwhich we can pass to the ``dict`` constructor to turn it into a\nmapping object. Note that ``context`` is omitted.\n\n>>> mapping = dict(translations)\n\nFor some applications, we want to establish a relation for each of the\nsupported languages to allow a user or visitor to get to the *nearest*\ncontent object appearing in a supported language of choice. In this\nsituation, nearest will be defined as the closest ancestor\ntranslation:\n\n>>> nearest = graph.getNearestTranslations()\n\nThe ``nearest`` mapping is used to generate the \"Translate\" menu that\nlet's a contributor or editor navigate between the different\ntranslations of a content object.\n\nIt's also used in the language selection viewlet which appears in\nPlone when cookie-based language selection is enabled (see the\nlanguage tool for more information).\n\n\nHistory\n=======\n\nIn 2004, Jarn (formerly Plone Solutions) released `LinguaPlone\n<http://pypi.python.org/pypi/Products.LinguaPlone>`_ which, although\nstill compatible with recent Plone releases, is now in legacy\nstatus. It's recommended that you use this package if you have\n`Archetypes <http://plone.org/products/archetypes>`_ content only.\n\nIn 2005, Ramon Navarro Bosch <r.navarro@iskra.cat> organized a sprint\nin Girona on the subject of multilingual content in Plone. The idea\nwas to take advantage of the component architecture\n(i.e. ``zope.interface`` and ``zope.component``) from the `Zope\nToolkit <http://docs.zope.org/zopetoolkit/>`_ to model an architecture\nthat could realistically support the diverse requirements for\nmultilingual content. The implementation of this architecture has been\nan on-going process, but as of this writing, beta releases are\navailable for testing. The `plone.app.multilingual\n<http://pypi.python.org/pypi/plone.app.multilingual>`_ (or PAM) pulls\nin the required dependencies.\n\nNote that PAM supports both Archetypes and Dexterity content. It also\ntries to provide the user experience from LinguaPlone so that users\nfamiliar with this add-on from previous versions of Plone will quickly\nbe able to use it.\n\n\nFrequently Asked Questions\n==========================\n\nHow does *collective.multilingual* compare to *plone.multilingual*?\n\n This add-on is a brand new implementation. It's an *alternative* to\n the existing solutions.\n\n The most important difference is that ``collective.multilingual`` is\n built for Plone 4. It fully benefits from the new features included\n in this release.\n\n The newer platform arguably makes the implementation simple, and\n this is not just a good thing, it also makes it much easier to\n maintain the software as a community.\n\n There's another key difference: *less features*. There is no compare\n view, and no integration with external translation tools. It's not\n that we don't want to be \"feature complete\", but some of these\n features are already provided by the web browser and it's not\n necessarily a good thing to try and implement these in Plone.\n\n In short, if you're *not* using the Archetypes content type\n framework (and you really shouldn't be, if you have a choice), then\n ``collective.multilingual`` is probably going to work well.\n\nWhat's a *canonical item*?\n\n This is an item that you have created using Plone's *add* menu and\n which has been translated into one or more languages.\n\nMust I set a language for my content?\n\n No. If you don't set the language field, the language is considered\n neutral. At any given time, this effectively means the site's\n default language.\n\nCan I have language-independent fields?\n\n Yes. You can set a value of ``True`` for the tagged value\n ``\"plone.autoform.languageindependent\"`` or use the included utility\n function::\n\n from collective.multilingual.interfaces import setLanguageIndependent\n from plone.app.dexterity.behaviors.metadata import IDublinCore\n\n setLanguageIndependent(\n IDublinCore['contributors'],\n IDublinCore['creators'],\n IDublinCore['rights'],\n )\n\n This is not just an example. These fields are actually set as\n language-independent.\n\n Note that when a field is language-independent, changes are copied\n into all the content items in the corresponding translation graph.\n\nWhat's the language of newly created content?\n\n There's a setting in Plone which decides whether this is unset\n (neutral), or set to the language which is currently the default.\n\n If content is created using the translate menu, then the language\n form default will be provided automatically.\n\n\n\n\nChanges\n=======\n\n2.0 (unreleased)\n----------------\n\n- Fall back to English language names when the localized list offered\n by Zope does not provide one.\n [malthe]\n\n- Plone 5.2 and Python 3 support.\n [thet]\n\n- Language switcher: Do not render a link for the current language.\n [thet]\n\n\n1.0.1 (2016-03-30)\n------------------\n\n- Fix issue where a widget that was updated multiple times would\n result in a circular translation reference.\n [malthe]\n\n- Fix issue where translating _into_ the default language would ignore translated parents\n and place the new translation in the site root.\n [tmog]\n\n- Always show \"Clear...\" and \"This is a translation of...\" menu items for context, even if context is a default page.\n [tmog]\n\n- check to make sure we do not add multiple translations for one language. Even if one is neutral and the other is not.\n [tmog]\n\n- Initial public release.\n",
"bugtrack_url": null,
"license": "GPL version 2",
"summary": "Create, relate and manage content in multiple languages in Plone!",
"version": "2.0",
"split_keywords": [
"plone",
"multilingual",
"dexterity"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1cbfb6298f696e6c31cd7031f3feae6c877f2b60d2773454e419501480e9a711",
"md5": "cf000ccbbdd505c1f683b620481ae981",
"sha256": "109d98248e5f8f5954a806b90c181e4badc549afb6a0ebdbb0e4b9aa0d7f0f2d"
},
"downloads": -1,
"filename": "collective.multilingual-2.0.tar.gz",
"has_sig": false,
"md5_digest": "cf000ccbbdd505c1f683b620481ae981",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7,!=3.6.*,<=4.0",
"size": 47172,
"upload_time": "2023-03-30T05:10:51",
"upload_time_iso_8601": "2023-03-30T05:10:51.471516Z",
"url": "https://files.pythonhosted.org/packages/1c/bf/b6298f696e6c31cd7031f3feae6c877f2b60d2773454e419501480e9a711/collective.multilingual-2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-30 05:10:51",
"github": false,
"gitlab": false,
"bitbucket": false,
"lcname": "collective.multilingual"
}