<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mattdorn.com &#187; i18n</title>
	<atom:link href="http://www.mattdorn.com/content/tag/i18n/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mattdorn.com</link>
	<description>Generously funded by Matt Dorn</description>
	<lastBuildDate>Sun, 07 Feb 2010 00:07:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Plone i18n: a brief tutorial</title>
		<link>http://www.mattdorn.com/content/plone-i18n-a-brief-tutorial/</link>
		<comments>http://www.mattdorn.com/content/plone-i18n-a-brief-tutorial/#comments</comments>
		<pubDate>Fri, 20 Apr 2007 12:47:54 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[plone]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=44</guid>
		<description><![CDATA[


The following tutorial details the steps I took to internationalize (starting with a Spanish translation) the interface of Plone Translation Hub, a Plone Archetypes-based product.

Contents

Basic Plone i18n with i18ndude
Advanced Plone i18n
Translating workflow states and transitions
Accessing the Plone translation machinery directly


Resources



Basic Plone i18n with i18ndude
First, processing your UML model via ArchGenXML (assuming you have i18ndude installed) [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>The following tutorial details the steps I took to internationalize (starting with a Spanish translation) the interface of <a class="reference" href="http://plonexl8.textmethod.com">Plone Translation Hub</a>, a Plone Archetypes-based product.</p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#basic-plone-i18n-with-i18ndude" id="id1" name="id1">Basic Plone i18n with i18ndude</a></li>
<li><a class="reference" href="#advanced-plone-i18n" id="id2" name="id2">Advanced Plone i18n</a><ul>
<li><a class="reference" href="#translating-workflow-states-and-transitions" id="id3" name="id3">Translating workflow states and transitions</a></li>
<li><a class="reference" href="#accessing-the-plone-translation-machinery-directly" id="id4" name="id4">Accessing the Plone translation machinery directly</a></li>
</ul>
</li>
<li><a class="reference" href="#resources" id="id5" name="id5">Resources</a></li>
</ul>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id1" id="basic-plone-i18n-with-i18ndude" name="basic-plone-i18n-with-i18ndude">Basic Plone i18n with i18ndude</a></h2>
<p>First, processing your UML model via ArchGenXML (assuming you have <a class="reference" href="http://plone.org/products/i18ndude">i18ndude</a> installed) will produce a file called <tt class="docutils literal"><span class="pre">generated.pot</span></tt> and place it in your product&#8217;s <tt class="docutils literal"><span class="pre">i18n</span></tt> directory, which is where all translations must go.  Plone makes somewhat customized use of a the GNU <a class="reference" href="http://oriya.sarovar.org/docs/gettext/">gettext</a> architecture for i18n of applications.  So <tt class="docutils literal"><span class="pre">generated.pot</span></tt> is a template that contains the labels and text for your Archetypes objects.</p>
<p>Before you can begin translating, though, you&#8217;ll need to ensure that the elements in your your page templates that expose text to the user are tagged for translation by the Plone translation architecture.  First you want to make sure that you specify the <tt class="docutils literal"><span class="pre">domain</span></tt> element in the template&#8217;s root (<tt class="docutils literal"><span class="pre">html</span></tt>) element to correspond to your product:</p>
<pre class="literal-block">
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;
    lang=&quot;en&quot;
    metal:use-macro=&quot;here/main_template/macros/master&quot;
    i18n:domain=&quot;PRODUCT_NAME&quot;&gt;
</pre>
<p>Next, for field labels, help indicators, etc.&#8211;any text that&#8217;s visible to your user&#8211;you&#8217;ll need to apply the <tt class="docutils literal"><span class="pre">i18n:translate</span></tt> attribute:</p>
<pre class="literal-block">
&lt;label for=&quot;my_field&quot; i18n:translate=&quot;PRODUCT_NAME_label_my_field&quot;&gt;Enter your name&lt;/label&gt;
</pre>
<p>Once you&#8217;ve finished applying this attribute in your page templates, if your product is fairly simple, you&#8217;re nearly finished.  All you need to do is merge the original PO file from your Archetypes product with your new translatable items from your page templates.  Assuming i18ndude is in your path, from your product&#8217;s root directory, execute it like so:</p>
<pre class="literal-block">
i18ndude rebuild-pot --pot i18n/PRODUCT_NAME.pot --create PRODUCT_NAME --merge i18n/generated.pot skins/PRODUCT_NAME/*.pt
</pre>
<p>Then create an empty PO file for the language(s) you want to create.  E.g., for Spanish, you&#8217;d want:</p>
<pre class="literal-block">
touch i18n/PRODUCT_NAME-es.po
</pre>
<p>Finally, to populate the PO file with the text from the original template so that you can translate it:</p>
<pre class="literal-block">
i18ndude sync --pot i18n/PRODUCT_NAME.pot i18n/PRODUCT_NAME-es.po
</pre>
<p>You can now perform your translations with a tool like <a class="reference" href="http://www.poedit.net/">POEdit</a>.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id2" id="advanced-plone-i18n" name="advanced-plone-i18n">Advanced Plone i18n</a></h2>
<div class="section">
<h3><a class="toc-backref" href="#id3" id="translating-workflow-states-and-transitions" name="translating-workflow-states-and-transitions">Translating workflow states and transitions</a></h3>
<p>Now, if your product has its own workflow states and transitions, you&#8217;ll want to translate those as well.  Enabling those translations is not included in the above process.  You&#8217;ll need to create a separate file with a name reflecting the &quot;plone&quot; domain:</p>
<pre class="literal-block">
touch i18n/plone-PRODUCT_NAME-es.po
</pre>
<p>(Note also that the PO file header includes a &quot;Domain&quot; key to which you&#8217;ll want to assign the value &quot;plone&quot;.)</p>
<p>Essentially you&#8217;ll need to edit this file by hand, assigning the <tt class="docutils literal"><span class="pre">msgid</span></tt> key with the original text and the <tt class="docutils literal"><span class="pre">msgstr</span></tt> with your translation:</p>
<pre class="literal-block">
msgid &quot;Open&quot;
msgstr &quot;Abierto&quot;

msgid &quot;Closed&quot;
msgstr &quot;Cerrado&quot;
</pre>
</div>
<div class="section">
<h3><a class="toc-backref" href="#id4" id="accessing-the-plone-translation-machinery-directly" name="accessing-the-plone-translation-machinery-directly">Accessing the Plone translation machinery directly</a></h3>
<p>You may have some text in your application that appears neither in your page templates nor in your workflow (obviously a situation that you want to avoid if possible).  If so, you may need to access the Plone translation machinery directly, which is best illustrated with an example taken from an External Method used by my product:</p>
<pre class="literal-block">
from Products.CMFCore.utils import getToolByName
...
translation_service = getToolByName(self, 'translation_service')
msg = translation_service.utranslate(domain='PloneXL8',
                                     msgid='You have taken ownership of this translation.',
                                     default='You have taken ownership of this translation.',
                                     context=self)
msg = msg.encode('utf-8')
</pre>
<p>Note that you&#8217;ll need to add the <tt class="docutils literal"><span class="pre">msgid</span></tt> and <tt class="docutils literal"><span class="pre">msgstr</span></tt> for such into your PRODUCT_NAME.pot and/or PRODUCT_NAME-xx.po file by hand.</p>
</div>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id5" id="resources" name="resources">Resources</a></h2>
<p>Some helpful links:</p>
<ul class="simple">
<li><a class="reference" href="http://docs.neuroinf.de/programming-plone/i18n">Basic Plone i18n</a></li>
<li><a class="reference" href="http://plone.org/products/archgenxml/documentation/how-to/handling-i18n-translation-files-with-archgenxml-and-i18ndude">Archetypes and i18ndude</a></li>
<li><a class="reference" href="http://plone.org/documentation/manual/plone-developer-reference/patterns/referencemanual-all-pages">Plone best practices</a></li>
<li><a class="reference" href="http://plone.org/development/teams/i18n/datetime">Date and time localization</a></li>
</ul>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/plone-i18n-a-brief-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Source i18n</title>
		<link>http://www.mattdorn.com/content/open-source-i18n/</link>
		<comments>http://www.mattdorn.com/content/open-source-i18n/#comments</comments>
		<pubDate>Tue, 17 Apr 2007 11:05:04 +0000</pubDate>
		<dc:creator>mdorn</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://67.207.132.145/wordpress/?p=43</guid>
		<description><![CDATA[


Not so long ago I found myself in the rather embarrassing position of having authored a translation collaboration tool for use by an international user base without having implemented the platform&#8217;s (Plone) internationalization (i18n) facilities.  That is, I gave the application an English interface and left it at that.  Furthermore I began to [...]]]></description>
			<content:encoded><![CDATA[
<div class="document">
<!-- -*- mode: rst -*- -->
<p>Not so long ago I found myself in the rather embarrassing position of having authored a <a class="reference" href="http://plonexl8.textmethod.com">translation collaboration tool</a> for use by an international user base without having implemented the platform&#8217;s (<a class="reference" href="http://plone.org">Plone</a>) internationalization (i18n) facilities.  That is, I gave the application an English interface and left it at that.  Furthermore I began to consider how I might extend this application to enable the more professional users to leverage their existing translation tools, like the industry-standard <a class="reference" href="http://www.trados.com/">Trados</a>, rather than being confined to using my application&#8217;s Web interface when actually performing a translation (even if a cut-and-paste workaround is available).  Correcting the first problem and laying the groundwork for solving the second entailed giving myself a pretty extensive lesson in both open standards and Open Source software for Computer Aided Translation (CAT), which I summarize below.</p>
<div class="contents topic">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#translating-software-interfaces" id="id1" name="id1">Translating software interfaces</a></li>
<li><a class="reference" href="#translating-documents" id="id2" name="id2">Translating documents</a></li>
<li><a class="reference" href="#translation-memory-tm" id="id3" name="id3">Translation Memory (TM)</a></li>
</ul>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id1" id="translating-software-interfaces" name="translating-software-interfaces">Translating software interfaces</a></h2>
<p>First, I discovered that there are two aspects of what I&#8217;m currently trying to achieve with this tool, both of which have different, but related, technological solutions.  First of all, I need translations for the interface of the tool itself. To accomplish this, Plone makes somewhat customized use of a the GNU <a class="reference" href="http://oriya.sarovar.org/docs/gettext/">gettext</a> architecture for i18n of applications.  In that model, translations are stored in message catalogs which match original translations with their target language translations contained and which are contained in files with the <tt class="docutils literal"><span class="pre">.po</span></tt> format, which essentially maintains translations through original/translation key-value pairs.  In the case of Plone, a utility called <a class="reference" href="http://plone.org/products/i18ndude">i18ndude</a> handles much of the heavy lifing involved in preparing these files for use with your Plone Product, while a PO file editor like <a class="reference" href="http://www.poedit.net/">POEdit</a> helps you actually perform the translations.</p>
<p>The gettext/PO file approach appears to be the most common solution for translating the interfaces for Linux-based open source projects as well as Web applications (though there are some sui-generis exceptions, such as the <a class="reference" href="http://www.globalize-rails.org/">Globalize plugin</a> for Ruby on Rails).</p>
<p>So I went ahead and created a Spanish translation for the application, but its current users include translators of French and Portuguese as well, and potentially Italian, Swahili, Greek, and Arabic.  I can&#8217;t translate the interface into those languages (though I might be able to create a passable Portuguese interface), and I&#8217;d like to make it as easy as possible for those who can to help me out.  A solution to this problem might be to set up a server tool like <a class="reference" href="http://www.wordforge.org/drupal/projects/wordforge/tools/pootle">Pootle</a>, which lets  you visualize progress made on translation of PO files, to help manage the project.  Ubuntu/Launchpad&#8217;s <a class="reference" href="https://launchpad.net/rosetta">Rosetta</a>, which is not (yet) open source, appears to be a more sophisticated implementation of the same idea.  In conjunction with the server app, I could provide a brief overview of client-side tools that can be used to edit the PO files.  I have already mentioned <a class="reference" href="http://www.poedit.net/">POEdit</a>, but <a class="reference" href="http://sourceforge.net/projects/omegat">OmegaT</a>, a more ambitious suite of Open Source CAT tools, a also has support for PO files.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id2" id="translating-documents" name="translating-documents">Translating documents</a></h2>
<p>So, software interface translation is the first order of translation business for my project.  The second issue is the translation of documents, which is the purpose of the application itself.  Take the documentation of a software program, for example, with an original document in, say, HTML.  A translator could simply translate it free-form, using copy-and-paste and whatever tools she happens to have available.  But translation-specific editors like that provided by <a class="reference" href="http://sourceforge.net/projects/omegat">OmegaT</a>&#8211;which supports HTML, OpenOffice, and ODF among several other formats&#8211;can help present the text in a way that&#8217;s more comfortable for translation, in addition to providing access to Translation Memory tools.  As long as the program is capable of exporting the translation to the format of the original (which is presumably what would be reqeusted in most translation jobs), this would appear to be the preferable route.</p>
<p>The problem with this process is that translators are likely to receive documents in any number of formats&#8211;the tools they use may be more capable of dealing with some formats than with others, and a separate workflow or collaboration process may need to be defined depending on the type of file.  This is the problem that <a class="reference" href="http://www.opentag.com/xliff.htm">XLIFF</a>, an XML format for translations, attempts to address, by providing a set of elements for tracking information common to translation activity.  I don&#8217;t go into detail on XLIFF here (and in fact have quite a bit more to learn about it), but Trados and other major translation software vendors already include support for XLIFF, and given its emergence as a standard, any software meant to support translation collaboration should also support XLIFF.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id3" id="translation-memory-tm" name="translation-memory-tm">Translation Memory (TM)</a></h2>
<p>Finally, both activities&#8211;the translation of software interfaces and the translation of documents&#8211;benefit from the use of a Translation Memory (TM) system.  POEdit can generate a TM for you by letting you import previously existing PO files based on the language(s) you want to work with.  OmegaT generates one for you based on the translations you provide while working on your project, but also allows you to import existing TMs based on the <a class="reference" href="http://www.lisa.org/standards/tmx/">TMX</a> standard.</p>
<p>Pending further investigation, I&#8217;m considering complementing Plone Translation Hub with a repository of TMX files for enhanced collaboration.  Because it&#8217;s Zope/Plone, <a class="reference" href="http://www.tumatxa.com/">Tumatxa</a> might provide a good starting point.</p>
<p>Note that the effectiveness of TM relies on a program&#8217;s ability to &quot;segment&quot; a source document properly, <a class="reference" href="http://www.lisa.org/standards/srx/srx.html">SRX</a> is the emerging standard for defining segmentation rules.</p>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattdorn.com/content/open-source-i18n/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
