Get localized string for specific locale

How can I use the localization mechanism in WordPress to get access to an existing but not-current language string?

Background: I have a custom theme where I use locale ‘en_US’ as the default locale and translate through a PO file to locale ‘es_ES’ (Spanish).

Read More

Let us say I use the construction

__('Introduction', 'my_domain');

in my code, and that I have translated ‘Introduction’ to the Spanish ‘Introducción´ in my PO file. All this works fine.

Now to the problem: I want to insert n records in my database with all existing translations of the string ‘Introduction’ – one for each language; so, n = 2 in my example.

Ideally, I would write something like this:

$site_id = 123;
// Get an array of all defined locales: ['en_US', 'es_ES']
$locales = util::get_all_locales();
// Add one new record in table details for each locale with the translated target string
foreach ($locales as $locale) {
    db::insert_details($site_id, 'intro',
        __('Introduction', 'my_domain', $locale), $locale);
}

Only, that the 3rd parameter in __() above is pure fantasy on my part. You can only validly write

__(‘Introduction’, ‘my_domain’);

to get either ‘Introduction’ or ‘Introducción’ depending on the current locale.

The outcome of the code above would ideally be that I end up with two records in my table:

SITE_ID  CAT    TEXT             LOCALE
123      intro  Introduction     en_US
123      intro  Introducción     es_ES

I am aware that I want something that requires loading all the MO files, where normally, only the MO file for the current language is required. Maybe use of the WordPress function load_textdomain is necessary – I was just hoping there already exists a solution.


Expanding on the question by including the plugin PolyLang: is it possible to use Custom Strings to achieve the above functionality? E.g. conceptually:

pll_('Introduction', $locale)

Related posts

Leave a Reply

1 comment

  1. Old question I know, but here goes –

    Starting with a simple example where you know exactly what locales to load and exactly where the MO files are, you could use the MO loader directly:

    <?php
    $locales = array( 'en_US', 'es_ES' );
    foreach( $locales as $tmp_locale ){
        $mo = new MO;
        $mofile = get_template_directory().'/languages/'.$tmp_locale.'.mo';
        $mo->import_from_file( $mofile );
        // get what you need directly
        $translation = $mo->translate('Introduction');
    }
    

    This assumes your MO files are all under the theme. If you wanted to put more of this logic through the WordPress’s environment you could, but it’s a bit nasty. Example:

    <?php
    global $locale;
    // pull list of installed language codes
    $locales = get_available_languages();
    $locales[] = 'en_US';
    // we need to know the Text Domain and path of what we're translating
    $domain = 'my_domain';
    $mopath = get_template_directory() . '/languages';
    // iterate over locales, finally restoring the original en_US
    foreach( $locales as $switch_locale ){
        // hack the global locale variable (better to use a filter though)
        $locale = $switch_locale;
        // critical to unload domain before loading another
        unload_textdomain( $domain );
        // call the domain loader - here using the specific theme utility
        load_theme_textdomain( $domain, $mopath );
        // Use translation functions as normal
        $translation = __('Introduction', $domain );
    }
    

    This method is nastier because it hacks globals and requires restoring your original locale afterwards, but it has the advantage of using WordPress’s internal logic for loading your theme’s translations. That would be useful if they were in different locations, or if their locations were subject to filters.

    I also used get_available_languages in this example, but note that you’ll need the core language packs to be installed for this. It won’t pick up Spanish in your theme unless you’ve also installed the core Spanish files.