How does gettext handle dynamic content?

To build a little on what Mark said... the only problem with the above solution is that the static list must be always maintained by hand and if you add a new string before all the others or you completely change an existing one, the soft you use for translating might confuse the new strings and you could lose some translations.

I'm actually writing an article about this (too little time to finish it anytime soon!) but my proposed answer goes something like this:

Gettext allows you to store the line number that the string appears in the code inside the .po file. If you change the string entirely, the .po editor will know that the string is not new but it is an old one (thanks to the line number).

My solution to this is to write a script that reads the database and creates a static file with all the gettext strings. The big difference to Mark's solution is to have the primary key (let's call it ID) on the database match the line number in the new file. In that case, if you completely change one original translation, the lines are still the same and your translator soft will recognize the strings.

Of course there might be newer and more intelligent .po editors out there but at least if yours is giving you trouble with newer strings then this will solve them.

My 2 cents.


If you have somewhere in your code: <?=sprintf(_('%s poked %s'), $user1, $user2)?> and one of your languages needs to swap the arguments it is very simple. Simply translate your code like this: msgid "%s poked %s" msgstr "%2$s translation_of_poked %1$s"


Your best option is to use sprintf() function. Then you would use printf notation to handle dynamic content in your strings. Here is a function I found on here a while ago to handle this easily for you:

function translate()
{
    $args = func_get_args();
    $num = func_num_args();
    $args[0] = gettext($args[0]);

    if($num <= 1)
      return $args[0];

    return call_user_func_array('sprintf', $args);

}

Now for example 1, you would want to change the string to:

%s poked %s

Which you would input into the translate() function like this:

<?php echo translate('%s poked %s', $user1, $user2); ?>

You would parse out all translate() functions with poEdit. and then translate the string "%s poked %s" into whatever language you wanted, without modifying the %s string placeholders. Those would get replace upon output by the translate() function with user1 and user2 respectively. You can read more on sprintf() in the PHP Manual for more advanced usages.

For issue #2. You would need to create a static file which poEdit could parse containing the category names. For example misctranslations.php:

<?php

_('Cars');
_('Trains');
_('Airplanes');

Then have poEdit parse misctranslations.php. You would then be able to output the category name translation using <?php echo gettext($data['name']); ?>