Archive for the category “Tools”

December 12th, 2007 at 12:47 pm

Playing with xgettext

xgettext is a great shell tool to create po files (i.e. Gettext translation templates). It is also able to merge existing translations with new strings. For example, to create a po template from all PHP files in a directory tree and preserve already done translations from the file my_translation-de_DE.po, enter:

CODE:
  1. mv my_translation-de_DE.po messages.po
  2. find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
  3. mv messages.po my_translation-de_DE.po

Now you have a new my_translation-de_DE.po, with all the translated and the newly added strings appended to this file. (The --keywords parameter is very useful to specify your translation function(s), because if you do so, xgettext will not extract all the other strings, too.)

Unfortunately, xgettext is not able to expunge strings that are no longer existing. This behaviour is easy to explain: In many cases, you might be doing an incremental update of your translation template (i.e. you only add the strings for a subset of your files). If xgettext would expunge the translations for which no sting wasn't found in your code, you would always have to recreate the po template completely. Anyway, a little option to expunge translations that weren't found in the original, would be nice.

A little trick will at least help to determine the strings that do no longer exist: Open the po file to be merged and delete all #: lines (the regex ^#:.*$ will match them). Then merge the files as usual. In the new file, all messages without a #: marker do no longer exist. You can even modify the above code to do so automatically:

CODE:
  1. grep -v "^#:" my_translation-de_DE.po> messages.po
  2. find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
  3. mv messages.po my_translation-de_DE.po

This way, you will preserve your translations, but your references are recreated, and you can easily see which strings do not exist anymore.

Update, 16.04.08: When I wrote this post, I didn't know about the msgmerge tool. Using it is much better than the grep foo above. Use it as follows:

CODE:
  1. echo ''> messages.po # xgettext needs that file, and we need it empty
  2. find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
  3. msgmerge -N existing.po messages.po> new.po
  4. mv new.po existing.po
  5. rm messages.po

It looks a bit more complex, but it's the best generic solution I can provide. Note the -N parameter for msgmerge: It suppresses the fuzzy mode, which yields more confusion and extra work than anything else.