5

I'm trying to achieve, that when someone visits my wordpress page the .po (language-) packages of his pefered language are loaded. At the moment it is possible to change the language by adding a ?lang= parameter to the URL. But i want the right language to be selected based on the browser language.

My code:

<?php
// start the session 
session_start();
$browserlang = " ".$_SERVER['HTTP_ACCEPT_LANGUAGE'];

// if there's a "lang" parameter in the URL...  
if( isset( $_GET[ 'lang' ] ) ) { 

    // ...set a session variable named WPLANG based on the URL parameter...     
    $_SESSION[ 'WPLANG' ] = $_GET[ 'lang' ]; 

    // ...and define the WPLANG constant with the WPLANG session variable 
    $locale = $_SESSION[ 'WPLANG' ];
    echo 'Based on URL parameter';

// if there isn't a "lang" parameter in the URL...  
} else {

    // if the WPLANG session variable is already set...
    if( isset( $_SESSION[ 'WPLANG' ] ) ) {

        // ...define the WPLANG constant with the WPLANG session variable 
        $locale = $_SESSION[ 'WPLANG' ];
        echo 'Based on session variable';

   // if the WPLANG session variable isn't set...
   } else { 

        // set the WPLANG constant to your default language code is (or empty, if you don't need it)        
        $locale = $browserlang;
        echo 'Should be based on browser language. It is:' . $browserlang;

    } 
};
?>

$locale is used to set the language and select the right .po files.

Now i want $locale to be

$locale = 'en_US'

by default, but when someone enters the page that has default language "de", "de_DE", "de_CH" or "de_AT" it should be.

$locale = 'de_DE'

The Code im currently using isnt working.

$browserlang = " ".$_SERVER['HTTP_ACCEPT_LANGUAGE'];
echo $browserlang;

Shows me the right language, which is "de_DE", but $locale = $browserlang doesnt do anything. On the other hand when i set $locale = 'de_DE' it works...

Thank you guys in advance.

Edit:

When i use echo $locale is says de-DE. Thats very stange, because it doesnt work...

Edit 2:

Thats because it must be de_DE (underline) not de-DE (minus)... how to fix that?

Edit 3:

Finally it works.

Pintolus
  • 135
  • 3
  • 14
  • 1
    Why did you put a `" "` in front of your variable? If you remove that, it should work? – putvande Jun 01 '15 at 11:21
  • 2
    use [str_replace](http://php.net/str_replace) to change from **de-DE** to **de_DE**. `str_replace('-','_',$browserlang);` – Gabriel Moretti Jun 01 '15 at 11:26
  • 1
    Thank you both for your comments. @GabrielMoretti yes that would work. But i found another way: i'll edit my post in about 1min. – Pintolus Jun 01 '15 at 11:44
  • 1
    Is this file for lang configurtion? – Gabriel Moretti Jun 01 '15 at 11:53
  • @GabrielMoretti which file do u mean? – Pintolus Jun 01 '15 at 11:55
  • @putvande thank you for the hint, also fixed that, but that wasnt the flaw, since it did correctly readout the browser language. – Pintolus Jun 01 '15 at 11:58
  • 1
    The code on your question. If your app may grow up, you should look for a more generic solution. Otherwise, you will need to keep adding conditions for every new avaiable language (and it, in my opinion, violates the open-closed principle) – Gabriel Moretti Jun 01 '15 at 11:59
  • 1
    @GabrielMoretti At the moment there are no other translations planned. Only german and english. The file above is located in wp-lang.php and called in wp-config.php `require_once( dirname( __FILE__ ) . '/wp-lang.php' )`. – Pintolus Jun 01 '15 at 12:06
  • 1
    Please, add your solution as an Answer. Right now it's difficult to understand your post, too many "EDITs" and here at SO people expect to see the solution as an Answer. Thanks! – brasofilo Jan 10 '16 at 06:30

2 Answers2

2

Shows me the right language, which is "de_DE",

It shouldn't. The code you've shown us inserts a space before the header value.

Also, your code does not handle a multi-valued accept-language header which can also include preferences (e.g. see here for a parser)

How you normalize the value ( {"de", "de_DE", "de_CH","de_AT"} -> "de_DE" ) is up to you.

symcbean
  • 47,736
  • 6
  • 59
  • 94
  • So maybe i should combine my solution with the ones posted on this thread: http://stackoverflow.com/questions/3770513/detect-browser-language-in-php?rq=1 ? Some of them take care of multiple languages and q-values. – Pintolus Jun 01 '15 at 12:08
  • 1
    You could - but I'm not familiar with the APIs within Wordpress and how they expse the availability of languages. – symcbean Jun 01 '15 at 12:28
  • this question is not wordpress specific. The only parameter returned to wordpress is `$browserlang` which must contain the selected language. – Pintolus Jun 01 '15 at 12:32
0

Edit 3:

Got it working:

<?php
// start the session 
session_start();

// if there's a "lang" parameter in the URL...  
if( isset( $_GET[ 'lang' ] ) ) { 

    // ...set a session variable named WPLANG based on the URL parameter...     
    $_SESSION[ 'WPLANG' ] = $_GET[ 'lang' ]; 

    // ...and define the WPLANG constant with the WPLANG session variable 
    $locale = $_SESSION[ 'WPLANG' ];
    $languagemsg = 'based on url parameter';

// if there isn't a "lang" parameter in the URL...  
} else {

    // if the WPLANG session variable is already set...
    if( isset( $_SESSION[ 'WPLANG' ] ) ) {

        // ...define the WPLANG constant with the WPLANG session variable 
        $locale = $_SESSION[ 'WPLANG' ];
        $languagemsg = 'based on session variable';

    // if the WPLANG session variable isn't set...
    } else { 

        // set the WPLANG constant to your default language code is (or empty, if you don't need it) 
        $browserlang = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2);
        if ($browserlang == 'de') {$browserlang = 'de_DE';}
        else {$browserlang = 'en_US';}
        $_SESSION[ 'WPLANG' ] = $browserlang;
        $locale = $browserlang;
        $languagemsg = 'based on browser language';

    } 
};
?>

Modern browsers always list the prefered language in front of the others. Thats why i only pick the first two letters of the sting:

$browserlang = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"],0,2);

now i set $browserlang = de_DE for all language codes that begin with "de". For all other languages i set $browserlang = en_US.

'$languagemsg' is just for debugging reasons.

Pintolus
  • 135
  • 3
  • 14