Maintaining translations in custom modules

Published by Lennart Van Vaerenbergh on March 26, 2015

Translations. Managing them can be a pain in the ass, especially when trying to keep them synched in all environmets.

When working with several server environments, for example a local machine, test server, staging server and live server, you'll want to manage your website translations at one place and deploy it afterwards to all other environments. In this blog post we'll see how to manage your custom module's translations through .po files included in the module.

This week a coworker of mine presented this tool 'Poedit' to manage translations in the so called .po files, so you can manage all translations in version control (in my case GIT). The idea is to use the tool for scanning a module, translate all found strings and save the file to the translations directory of the custom module. Yep, we don't even need Drupal to handle this process. The .po extension is, in the end, a universal file type for storing translations.

Required tools:

1. Use .po file editor Poedit to create a .po file

  • Download and install Poedit from (both for windows and osx)
  • Create a 'translations' directory in you custom module (this is important for scanning translations later on)
  • Create an empty .po file in the translations directory and paste the default header in it (this one is for dutch translations):
msgid ""
msgstr ""
"Project-Id-Version: PROJECT_NAME\n"
"POT-Creation-Date: 2014-01-01 00:00+0100\n"
"PO-Revision-Date: 2014-01-01 00:00+0100\n"
"Language-Team: TEAM <MAIL>\n"
"Language: Dutch\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.7\n"
"X-Poedit-KeywordsList: t;format_plural:2,3;watchdog:2;$t;Drupal.t;Drupal."
"X-Poedit-Basepath: ../\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-SearchPath-0: .\n"
  • Now let's configure Poedit so it can scan your Drupal modules for translations: Open the settings or preferences of Poedit and do the following:
    • General tab: uncheck 'Automatically compile MO file when saving'
    • Extractors tab: select PHP and click 'Edit': add the .module, .inc and .install extension to the list: *.php;*.php3;*.php4;*.phtml;*.module;*.inc;*.install
  • That's it, we're ready to scan our module and add or change translations. Open up your po file in Poedit, in the task bar, click on Catalogue > Update from Sources and all translatable strings are appearing.
  • Afterwards you can save the file and add it to your code repository, ready to deploy to other environments.

2. Manual adjustments in .po file (optional)

If you quickly want to add or change something in the .po file, you can. The only thing you have make sure of, is to update the "PO-Revision-Date" in the header of the .po file so Drupal can recognize it as an updated file.

3. Make Drupal able to scan all translation directories

Drupal doesn't do this by default. It only scans translation files in the /sites/all/translations directory. To scan all 'translations' directories in modules (probably your custom modules), install the contrib module Localization update bundled and enable it.

4. Scan and update translations.

Remember, Drupal only sees .po files with an updated revision date. Now let's update our Drupal translations in the database by scanning the .po files.
Option 1: use Drush
$ drush l10n-update-refresh && drush l10n-update
Option 2: use Drupal backend
Go to admin/config/regional/translate/update and go to the bottom of the page. Click on 'Refresh information' (equals "drush l10n-update-refresh"). Now you should see the outdated translations highlighted in yellow. Afterwards click on 'Update translations' (equals "drush l10n-update"). Your translations are processed now.


Submitted by Bart on Tuesday, July 07, 2015 - 17:02
To translate po files, the localization platform can also be used. This is an online app that can be used for managing the localization workflow, and for collaborative translation.
Submitted by Lennart on Tuesday, July 07, 2015 - 17:09
Thanks Bart! Haven't seen this page yet. Looks like it's worth a good look and perhaps another exposition in a blog post :).
Submitted by Bart on Wednesday, July 08, 2015 - 10:06
Cool! Looking forward to reading your opinion on it!

Add new comment

(If you're a human, don't change the following field)
Your first name.
(If you're a human, don't change the following field)
Your first name.
This challenge is for testing whether or not you are a human visitor and to prevent automated spam submissions.