{ "info": { "author": "Maurits van Rees", "author_email": "m.van.rees@zestsoftware.nl", "bugtrack_url": null, "classifiers": [ "Framework :: Buildout", "Framework :: Plone", "Framework :: Plone :: 3.3", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License (GPL)", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": ".. contents::\n\ncollective.recipe.i18noverrides\n===============================\n\nThis is a buildout recipe. It creates an i18n directory within one or\nmore zope 2 instances in your buildout. It copies some .po files to\nthose directories. The translations in those .po files will override\nany other translations. \n\n\nPlone/Zope versions\n-------------------\n\nThis is tested for Plone 3 with Zope 2.10. It should work for a plain\nZope site without Plone as well, as there is nothing Plone specific to\nthis recipe. It should work fine for all previous versions as well.\n\nFor Plone 4 and Zope 2.12 it has no effect: there is no code anymore\nin those versions that looks for translations in an i18n folder of\nyour instance. You should create an own package and register a\nlocales directory with translation in it. For more info or questions,\nsee the `plone-internationalization mailing list`_.\n\n.. _`plone-internationalization mailing list`: http://plone-regional-forums.221720.n2.nabble.com/plone4-how-to-override-translations-in-plone-app-locales-tt5456430.html\n\n\nUse case\n--------\n\nAn example use case is:\n\n- In the Dutch Plone translations the msgid 'Manager' is translated as\n 'Beheerder'.\n\n- A customer wanted it to be translated as 'Site admin' instead.\n\n- Just putting this translation within the i18n directory of the\n customer product is not guaranteed to work as it depends on the\n order in which the i18n folders get read on Zope startup: is\n CMFPlone/i18n or Customer/i18n read first.\n\n- When you create an i18n directory within the zope 2 instance and add\n a po file with that msgid there, this is guaranteed to get used.\n\nNote that this should work for overriding translations within i18n\ndirectories. Overriding translations in locales directories is not a\nuse case of this recipe.\n\n\nContents of .po file\n--------------------\n\nWhat should be in the .po file? You need all the headers that are\nnormally in .po files. So copy the headers of the current .po file\nthat has the translation that you want to override. Then just add the\nmsgid and a new msgstr. The name of the file does not really matter.\nIt should be meaningful to you and end with '.po'. In the mentioned\nuse case it makes sense to call it ``plone-nl.po`` as that is the name\nof the original file from the plone translations. The contents would\nbe something like this (non-interesting header lines skipped for\nclarity)::\n\n\n msgid \"\"\n msgstr \"\"\n ...\n \"Language-Code: nl\\n\"\n \"Language-Name: Nederlands\\n\"\n \"Domain: plone\\n\"\n\n msgid \"Manager\"\n msgstr \"Site admin\"\n\n\nDetailed Documentation\n======================\n\nSupported options\n=================\n\nThe recipe supports the following options:\n\nsource\n Source directory that contains the .po files that the recipe will\n copy. All ``*.po`` files will be copied. This option is mandatory.\n\negg\n Egg that contains the ``source`` directory. If this option is mentioned,\n the ``source`` directory has to be a relative path.\n\npackage\n Can be mentioned when ``source`` cannot be found in ``egg`` for one of the\n following reasons : ``egg`` holds a version specification; ``egg`` is not\n equal to the name of the installed package; ``source`` is in a subpackage.\n\ndestinations\n Target directory or directories. This should point to the\n directory of the zope 2 instance. The recipe will create an i18n\n directory in each of the destinations and copy all ``*.po`` files\n from the source directory to these i18n directories. This option\n is mandatory.\n\n\nExample usage\n-------------\n\nWe'll start by creating a buildout that uses the recipe. Here is a\ntemplate where we only have to fill in the source and destinations::\n\n >>> buildout_config_template = \"\"\"\n ... [buildout]\n ... index = http://pypi.python.org/simple\n ... parts = i18noverrides\n ... versions = versions\n ...\n ... [versions]\n ... zc.buildout = 1.4.3\n ... zc.recipe.egg = 1.2.2\n ... setuptools = 0.6c11\n ... distribute = 0.6.14\n ...\n ... [i18noverrides]\n ... recipe = collective.recipe.i18noverrides\n ... source = %(source)s\n ... destinations = %(dest)s\n ... \"\"\"\n\nWe will start with specifying some non existing source and destination\ndirectories::\n\n >>> write('buildout.cfg', buildout_config_template % {\n ... 'source': '${buildout:directory}/translations',\n ... 'dest': '${buildout:directory}/instance'})\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Installing i18noverrides.\n While:\n Installing i18noverrides.\n Error: path '/sample-buildout/translations' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.\n \n\nThe source must be a directory::\n\n >>> write('translations', 'This is a file.')\n >>> print system(buildout)\n Installing i18noverrides.\n While:\n Installing i18noverrides.\n Error: path '/sample-buildout/translations' must be a directory.\n \n\nNow we remove this file and try with a proper directory::\n\n >>> remove('translations')\n >>> mkdir('translations')\n >>> print system(buildout)\n Installing i18noverrides.\n While:\n Installing i18noverrides.\n Error: path '/sample-buildout/instance' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.\n \n\nSo we set a destination too and first try with a file as well before\ncreating a directory::\n\n >>> write('instance', 'This is a file.')\n >>> print system(buildout)\n Installing i18noverrides.\n While:\n Installing i18noverrides.\n Error: path '/sample-buildout/instance' must be a directory.\n \n >>> remove('instance')\n >>> mkdir('instance')\n >>> print system(buildout)\n Installing i18noverrides.\n collective.recipe.i18noverrides: Warning: source '/sample-buildout/translations' contains no .po files.\n \n\nNow the source and destination have been setup correctly, but we get a\nwarning as the source directory has no translation files. We first\nadd a file that does not end with ``.po``. Since the previous\nbuildout run only had a warning and finished successfully, the recipe\nnow runs in update mode, which does the same as the install mode::\n\n >>> write('translations', 'not-a-po-file', 'I am not a po file')\n >>> print system(buildout)\n Updating i18noverrides.\n collective.recipe.i18noverrides: Warning: source '/sample-buildout/translations' contains no .po files.\n \n >>> write('translations', 'plone-nl.po', 'I am a Dutch plone po file')\n >>> write('translations', 'plone-de.po', 'I am a German plone po file')\n >>> print system(buildout)\n Updating i18noverrides.\n collective.recipe.i18noverrides: Creating directory /sample-buildout/instance/i18n\n collective.recipe.i18noverrides: Copied 2 po files.\n \n\nNo warnings, no errors, so let's see what the end result is::\n\n >>> ls('translations')\n - not-a-po-file\n - plone-de.po\n - plone-nl.po\n >>> ls('instance')\n d i18n\n\nA i18n directory has been created in the instance. Inside that\ndirectory we find our two po files::\n\n >>> ls('instance', 'i18n')\n - plone-de.po\n - plone-nl.po\n >>> cat('instance', 'i18n', 'plone-de.po')\n I am a German plone po file\n >>> cat('instance', 'i18n', 'plone-nl.po')\n I am a Dutch plone po file\n\nIf the destination directory for some strange reason already contains\na i18n file instead of a directory, we fail::\n\n >>> remove('instance', 'i18n')\n >>> write('instance', 'i18n', 'I am a file')\n >>> print system(buildout)\n Updating i18noverrides.\n While:\n Updating i18noverrides.\n Error: '/sample-buildout/instance/i18n' is not a directory.\n \n >>> remove('instance', 'i18n')\n\nIt should also be possible to have multiple destinations::\n\n >>> write('buildout.cfg', buildout_config_template % {\n ... 'source': '${buildout:directory}/translations',\n ... 'dest': \"\"\"\n ... ${buildout:directory}/instance\n ... ${buildout:directory}/instance2\"\"\"})\n >>> print system(buildout)\n Installing i18noverrides.\n While:\n Installing i18noverrides.\n Error: path '/sample-buildout/instance2' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.\n \n\nRight, right, we will create that directory too::\n\n >>> mkdir('instance2')\n >>> print system(buildout)\n Installing i18noverrides.\n collective.recipe.i18noverrides: Creating directory /sample-buildout/instance/i18n\n collective.recipe.i18noverrides: Creating directory /sample-buildout/instance2/i18n\n collective.recipe.i18noverrides: Copied 2 po files.\n \n\nLet's check the result::\n\n >>> ls('instance')\n d i18n\n >>> ls('instance', 'i18n')\n - plone-de.po\n - plone-nl.po\n >>> ls('instance2')\n d i18n\n >>> ls('instance2', 'i18n')\n - plone-de.po\n - plone-nl.po\n >>> cat('instance2', 'i18n', 'plone-de.po')\n I am a German plone po file\n >>> cat('instance2', 'i18n', 'plone-nl.po')\n I am a Dutch plone po file\n\nClean up:\n\n >>> remove('instance')\n >>> remove('instance2')\n\n\nIntegration with plone.recipe.zope2instance\n-------------------------------------------\n\nAs the recipe is normally used to add translations to zope 2\ninstances, it makes sense to search for buildout parts that setup zope\ninstances and take those locations.\n\n >>> write('buildout.cfg', \"\"\"\n ... [buildout]\n ... index = http://pypi.python.org/simple\n ... parts = instance instance2 zeoclient i18noverrides\n ... versions = versions\n ...\n ... [versions]\n ... zc.buildout = 1.4.3\n ... zc.recipe.egg = 1.2.2\n ... setuptools = 0.6c11\n ... distribute = 0.6.14\n ... plone.recipe.zope2instance = 3.9\n ... mailinglogger = 3.3\n ...\n ... [i18noverrides]\n ... recipe = collective.recipe.i18noverrides\n ... source = ${buildout:directory}/translations\n ...\n ... [instance]\n ... recipe = plone.recipe.zope2instance\n ... user = admin:admin\n ...\n ... [instance2]\n ... recipe = plone.recipe.zope2instance\n ... user = admin:admin\n ...\n ... [zeoclient]\n ... recipe = plone.recipe.zope2instance\n ... user = admin:admin\n ... \"\"\")\n\nWe mock a mkzopeinstance script in the bin directory:\n\n >>> write('bin/mkzopeinstance', \"\"\"\n ... import sys\n ... import os\n ... path = sys.argv[2]\n ... os.mkdir(path)\n ... os.mkdir(os.path.join(path, 'etc'))\n ... \"\"\")\n\nWe do not want to install a complete zope2 instance in the tests, so\nwe do not add it to the buildout parts. That does mean that running\nbuildout now fails:\n\n >>> print system(buildout)\n Getting distribution for 'plone.recipe.zope2instance==3.9'.\n ...\n Installing instance.\n Generated script '.../bin/instance'.\n ...\n Installing i18noverrides.\n collective.recipe.i18noverrides: Creating directory .../i18n\n collective.recipe.i18noverrides: Creating directory .../i18n\n collective.recipe.i18noverrides: Creating directory .../i18n\n collective.recipe.i18noverrides: Copied 2 po files.\n \n >>> ls('parts', 'instance')\n d etc\n d i18n\n >>> ls('parts', 'instance', 'i18n')\n - plone-de.po\n - plone-nl.po\n >>> ls('parts', 'instance2', 'i18n')\n - plone-de.po\n - plone-nl.po\n >>> ls('parts', 'zeoclient', 'i18n')\n - plone-de.po\n - plone-nl.po\n\nIf we explicitly specify destinations, the recipes are ignored.\n\n >>> write('buildout.cfg', \"\"\"\n ... [buildout]\n ... index = http://pypi.python.org/simple\n ... parts = dummy i18noverrides\n ... versions = versions\n ...\n ... [versions]\n ... zc.buildout = 1.4.3\n ... zc.recipe.egg = 1.2.2\n ... setuptools = 0.6c11\n ... distribute = 0.6.14\n ... plone.recipe.zope2instance = 3.9\n ... mailinglogger = 3.3\n ...\n ... [i18noverrides]\n ... recipe = collective.recipe.i18noverrides\n ... source = ${buildout:directory}/translations\n ... destinations = ${buildout:directory}/dest\n ...\n ... [dummy]\n ... recipe = plone.recipe.zope2instance\n ... user = admin:admin\n ... \"\"\")\n >>> mkdir('dest')\n >>> print system(buildout)\n Uninstalling ...\n Installing i18noverrides.\n collective.recipe.i18noverrides: Creating directory /.../dest/i18n\n collective.recipe.i18noverrides: Copied 2 po files.\n \n >>> ls('parts', 'dummy')\n d etc\n >>> ls('dest', 'i18n')\n - plone-de.po\n - plone-nl.po\n\nClean up:\n\n >>> remove('translations')\n\n\nUsage with directory in egg\n---------------------------\n\nWe start by creating a buildout that uses the recipe. Here is a\ntemplate where we only have to fill in the source, egg and\ndestinations::\n\n >>> buildout_config_template = \"\"\"\n ... [buildout]\n ... index = http://pypi.python.org/simple\n ... parts = i18noverrides\n ... versions = versions\n ...\n ... [versions]\n ... zc.buildout = 1.4.3\n ... zc.recipe.egg = 1.2.2\n ... setuptools = 0.6c11\n ... distribute = 0.6.14\n ... # We need to pin this one because it still needs to be uninstalled.\n ... # If we do not pin, the uninstall code will get the latest version,\n ... # which depends on Zope2, which means we are hosed...\n ... plone.recipe.zope2instance = 3.9\n ... mailinglogger = 3.3\n ...\n ... [i18noverrides]\n ... recipe = collective.recipe.i18noverrides\n ... source = %(source)s\n ... egg = %(egg)s\n ... destinations = %(dest)s\n ... \"\"\"\n\nWe specify ``egg`` and ``source``::\n\n >>> write('buildout.cfg', buildout_config_template % {\n ... 'source': 'tests/translations',\n ... 'egg': 'collective.recipe.i18noverrides',\n ... 'dest': 'translations'})\n\nWe prepare target directory::\n\n >>> mkdir('translations')\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Uninstalling ...\n Installing i18noverrides.\n collective.recipe.i18noverrides: Creating directory translations/i18n\n collective.recipe.i18noverrides: Copied 2 po files.\n \n\nLet's check the result::\n\n >>> ls('translations')\n d i18n\n >>> ls('translations', 'i18n')\n - test-fr.po\n - test-nl.po\n >>> cat('translations', 'i18n', 'test-fr.po')\n Un fichier .po\n >>> cat('translations', 'i18n', 'test-nl.po')\n Een .po bestand\n\nWe specify ``egg`` and an absolute path in ``source``::\n\n >>> write('buildout.cfg', buildout_config_template % {\n ... 'source': '/translations',\n ... 'egg': 'testegg',\n ... 'dest': 'translations'})\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Uninstalling i18noverrides.\n Installing i18noverrides.\n While:\n Installing i18noverrides.\n Error: Because egg option is provided,\n source '/translations' should be relative, not absolute.\n \n\nWe specify an `egg`` that does not hold the configured ``source``::\n\n >>> write('buildout.cfg', buildout_config_template % {\n ... 'source': 'translations',\n ... 'egg': 'zc.recipe.egg',\n ... 'dest': 'translations'})\n\nRunning the buildout gives us::\n\n >>> print system(buildout)\n Installing i18noverrides.\n While:\n Installing i18noverrides.\n Error: path '/sample-buildout/eggs/zc.recipe.egg.../zc/recipe/egg/translations' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.\n \n\nContributors\n============\n\nMaurits van Rees, Author\n\n\nChange history\n==============\n\nHistory of collective.recipe.i18noverrides\n==========================================\n\n1.2 (2013-01-23)\n----------------\n\n- Raise ``zc.buildout.UserWarning`` in case of errors. This is how it\n should be done. It is more noticeable than logging an error (which\n may not be really visible as error) and quitting.\n [maurits]\n\n\n1.1 (2012-09-13)\n----------------\n\n- Moved to github:\n https://github.com/collective/collective.recipe.i18noverrides\n [maurits]\n\n\n1.0 (2010-08-25)\n----------------\n\n- Added a note to warn that this recipe will have no effect in Plone 4\n (Zope 2.12) or higher. You should create an own package and\n register a locales directory there.\n [maurits]\n\n\n0.4 (2009-09-08)\n----------------\n\n- Only consider buildout parts for inclusion in the destinations when\n they are actually in the parts section of buildout. Otherwise you\n can run into errors like this:\n Error: Missing option: zptdebugger:__buildout_signature__\n [maurits]\n\n\n0.3 (2009-09-08)\n----------------\n\n- If no destinations are specified, we automatically copy the po files\n to all parts that use plone.recipe.zope2instance.\n [maurits]\n\n\n0.2 (2009-08-12)\n----------------\n\n- Allow to specify an egg (with optional package)\n where the source directory can be found.\n [gotcha]\n\n- Pin packages (at least zc.buildout) in both the main buildout.cfg\n and the one in the tests, to avoid test failures simply because the\n used zc.buildout is upgraded during the test run.\n [maurits]\n\n\n0.1 (2009-06-05)\n----------------\n\n- Initial implementation moved over from a one-off script. [maurits]\n\n- Created recipe with ZopeSkel\n [Maurits van Rees]\n\nDownload\n========", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/collective/collective.recipe.i18noverrides", "keywords": "i18n", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "collective.recipe.i18noverrides", "package_url": "https://pypi.org/project/collective.recipe.i18noverrides/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/collective.recipe.i18noverrides/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/collective/collective.recipe.i18noverrides" }, "release_url": "https://pypi.org/project/collective.recipe.i18noverrides/1.2/", "requires_dist": null, "requires_python": null, "summary": "Override translations by putting some .po files in the i18n directory of the zope 2 instance", "version": "1.2" }, "last_serial": 741816, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "c347d26688a56c6a1d3cc81835074e6f", "sha256": "b40460e7c3ce1a4a841bddedf532dabd911ae6d8d2d6e424cd53350c50227d91" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-0.1.tar.gz", "has_sig": false, "md5_digest": "c347d26688a56c6a1d3cc81835074e6f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7410, "upload_time": "2009-06-05T16:09:09", "url": "https://files.pythonhosted.org/packages/09/a4/4184eb8aaac8ad7b17d6c39b33e7f6b67d339c5b3c05c51df0237fca10e9/collective.recipe.i18noverrides-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "fcc7dcbcee0d8fd735c3c78d99bdc537", "sha256": "1bde03cf491b86a4061e46e86e9dd210080c4b2c2fb41bea090594bd4df1b846" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-0.2.tar.gz", "has_sig": false, "md5_digest": "fcc7dcbcee0d8fd735c3c78d99bdc537", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9260, "upload_time": "2009-08-12T12:20:25", "url": "https://files.pythonhosted.org/packages/95/bd/6e9f70f8e8af0b260c751debd1192a12c55c90b6c30c39023d7d403715f7/collective.recipe.i18noverrides-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "3368835dfce7f07c472f2a9cb4bd4441", "sha256": "bc21be52443dd7f668b68c3b8c8862524013e56063795fdb1f9f2459b303c18b" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-0.3.tar.gz", "has_sig": false, "md5_digest": "3368835dfce7f07c472f2a9cb4bd4441", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9931, "upload_time": "2009-09-08T17:03:34", "url": "https://files.pythonhosted.org/packages/11/08/0f63375057e3f87cd22facfb945ccaa75e96bb71e1d5f0e2cf91cbeb326f/collective.recipe.i18noverrides-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "80d23d2acec6742590233201fb504c5e", "sha256": "bc358e99ade6673f8f99755f5db8b1cec6f1b2d4c919accd0864232115b97d3b" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-0.4.tar.gz", "has_sig": false, "md5_digest": "80d23d2acec6742590233201fb504c5e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10070, "upload_time": "2009-09-08T17:31:33", "url": "https://files.pythonhosted.org/packages/d4/39/58bf7aae9232a42dd5297a61af0e8d0d681a5029f8bdcf06b32f5fc15650/collective.recipe.i18noverrides-0.4.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "7ddac0c4638e06c90f33909b9fb287da", "sha256": "7c434e96aa4ee2ea5b32ae9baa7686ca8345b8c74caee2fb275cef2984e2116c" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-1.0.zip", "has_sig": false, "md5_digest": "7ddac0c4638e06c90f33909b9fb287da", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23791, "upload_time": "2010-08-25T10:22:59", "url": "https://files.pythonhosted.org/packages/8b/b7/28ae46c11820c5f371985b495d315e75029da2466215ea59feef43b8fb54/collective.recipe.i18noverrides-1.0.zip" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "48a30485011d567d28315d975761cf51", "sha256": "a13342a6f78cf10816cc2b107405d65b63f51f0d43af64416a004292f2054fec" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-1.1.zip", "has_sig": false, "md5_digest": "48a30485011d567d28315d975761cf51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25919, "upload_time": "2012-09-13T13:10:40", "url": "https://files.pythonhosted.org/packages/c3/c1/938ad09b57e1bab2e98194fe693d744708ba91eb489ffff6104d476662d2/collective.recipe.i18noverrides-1.1.zip" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "4e3dd3e44bfa96a355cde0a98d6397e3", "sha256": "e20618ae9219381dfd4d8f2b04d81cff0fe555e3585d9a4ec7b218ceb8eb562a" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-1.2.zip", "has_sig": false, "md5_digest": "4e3dd3e44bfa96a355cde0a98d6397e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29345, "upload_time": "2013-01-23T13:40:57", "url": "https://files.pythonhosted.org/packages/97/78/0073be3da2282c5bdd19a8265b53e606527e56bff1137f31612e7b1986c8/collective.recipe.i18noverrides-1.2.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4e3dd3e44bfa96a355cde0a98d6397e3", "sha256": "e20618ae9219381dfd4d8f2b04d81cff0fe555e3585d9a4ec7b218ceb8eb562a" }, "downloads": -1, "filename": "collective.recipe.i18noverrides-1.2.zip", "has_sig": false, "md5_digest": "4e3dd3e44bfa96a355cde0a98d6397e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29345, "upload_time": "2013-01-23T13:40:57", "url": "https://files.pythonhosted.org/packages/97/78/0073be3da2282c5bdd19a8265b53e606527e56bff1137f31612e7b1986c8/collective.recipe.i18noverrides-1.2.zip" } ] }