Translation Management Module - Features Preview

Translation Management is making its first steps. The new handbook gives a preview of the main features and how the module will work.

The idea behind the module is to implement much of our translation process in a Drupal module, so that everyone who needs to run complex multilingual sites can use.

Unified Translation Editor

Translation Editor

The heart of the module is the unified translation editing screen. Translators will use this single screen to translate anything.

Be it nodes, CCK, blocks or even interface strings. The translators don't need to know where to translate these in the Drupal admin. The module will collect everything that requires translation and will display in the same translation editor.

The translation editor will adapt according to what's being translated. For each job, it will include the right fields. Each field shows the original text and the translation.

It also shows which fields are new or modified, so that translators don't need to guess or look for changes.

When they complete translation in the translation editor, the module will send everything to its right place in Drupal.

Managing Translations

Content managers will be able to create new Translator users. Then, they use the Translation Dashboard to send jobs.

Translation Dashboard

The translation dashboard gives a full picture of everything that needs translation. From that screen you can see contents that needs translation, what's being translated right now and what's already completed.

Translation Queue

When content managers send jobs for translation, the module notifies the translators.

Translation Dashboard

Then, each translator has a queue of pending jobs. The translator clicks on each job to start translating.

Want to Get Involved?

Our plan is to have a first working version in about 6 weeks.

We're also going to do a session about it in DrupalCon Copenhagen in August. The session is called Translation Management for the Enterprise.

We're looking for early adopters who want to take the module for a spin. Contact us if that interests you.

Managing Translation Costs - Bidding or Fixed Price?

The translation management module will combine all the technical details of managing translation work with the actual translation process.

You will be able to use your own in-house translators, or get professional translators from ICanLocalize.

Right now, ICanLocalize uses a fixed rate for translation jobs (0.07 USD / word). We thought that this is too restrictive and wanted to change it to a bidding model.

I wrote a blog post, explaining why we want to move from fixed pricing to a bidding system.

The rational was that allowing translators to offer their pricing would lead to a healthy competition - which clients would benefit from.

For languages where there is very high demand, prices would naturally go up and in other languages, prices will go down.

When I woke up this morning, I was expecting cheering comments about that, but got exactly the opposite. Clients and translators are in full agreement that bidding wars would be bad for everyone. You can see what they wrote in the comments.

Mistake #1 - Bidding Will Lead to Lower Quality

Our assumption was that if we let the market have its say, everyone will come out happy.

Folks (everyone who commented) had an opposite view. They explained us that what they like best about ICanLocalize is the fact that translators compete on qualify and not on price. In our excitement, we overlooked this.

Opening translation jobs to bidding wars would push out the best translators, who spend long hours researching and proofreading. We'll be left with the turbo translators, who get the job done fast, but at questionable quality.

Mistake #2 - Clients Need Quality Before Cost

Of course, we know that quality comes before cost, but we didn't realize that clients are actually not looking for a cost reduction.

At 0.07 USD / word, they're happy with the pricing and have no incentive to reduce it. What they're asking us is to simplify the Translation Quality Assurance, so that it's easier to use for any project.

The main concern is being able to trust translation blindfolded. If you're translating to French and have a French speaker in your team, you can accept translation which you're only 99% sure about.

But, if you're getting Korean translation, you don't want the first reviewers to be your clients.

Conclusions - QA by Default, no Price Wars

Our conclusion from all that is that bidding wars are out of the question. We will allows clients to pay a premium if they want to (have asked for that), but are not going to allow translators to fight over cost.

Instead, we'll greatly simplify the review and QA process, so that every translation job gets reviewed by default. Clients can exclude jobs from this review, but the normal flow would be translation and review.

How is it Working for You?

When you order translator work, what are your criteria for choosing translators?

You can comment here or join the original discussion on ICanLocalize.

Translation Management for Enterprise Drupal Sites

First, there were websites (well, there were a few things before...).

Then, came content management systems.

Then, they became multilingual.

And then, problems started - how do we manage all these translations?

Working with Translators

Enterprise clients need a systematic process for managing translations. This process begins with original-language content and ends with completed translations.

In the middle, there's an entire process which includes notifying translators, translation review, quality assurance, building the translated contents in the CMS, maintaining a glossary and lots of other activities.

Translators Don't Speak Druplish

The best translators out there spend all their time translating. They're busy folks (and well paid as well). The last thing they need is to learn about the fascinating aspects of Drupal multilingual administration.

And so was born the title - translations manager / coordinator / administrator. The translation manager goes through the Drupal contents, finds what needs translation, sends it to the translators, gets it back and puts it in Drupal. A full time job if you're running even a medium sized Drupal site.

Enterprise Translation Management

Multilingual websites that have dozens of new articles a day cannot rely on a manual translation management process. They need a systematic solution, where the entire translation process is handled automatically.

ICanLocalize is migrating its proprietary closed translation management system into an open-source Drupal translation management module.

The idea is to allow enterprise users to run multilingual Drupal sites without reinventing the wheel every time.

The "bread and butter" of translation management (features for this module):

  • Tracking of what's translated and what needs translation
  • A translator role
  • Jobs queue, per translator
  • Notification to translators about new contents they need to translate
  • Unified translation interface (I'll explain about this in a minute)
  • Automatic link adjustment

Unified Translation

When translators translate your contents, they need to translate node title, body, taxonomy, blocks, CCK, interface strings and everything else your site uses. These are a lot of different things, each going to a different place in Drupal.

We don't want to teach translators where to go for everything and which tab to click on.

Instead, we'll have just one translation page. That page will let the translator edit everything. When translators edit, the module will automatically take those translations and put them in the right place. This way, multilingual content management happens automatically.

Sounds Confusing?

It's not a trivial subject. Companies build million dollar systems around translation management. We'll write more and explain each of these features in details.

The good news are, it's more difficult to explain than to use :-)

Consistant translations with glossary

It’s taken a while to build, but it’s finally ready – a global translation glossary for each client.

Many words can be translated in different ways and it’s important that everything we translate come out the same.

The solution is a glossary.

A glossary helps produce consistent translations, as it shows how phrases were translated before.

Website owners and developers can create entries for important phrases. These entries can include the translation and serve as guidelines for the translators, or remain untranslated, so that translators can suggest the right translation.

As translators work, they too can add glossary entries. These entries will help translate the rest of the project consistently and also serve as reference for other translators who work on the project.

Now it's ready for website translation projects

We've had this working for Software localization and for Instant translation projects for a while now at ICanLocalize. Now users of our Drupal ICanLocalize translator module can use this feature to get consistent translations for their Drupal websites.

Here is a short clip showing how glossaries work in the translation tool. What you'll see is:

  1. Drupal blog post to translate
  2. The translation tool
  3. Existing glossary terms highlighted while translating
  4. Translator creating new glossary entries
This text will be replaced

Multilingual Sites that Translate Well

Drupal's t() function allows translating texts from one language to others. In order to work right, you must create texts that translate well. We’ll show you frequent mistakes and how to correct them.

Localization 101

Once you've created a site, using the t() function, Drupal will scan the texts and send them to translation. The String translation mechanism allow replacing the texts in the original language with texts in other languages.

Translators cannot change anything else in the site or in the HTML. They only translate the texts that you give them.

Some of the things that translators cannot do:

  • Change the order in which texts appear
  • Merge or split texts
  • Translate texts that are not inside the t() function

Give your translators complete sentences

When translators get single words to translate, it's practically impossible to translate them correctly. They need to see full sentences in order to translate with meaning.

A common case is the login message:

You must be logged in to post a comment.

Too often, folks create this message using this code:

<?php print t('You must be') ?> <a href="<?php print url('user/login') ?>">
<?php print t('logged in ') ?></a> <?php print t('to post a comment.') ?>

This means that the translator now sees three strings to translate:

You must be
logged in
to post a comment.

Each of these strings makes little sense.

Did you know that the English word "be" has several meanings in Spanish?

Be can mean what you are (ser) or where you are (estar). Translators cannot tell which one you mean when they just see "you must be".

To fix this and create a sentence that translates well, we'll merge all these strings into a single sentence, as it's supposed to be in the first place.

We'll use placeholders to insert values from other functions into the sentence.

<?php print t('You must be <a !link>logged in</a> to post a comment' ),
 array('!link' => 'href="' . url('user/login') . '"') ) ?>

Now, it's crystal clear. The translator sees one sentence, from start to finish. If needed, the translator can swap between parts of the sentence and write it correctly in any language.

Beyond complete sentences

When we create multilingual sites, we need to remember that translation is not everything. Localization means adapting the site to a different language, country and conventions.

We need to create interface strings that allow adjusting things like:

  • Number formats
  • Date formats
  • Units
  • Phone numbers (adding country codes)
  • Addresses (adding the country)
  • and many others...

The first and most important step is understanding. Once we understand that localization only begins with adding t() functions, we'll create much better websites that read natural in any language.

Working with the Domain Access module

One of our clients at ICanLocalize has a number of sites that rely heavily on the Domain Access module. We thought that we had tested our ICanLocalize Translator module thoroughly with this module but nothing replaces a real live test.

For those that are not aware:

The Domain Access project is a suite of modules that provide tools for running a group of affiliated sites from one Drupal installation and a single shared database.

Problems found

1. ICanLocalize returned translations to the wrong domain.

What should happen here is that the all the translations of a node should be published in the same domain as the original node. What we found was that the domain information was not being saved at all for the translated nodes. After tracing through the code I found that all the domain information for a node was set correctly when calling node_save() but was not being saved to the domain access tables. It turns out that the Domain Access module was caching some of its data and the cached values where not always correct due to the way our module was accessing the saved node at a later stage. See for details.

We managed to fix this with the changes kindly done by the maintainer of the Domain Access module and changing the order of things in our ICanLocalize translator module.

2. Duplicate translated nodes were being created.

What was happening was that when an updated translation was being saved by the ICanLocalize Translator module, it was creating a completely new node instead of updating the content of translated node. It seemed that our module could not determine that the node was already translated. With the help of the client we checked what was in the database and what was returned by the function translation_node_get_translations. All appeared to be OK so why was it going wrong? Our module calls translation_node_get_translations to find the translated nodes. When the client ran it, it returned the translated nodes but when it was called from the ICanLocalize Translator module, didn't return any translations.

After a bit of head scratching it dawned on me that maybe it was another Domain Access issue. When we send back translations from the ICanLocalize server they get sent back via XML-RPC. When the XML-RPC function gets called it runs in the default domain so calling translation_node_get_translations returns none because the Domain Access module determines the original node was in a different domain.

To fix this I created our own version of the "translation_node_get_translations" that bypasses Domain Access filtering of nodes.


ICanLocalize Translator should now work much better with the Domain Access module thanks to our client and the maintainer of the Domain Access module.

Domain Access is a powerful module and we intend to use it to deliver other client sites that require complex configurations. It's great to know that things work together now.

Internationalization at DrupalCon 2010

Gábor Hojtsy and Robert Douglass will be talking about internationalization and localization at DrupalCon SF. Parlez vous Internet? Ignore the rest of the world at your own risk.

If you are going to the conference I hope you can make it. It should be very interesting.


Managing a multilingual site

This site ( is in English, German and Spanish with English as the default language. All the content is written in English and then professionally translated to German and Spanish using the ICanLocalize translator module.

Unfortunately I don't understand German or Spanish so what happens when someone comments on a page that has been translated to German.

Running a test server for translations

A common question we get asked at ICanLocalize is:

What's the best way of translating our Drupal site with minimum downtime and minimum disruption to our existing users.

I guess there are a number of answers, this is one method.

Under construction

Create a test (Quality Assurance) server

Here I'll show you how to set up a test site that's a copy of your original site so that you can then use this to setup a multilingual site. You will then be able to use this test site to add the required multilingual modules, enable your languages and translate your content.

1) Create a copy of your Drupal source directory:
  eg. my directory is /home/bruce/drupal-6.15, copy it to /home/bruce/drupal-6.15-QA

cp -Rpv /home/bruce/drupal-6.15 /home/bruce/drupal-6.15-QA

2) Copy your database:
  eg. mine is db_drupal, I did a sql dump and reloaded to a new db, db_drupal_QA

3) Edit your copied settings.php file so it uses the new database.

$db_url = 'mysqli://username:password@localhost/drupal_db_QA';

4) Edit your copied settings.php file and give it a different base url.

$base_url = 'http://localhost/drupal-QA';

5) Edit your apache configuration file to point to the new drupal site:

<VirtualHost *:80>
  DocumentRoot /home/bruce/drupal-6.15-QA
  ServerName localhost
  <Directory /home/bruce/drupal-6.15-QA>
    AllowOverride All

6) Restart apache

apache2ctl restart

Now you should have a complete duplicate of your site running at:

You can now go ahead and setup your translated site.

  • Add languages
  • Add modules, i18n, ICanLocalize, etc
  • Enable language switch block
  • Translate the content
  • etc

See our how-to guide for further info: Setup for a multilingual site

Under construction

Once you have finished setting up your multilingual site all you need to do now is follow some of the above steps to copy your translated site back to your production site.

Note for ICanLocalize users: When moving the ICanLocalize settings to the production server you will need to ask the ICanLocalize team to change the settings on the ICanLocalize server so further translations are sent back to the correct server.

Handy SQL for translations

Here are a few handy SQL snippets for dealing with translated content on a Drupal site. These will be helpful if you are trying to translate a site and need to work out what content hasn't been translated yet.

1. Find nodes that haven't been translated.

  nid, title, language 
FROM node 
WHERE nid=tnid AND nid NOT IN (SELECT tnid FROM node WHERE language="es")

2. Find blocks that haven't been translated.

FROM locales_source
WHERE source IN (SELECT body FROM boxes) 
  AND lid NOT IN (SELECT lid FROM locales_target) 

3. Find blocks that are not in the locales_source table. These will be blocks that haven't been viewed in a translated language.

FROM boxes 
WHERE body NOT IN (SELECT source FROM locales_source)

Syndicate content