0

I want to change the Theme's interface language without making multisite by passing langauage parameter into the URL.

<a href="<?php echo home_url('/')?lang=bn ?>">Bengali</a>

My thought is to use the following code:

if(get_query_var('bn')) {

    /**
     * CHANGE THE 'WPLANG' IN wp-config.php TO bn_BD ON THEME SWITCHING
     * Thanks: toscho
     * Source: http://wordpress.stackexchange.com/a/121136/22728
     * -------------------------------------------------- */

    add_filter( 'locale', 'toscho_change_language' );

    function toscho_change_language( $locale ) {
        return 'bn_BD';
    }

}

With checking isset() of the parameter in URL, loading of this code block. And using the theme's language file bn_BD.

But I'm actually curious about the logical proceedings:

  • Is this concept Ok?
  • Will it load the theme's language file successfully?
2
  • 2
    Don't use get_query_var for variables that are not query variables. Use: toscho_change_language( $locale ) { $bn = filter_input( INPUT_GET, 'bn' ) ? : $locale; } no need of get_query_var, no need of isset, just one line effective function. Regarding the 2 questions, it seems ok to me, but to be honest locale is not a field where I'm expert.
    – gmazzap
    Commented Jun 9, 2014 at 9:10
  • Thanks @G.M. I answered in my way. Tried your one with a syntax error, saying unwanted bracket ({). Would love if you comment how I can make my answer with your code. With advance thanks. :) Commented Jun 9, 2014 at 10:34

2 Answers 2

1

2 notes regarding your own answer:

  • try to not access on super global variables directly, but using filter_input
  • your code throw a notice if $_GET['lang'] is not set

So your code can be improved:

function toscho_change_language() {
    return 'bn_BD';
}

if ( filter_input( INPUT_GET, 'lang', FILTER_SANITIZE_STRING ) === 'bn' ) {
  add_filter( 'locale', 'toscho_change_language' );
}

Or if your server has PHP 5.3+

if ( filter_input( INPUT_GET, 'lang', FILTER_SANITIZE_STRING ) === 'bn' ) {
  add_filter( 'locale', function() { return 'bn_BD'; } );
}

Finally, if you mind that in future you may want to support additional languages, you can write the function in a easily extensible way:

function gm_change_language( $locale ) {
    $langs = array(
       'bn' => 'bn_BD',
       'sw' => 'sw_TZ' // Tanzania Swahili 
    );
    $l = strtolower( filter_input( INPUT_GET, 'lang', FILTER_SANITIZE_STRING ) );
    return $l && array_key_exists( $l, $langs ) ? $langs[$l] : $locale; 
}

add_filter( 'locale', 'gm_change_language' );

Problem with this code is that clicking an inner link, language parameter is lost. A possible solution is to use a cookie to store the language.

I'll apply this improvement to last snippet, but can be used also in the previous.

function gm_change_language( $locale ) {
    $langs = array(
       'bn' => 'bn_BD',
       'sw' => 'sw_TZ' // Tanzania Swahili 
    );
    $l = filter_input( INPUT_GET, 'lang', FILTER_SANITIZE_STRING );
    if ( ! empty( $l ) ) {
       setcookie ( 'my_theme_lang', $l, 0 );
    } else {
       $l = filter_input( INPUT_COOKIE, 'my_theme_lang', FILTER_SANITIZE_STRING );
    }
    return $l && array_key_exists( $l, $langs ) ? $langs[$l] : $locale; 
}

add_filter( 'locale', 'gm_change_language' );

And sure, as you said, you need to translate your theme and load the texdomain using load_theme_textdomain.

And, just a note for future readers, to be able to translate strings in a theme, all of them must be wrote using i18n functions.

2
  • Begging a little bit of help so that the code can be bullet-proof. The parameter's getting gone when any inner link is clicked (stackoverflow.com/q/18972502/1743124). So how can I pass the code into a WP Session, and get the session data back using this function? Commented Jun 10, 2014 at 5:28
  • @MayeenulIslam updated answer to use a cookie to store language.
    – gmazzap
    Commented Jun 10, 2014 at 9:07
0

Trigger in template:

<a href="?lang=bn">BN</a>|<a href="<?php echo home_url(); ?>">EN</a>

Code in functions.php:

function toscho_change_language( $locale ) {
    return 'bn_BD';
}

if( $_GET['lang'] && $_GET['lang'] == 'bn' ) add_filter( 'locale', 'toscho_change_language' );

To make my theme translation-ready:

load_theme_textdomain( 'your-theme', get_template_directory() . '/lang' );

And I put my translation-file bn_BD.po (using Poedit) inside my theme's lang folder. And yala!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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