8

I was wandering... All the translation functions (__(), _e(), _x() and so on) use the current/active language. Is there a way to get a translation from another language than the current one? For example, I'm on a French page and I want and english translation: how to?

2

To find the answer to this question, you just need to look at how WordPress retrieves the translations. Ultimately it is the load_textdomain() function that does this. When we take a look at its source we find that it creates a MO object and loads the translations from a .mo file into it. Then it stores that object in a global variable called $l10n, which is an array keyed by textdomain.

To load a different locale for a particular domain, we just need to call load_textdomain() with the path to the .mo file for that locale:

$textdomain = 'your-textdomain';

// First, back up the default locale, so that we don't have to reload it.
global $l10n;

$backup = $l10n[ $textdomain ];

// Now load the .mo file for the locale that we want.
$locale  = 'en_US';
$mo_file = $textdomain . '-' . $locale . '.mo';

load_textdomain( $textdomain, $mo_file );

// Translate to our heart's content!
_e( 'Hello World!', $textdomain );

// When we are done, restore the translations for the default locale.
$l10n[ $textdomain ] = $backup;

To find out what logic WordPress uses to determine where to look for the .mo file for a plugin (like how to get the current locale), take a look at the source of load_plugin_textdomain().

  • But where does the first $textdomain come from? – Luca Reghellin Jul 28 '17 at 8:29
  • Indeed, where does it come from? For example, one of my actions/filters wont get the correct locale, when others do. How to figure this one out? It's "pending_to_publish" hook for example ... if I want to send emails there, they are always in a defined language whereas in "transition_post_status" hook it gets the correct language. Any thoughts? – trainoasis Mar 20 '18 at 11:22
  • @trainoasis I've updated the example to show example values, but you can see how to get the current locale from the source of load_plugin_textdomain(). – J.D. Mar 20 '18 at 17:17
  • I updated the code below, because I found out that sometimes $l10n[$textdomain] is not setted, even after loading the text domain in a after_setup_theme action. – Luca Reghellin Aug 13 '18 at 12:08
0

So thanks to J.D., I finally ended up with this code:

function __2($string, $textdomain, $locale){
  global $l10n;
  if(isset($l10n[$textdomain])) $backup = $l10n[$textdomain];
  load_textdomain($textdomain, get_template_directory() . '/languages/'. $locale . '.mo');
  $translation = __($string,$textdomain);
  if(isset($bkup)) $l10n[$textdomain] = $backup;
  return $translation;
}


function _e2($string, $textdomain, $locale){
  echo __2($string, $textdomain, $locale);
}

Now, I know it shouldn't be, as per this famous article:

http://ottopress.com/2012/internationalization-youre-probably-doing-it-wrong/

But, I don't know, it works... And bonus: say you want to use it in admin, because the admin language is x, but you want to get/save data in lang y, and you're using polylang. So i.e. your admin is english, but you're on the spanish translation of a post, and you need to get spanish data from your theme locales:

global $polylang;
$p_locale = $polylang->curlang->locale; // will be es_ES
_e2('your string', 'yourtextdomain', $p_locale)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.