[wp-hackers] Improvements to the WordPress l10n framework

Jamie Talbot wphackers at jamietalbot.com
Sat May 12 09:25:41 GMT 2007

Hash: SHA1

Omry Yadan wrote:
> Jamie Talbot wrote:
>>> From what I've seen in other systems, and from my own development
>>> experience, I got to the conclusion that the process of making your
>>> plugin l10n-enabled should be simplified for developers. Wrapping your
>>> strings with __() is easy, but if you need to start specifying your
>>> domain every line, you're not going to do it.
>> Why not?  A simple macro in your favourite code editor (assuming it's
>> not notepad) can insert this
>> automatically.  At worst it's just copy and paste.
> That can be used as an excuse to write any bad API.
> "ah, they can just use an IDE macro!"
> did you ever transform a plugin that does not support i18n, or have
> partial support (calls to __() and _e() without a domain) into a
> correctly localized plugin?
> its not fun, and its not pretty.

Of course I have - multilingualism is my special interest.  I maintain Gengo, a multilingual plugin.
 I also run wp-multilingual.net, - I rewrote connections reloaded to be correctly localised and no,
it wasn't pretty.  This isn't WordPress' fault, it was incorrectly localised.  The API isn't bad
just because authors can't be bothered/don't know how to use it properly.  It's not difficult,
people just don't know about it - hence my suggestion for better education.

> consider the difference between:
> $str = "There are ".$x." new messages";
> to:
> $str = __("There are ").$x.__(" new messages");
> pretty close.
> now, what does this do the the code readability?
> $str = __("There are ","foobar plugin").$x.__(" new messages","foobar
> plugin");
> even if plugin authors were aware of this option (and they are not),
> many will not use it simply because makes the code uglier.

Well firstly, they shouldn't do that anyway, because word order between different languages is
totally different.  What they should do is:

$str = sprintf(__("There are %s new messages", 'foobar_plugin'), $x);

Which I find very easy to read.

> you can argue that they can create a function like:
> function fb__($str) {return __($str,"foobar-plugin");}
> and call it instead, and you will be right, but I still think the domain
> specific translation for plugins should be initialized and provided by
> the platform.
>>> So this is where I ask
>>> you: How can this be done? Omry Yadan suggested this process (roughly):
>>> Plugin init loop:
>>> 1. When each plugin is initialized, its directory is searched for a
>>> translation file for the current locale. If it exists, it is loaded
>>> under the plugin name's textdomain. A global variable (Say,
>>> $pluginDomain) for the current plugin's domain is set.
>> What is this pluginDomain determined from?
> That's implementation detail.
> it can be the the name of the plugin file without the extension.

That's fine.

>>> 2. The plugin is initialized.
>>> 3. $pluginDomain is unset.
>>> When __() or _e() are called, if a string is not found in the default
>>> textdomain, they try to match the string to the textdomain named in
>>> $pluginDomain. That will also be backwards-compatible if current plugins
>>> intentionally don't name a domain to get the default.
>> I'm a bit confused with how this will work.  How will you determine
>> what $pluginDomain to check if
>> it has been unset?  How will you know which $pluginDomain to look in
>> if there are multiple localised
>> plugins?  This also seems pretty slow because it means first checking
>> the default domain, then
>> checking another domain (or lots of other domains).
> The idea is to have the correct domain active at the correct context.
> when calling the code of a particular plugin, its translation should be
> loaded and be made available through the standard __() and _e().

"Have the correct domain active at the correct context" - if you can actually explain how to do
this, I would be very excited.  You specify unsetting pluginDomain, at which point you lose context.
 And you surely realise that plugin strings are only translated as required, so we don't know the

> the only problem is that when the platform is calling hooks code, I
> don't think it knows which plugin "owns" that code, so it can't possibly
> make the correct translation available for it.
> maybe the right solution would be to flatten the entire translation
> space into a single hashtable, and load the plugins translations into it
> as well.

Exactly - we don't know which plugin 'owns' which string, which means we have to search a
potentially huge translation space for every string.  Why not then just do away with domains
altogether?  I'm not coming at this with no experience, and I'm not being deliberately negative -
just that your solution isn't really a solution at all.  I genuinely would be very interested if you
can supply concrete implementation details for your suggestion.


Version: GnuPG v1.2.5 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org


More information about the wp-hackers mailing list