When you use the WordPress translation functions to make your plugin or theme translatable, you pass in a text domain as a second parameter, like so:
<?php _e( 'Some Text String', 'my-plugin-name' ); ?>
This text domain is just a unique string (usually your plugin’s WordPress.org repository slug). Well, many plugin developers see code like this:
<?php _e( 'Another Text String', 'my-plugin-name' ); ?> <?php _e( 'Yet Another Text String', 'my-plugin-name' ); ?> <?php _e( 'Gosh, So Many Text Strings!', 'my-plugin-name' ); ?>
And they think to themselves “hm, I sure am typing the
'my-plugin-name' string a lot. I’ll apply the DRY (Don’t Repeat Yourself) principle and throw that string into a variable or a constant!”
Stop! You’re being too clever! That won’t work!*
See, PHP isn’t the only thing that needs to parse out your translatable strings. GNU gettext also needs to parse out the strings in order to provide your blank translation file to your translators. GNU gettext is not a PHP parser. It can’t read variables or constants. It only reads strings. So your text domain strings needs to stay hardcoded as actual quoted strings.
* Well, it won’t break your plugin, but it could make it harder to be used with automated translation tools. And trust me, you don’t want to be manually managing your translation files… we have a better solution coming.
35 thoughts on “Translating WordPress Plugins and Themes: Don’t Get Clever”
Actually, you can pass anything you want as the textdomain and gettext will parse it just fine.
What won’t work is passing a variable as the text to be translated.
Oh snap, MJ what’s your rebuttal?
My rebuttal is that this will work when doing once-off manual generation. But if you want to, say, automate the generation across, say, the entire WordPress.org plugin repository, you’re going to need to know the textdomain programmatically.
I’m afraid I don’t understand the distinction between manual generation (i.e. using WP’s own i18-tools) and the automation you mention.
The way I see it, you would have to make some additional assumptions, such that every plugin has the Textdomain: header set or that the textdomain is identical to the plugin slug.
You get the textdomain from the i18n calls.
As scribu said, Mark, you are wrong. The domain argument isn’t parsed at all. It is used only when the string is translated to choose the correct
.mofile and it’s perfectly OK to be a variable.
One thing that won’t work with the domain-as-variable approach is the add-textdomain.php. It expects the domain you give to be a literal string and not a PHP expression.
Ha! Yup… Hybrid Core dose this for quite some time and works just fine 🙂
Ugh … I wish you would have posted this last week, but still great information to have. I just need to fix a newly released plugin now. Thanks!
Mark I think you’re getting clever by inventing the new </php tag 😛
I use the WordPress.org tool for generating the .pot file and it seems like it’s always worked fine with using a variable for the text domain.
See my above response to Scribu. It’s about automation, not manual generation (where you can just rename things if they’re wrong).
Ben manuel nesil (yani WP kendi I18-araçları kullanarak) ve söz otomasyon arasındaki ayrım anlamıyorum korkuyorum.
Başlık kümesi veya textdomain eklenti slug aynı I see it: yol, her eklenti Textdomain olduğu gibi bazı ek varsayımları yapmak olurdu.
Lütfen açıklığa kavuşturun
Loved way you present all stuff so gud <3<3<3
Mark, I’d love to hear you opinion about “redundant translations”. Like for example I have a plugin and I’d like to use the string “These revisions are identical.” in it. The WordPress core also contains exactly this string, so should I use _e(‘These revisions are identical.’, ‘myplugin’) or _e(‘These revisions are identical.’) instead in my plugin code?
Another funny case would be: _x(‘j F, Y @ G:i’, ‘revision date format’) …
Good info. Thanks for giving me the useful information. chin su su cu to nhu phich. Ok.
You are clever.
Thanks for giving me the useful information
What about using defines? Do the non-WP scripts look for ‘blah’ or will BLAH work?
It still allow you to easily change the text domain if you ever needed to, while cutting down significantly on app overhead associated with $thedomain = ‘pluginname’; __(‘the string’,$thedomain);
The question is, will an automation shell script care that the value is THEDOMAIN but WordPress processes uses ‘pluginname’?
If they need to be the same, as in define(pluginame,’pluginame’) then the define gains no advantage. If you ever needed to change the domain ID string for any reason, i.e. define(‘newpluginame’,’newpluginame’) you are stuck with just as much editing as using a string literal.
Thanks for giving the information, i am actually currently looking it. You are clever 🙂
The information I’ve found here are very helpful. Thanks for it!
thanks article cool web sites
tskler arkadaslar güzel bir paylasım sagolun
I think a very successful and useful bütün gazeteler
I don’t do even that. I route all translations through my own function t. It’s t that applies the text domain :p
$this->t( ‘translate this’ );
Actually after going through the i8ln page on wordpress.org it seems its not necessary to add the text domain manually. You can use the add-textdomain.php script to do that for you.
thanks Hybrid Core dose this for quite some time and works just fine yeahh
ugh it’s so hard to clear about PHB
Like it !
add ur blog to my Favorite list
Very useful, thanks
Comments are closed.