Setting Wordpress language programmatically?
Asked Answered
D

8

18

I have a user based website with Wordpress and from their profile settings they are able to select the language, this info and other settings are set for every user in user_meta.

I know how to translate but, is there a way to set the theme language programmatically?

Thank you!

Edit: No plugins please, I need to do this as simple as possible.

Discerning answered 23/11, 2011 at 1:33 Comment(0)
D
8

I found a different solution:

// Set user selected language by loading the lang.mo file
if ( is_user_logged_in() ) {

    // add local filter
    add_filter('locale', 'language');

    function language($locale) {
        /* Note: user_meta and user_info are two functions made by me,
           user_info will grab the current user ID and use it for
           grabbing user_meta */

        // grab user_meta "lang" value
        $lang = user_meta(user_info('ID', false), 'lang', false); 

        // if user_meta lang is not empty
        if ( !empty($lang) ) {
           $locale = $lang; /* set locale to lang */
        }

        return $locale; 
    }

    // load textdomain and .mo file if "lang" is set
    load_theme_textdomain('theme-domain', TEMPLATEPATH . '/lang');

}

Via: http://codex.wordpress.org/Function_Reference/load_theme_textdomain

Discerning answered 26/11, 2011 at 13:59 Comment(1)
I found I needed to unload the textdomain in my situation, before loading the text domain again. Which gave me the following code (and I am using it for a plugin so it says load_plugin_textdomain for me. unload_textdomain('my-plugin-txt-domain'); load_plugin_textdomain('my-plugin-txt-domain', __DIR__ . '/../../languages');Kylakylah
S
23

Since WP 4.7 you can use:

switch_to_locale('en_US');

Reference: https://developer.wordpress.org/reference/functions/switch_to_locale/

Stickler answered 2/5, 2019 at 6:49 Comment(1)
Where should this be used? I put it in the 'init' hook but it doesn't work (it did work a few times actually and then stopped, oddly enough)Orta
D
8

I found a different solution:

// Set user selected language by loading the lang.mo file
if ( is_user_logged_in() ) {

    // add local filter
    add_filter('locale', 'language');

    function language($locale) {
        /* Note: user_meta and user_info are two functions made by me,
           user_info will grab the current user ID and use it for
           grabbing user_meta */

        // grab user_meta "lang" value
        $lang = user_meta(user_info('ID', false), 'lang', false); 

        // if user_meta lang is not empty
        if ( !empty($lang) ) {
           $locale = $lang; /* set locale to lang */
        }

        return $locale; 
    }

    // load textdomain and .mo file if "lang" is set
    load_theme_textdomain('theme-domain', TEMPLATEPATH . '/lang');

}

Via: http://codex.wordpress.org/Function_Reference/load_theme_textdomain

Discerning answered 26/11, 2011 at 13:59 Comment(1)
I found I needed to unload the textdomain in my situation, before loading the text domain again. Which gave me the following code (and I am using it for a plugin so it says load_plugin_textdomain for me. unload_textdomain('my-plugin-txt-domain'); load_plugin_textdomain('my-plugin-txt-domain', __DIR__ . '/../../languages');Kylakylah
A
3

I came up with following solution as I needed to generate invoices from a plugin in different languages in the scope of the same request:

    global $locale;

    $locale = 'en_CA';
    load_plugin_textdomain('invoice', false, 'my-plugin/languages/');
    generateInvoice(); // produce the English localized invoice

    $locale = 'fr_CA';
    load_plugin_textdomain('invoice', false, 'my-plugin/languages/');
    generateInvoice(); // produce the French localized invoice
Alvord answered 28/9, 2015 at 18:21 Comment(0)
H
2

I guess you're looking for the override_load_textdomain filter, called just in the beginning of a load_textdomain function call.

That would be something like:

function my_load_textdomain ($retval, $domain, $mofile) {

    if ($domain != 'theme_domain')
        return false;

    $user = get_currentuserinfo()
    $user_lang = get_user_lang($user);

    if ($new_mofile = get_my_mofile($user_lang)) {
        load_textdomain('theme_domain', $new_mofile);
        return true;
    }

    return false;
}
add_filter('override_load_textdomain', 'my_load_textdomain');

Code from brain to keyboard, not tested. You should do some more validations and so.

Hyunhz answered 23/11, 2011 at 13:49 Comment(4)
Thank you, I will give it a test and let you know.Discerning
I get "Warning: Missing argument 2 for my_load_textdomain() in [...]", the code is the same you posted.Discerning
Please note that the code I posted won't work as it is. It's just a reference for you to apply to your site environment. I just corrected the function call to accept the arguments the filter needs.Hyunhz
I found a different, more easy solution. Thanks! (I up-voted you).Discerning
I
2

For me only these two solutions together worked.

switch_to_locale($locale);
load_textdomain('example_domain', $mo_file_full_path);
Intolerable answered 20/3, 2020 at 10:23 Comment(0)
T
1

A had same question, I resolved it this way:

fist step you have to create a .mo with a text domain. You can use loco translate plugin: https://br.wordpress.org/plugins/loco-translate/

Load your text domain linking .mo file:

load_textdomain('your_text_domain', '/your/file.mo');

Change wordpress location via hook. Create a function wich returns wanted location. Use Wordpress Locale Id ever, you can see all locales Id here: https://wpastra.com/docs/complete-list-wordpress-locale-codes/

Lets write the function:

function wpsx_redefine_locale($locale){
  
  return 'ja';
}
add_filter('locale','wpsx_redefine_locale',10);

You can change by user location. This way wordpress sets the same language was be set by user in its control panel:

$user_locale = get_user_locale();
function wpsx_redefine_locale($locale){
  global $user_locale;
  return $user_locale;
}
add_filter('locale','wpsx_redefine_locale',10);

Obs: My wordpress version is 5.7. This way can no work in another versions. Good look!

Trilbie answered 7/7, 2021 at 17:33 Comment(0)
D
0

I had a similar problem and solved it like this:

  1. In my case I wanted to retrieve the locale by using the user locale: $userLocale = get_user_locale($userObject->ID);

  2. I created a custom function to load the correct theme_textdomain with dynamic locale. It's almost the same as the WP function, but you can add a locale variable:

    /**
     * Loads text domain by custom locale
     * Based on a WP function, only change is the custom $locale
     * parameter so we can get translated strings on demand during runtime
     */
    function load_theme_textdomain_custom_locale($domain, $path = false, $locale)
    {
        /**
         * Filter a theme's locale.
         *
         * @since 3.0.0
         *
         * @param string $locale The theme's current locale.
         * @param string $domain Text domain. Unique identifier for retrieving translated strings.
         */
        $locale = apply_filters('theme_locale', $locale, $domain);
    
        if (!$path) {
            $path = get_template_directory();
        }
    
        // Load the textdomain according to the theme
        $mofile = "{$path}/{$locale}.mo";
        if ($loaded = load_textdomain($domain, $mofile)) {
            return $loaded;
        }
    
        // Otherwise, load from the languages directory
        $mofile = WP_LANG_DIR . "/themes/{$domain}-{$locale}.mo";
        return load_textdomain($domain, $mofile);
    }
    

Based on: http://queryposts.com/function/load_theme_textdomain/

Degust answered 3/10, 2017 at 12:19 Comment(0)
S
0

actually switch_to_locale not working for me, and during debug I have find out load_textdomain make out of memory fatal error :/

Sailmaker answered 26/3, 2020 at 22:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.