Archive for July, 2007

Interface translation in symfony

Thursday, July 26th, 2007

Symfony provides interface translation using the XLIFF standard. While using the XLIFF standard here is good, it has one pain point. The pain point becomes apparent when the need arises for changing/editing the phrases. If the phrase is used in several templates, you need to search all the templates and change there as well as in the dictionary.

For example, lets say we define a simple label like “Username” in the dictionary and in several templates. The dictionary will look like:

<?xml version="1.0" ?>
<xliff version="1.0">
  <file orginal="global" source-language="en_US"
    datatype="plaintext">
    <body>
      <trans-unit id="1">
        <source>Username</source>
        <target>ユーザー名</target>
      </trans-unit>
    </body>
  </file>
</xliff>

And in all templates that use the label “Username” we will use the following to translate it based on user’s culture:

echo __('Username');

This is good, but lets say down the line we decide to use the label “User Id” instead of “Username”. To do that we need to update all the templates and the dictionary. This becomes cumbersome if you have a large number of templates that reference this label. If you notice, the cause of the problem lies in the fact that we have used the actual text itself to identify the i18n phrase within all templates.

To get around this problem, what we did was to use a code to identify the phrase and use that in the template. And we provide a dictionary for each of the supported language. So in this case we create an English and Japanese dictionary both. But what about the source language, you would ask. Well, thats a hack: we ended up providing a non existent ISO code. Based on the comment from Dennis, we use English as the source since translation happens even if source and target languages are same.

So here is what our English and Japanese dictionary look like:

<?xml version="1.0" ?>
<xliff version="1.0">
  <file orginal="global" source-language="en_US"
    datatype="plaintext">
    <body>
      <trans-unit id="1">
        <source>LABEL_USERNAME</source>
        <target>Username</target>
      </trans-unit>
    </body>
  </file>
</xliff>

<?xml version="1.0" ?>
<xliff version="1.0">
  <file orginal="global" source-language="en_US"
    datatype="plaintext">
    <body>
      <trans-unit id="1">
        <source>LABEL_USERNAME</source>
        <target>ユーザー名</target>
      </trans-unit>
    </body>
  </file>
</xliff>

And the phrase in the template looks like:

echo __('LABEL_USERNAME')

So now if you want to change the English version of the phrase, you simply update the dictionary and no need to change the templates.