This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

So, you've developed your own package. Great! You did everything possible to make it a thing that will change the world. And to let the whole world use it, you enabled localization by writing all those t('…') that are described in the Internationalization and the t functions family how-to.

And now? How could your ready-to-be-translated package speak other languages?

Here it comes to help the gettext system. It can parse all your PHP files, and create the resources that translators can translate. Here's how you can obtain it:

  • For *nix systems: it's enough to do a simple apt-get install gettext.
  • For Mac OS X: MacPorts maintains a port of it
  • For Windows: I compiled the latest binaries: you can find them in GitHub.

Manual generation of translatable files

Generate the template file (.pot)

First of all, you need to extract translatable strings and create a so called Portable Object Template, actually a text file with a .pot extension. This is done by the xgettext command. For concrete5, you may want to use the following command line:

xgettext --default-domain=messages --output-dir=PotFolder --output=PotFileName --language=PHP --from-code=UTF-8 --add-comments=i18n --keyword --keyword=t:1 --keyword=t2:1,2 --keyword=tc:1c,2 --no-escape --add-location --no-wrap --files-from=FileList


  • PotFolder is the folder where to save the .pot file to be generated
  • PotFileName is the name of the .pot file (only its name, without folder specification)
  • FileList is the name of a file containing the list of all the .php files of your package

Once you have this .pot file, you have various options to translate it.

The simplest one is to use Transifex. It's an online collaborative tools, very powerful and it's free for open source projects.

Generate the translation files (.po)

If you don't want to use Transifex, you have to manually generate a Portable Object file for each language you want to translate. These are simple text files with a .po file extensions. They can be generated starting from the .pot file with the following command line:

msginit --input=PotFile --output=PoFile --locale=LocaleCode --no-wrap


  • PotFile is the name of the source .pot file you generated with xgettext
  • PoFile is the name of the .po to be generated
  • LocaleCode is the locale code (language code and country code, for instance it_IT for Italian - Italy)

Now that .po file can be translated, with for instance POEdit.

Update the translation files (.po)

What happens if you change your source files? Don't worry, your previous translations won't be lost. YOu simply re-create the .pot file with xgettext as mentioned above, and you only have to update your .po file with this command:

msgmerge --no-fuzzy-matching --previous --lang=LocaleCode --force-po --add-location --no-wrap --output-file=NewPoFile OldPoFile PotFile


  • LocaleCode is the locale code (language code and country code, for instance it_IT for Italian - Italy)
  • NewPoFile is the name of the new .po to be generated
  • OldPoFile is the name of your old .po containing translations
  • PotFile is the name of the source .pot file you generated with xgettext

Final step to use the translation files

Ok, now you have translated everything. How can you use it? concrete5 needs the compiled version of those .po files, that is the so-called Machine Object files (they have the .mo file extension). POEdit can compile the .po files into .mo files for you. If you want to do it yourself, you can use the following command line:

msgfmt --output-file=MoFile --check-format --check-header --check-domain PoFile


  • MoFile is the name of the .mo to be generated
  • PoFile iis the name of your .po containing translations

Now you can place this .mo file in the following location under your concrete5 installation folder:



  • PackageName is the folder where your package resides
  • LocaleCode is the locale code (language code and country code, for instance it_IT for Italian - Italy)

Automatic management of translation files

I've created a tool to help package developers to manage all the above manual process. You only need the gettext tools available in your path and the PHP interpreter installed.

With a great lack of creativity, I called my tool i18n. You can grab it from GitHub. You need the whole repo content, so just download it as a zip file (or git-clone it).

Once you got it, simply call the following line:

php i18n.php --webroot=concrete5root --interactive


  • concrete5root is the root folder of your local concrete5 installation

i18n will guide you throug the creation of the .pot file, the creation/update of the .po file and the generation of the .mo file. All that within seconds.

Final notes

In order to activate and use a package-specific language, that language must also be defined at the site-level. So, if for instance you have the file /packages/discussion/languages/it_IT/LC_MESSAGES/, to use it you need to have also the file /languages/it_IT/LC_MESSAGES/ You can download system-level language files from the developers > Translate concrete5 page.

The whole process from .php files to .mo files could be accomplished by POEdit. Anyway there are a few drawbacks with that. The bigger ones is that POEdit does not supports the t2() and tc() functions, and is not able to extract i18n comments.

Loading Conversation