web-dev-qa-db-ja.com

WMPLがブラウザの言語に基づいてユーザーを正しくリダイレ​​クトしないのはなぜですか?

WMPLの設定画面で'ブラウザ言語のリダイレクト'を有効にしても、ユーザーがブラウザの言語に従って正しくリダイレ​​クトされません。

現在、3つの言語が選択されています。 en(デフォルト) es 、および pt-br es ユーザーのみがスペイン語ページに自動的にリダイレクトされます。 pt-br usersは、どんなブラウザを使っても関係ありません。

2
emi

何が起こっているのかわかったので、私は将来の参考のためにそれに答えるつもりです。それは明確な解決策がない共通の問題であるからです。

TL; DR: リダイレクトされていないWPML言語に国コードがある場合(例: en ではなく en-US )、おそらく同じバグがあります。 "その修正方法"へ/


問題

問題はWPML (browser-redirect.js) によって提供されるリダイレクトJavaScriptで起こります。

[...]

1  // Get page language and browser language
2  var pageLanguage = wpml_browser_redirect_params.pageLanguage;
3  var browserLanguage = navigator.language? navigator.language : navigator.userLanguage;
4  browserLanguage = browserLanguage.substr(0,2); // browser language may have double code (i.e. en-us)

[...]

5  // Compare page language and browser language
6  if (pageLanguage != browserLanguage) {
7     var redirectUrl;
8     // First try to find the redirect url from parameters passed to javascript
9     var languageUrls = wpml_browser_redirect_params.languageUrls;
10    if (languageUrls[browserLanguage] != undefined) {
11            redirectUrl = languageUrls[browserLanguage];
12    }
13    // Finally do the redirect
14    if (redirectUrl != undefined) {
15            window.location = redirectUrl;
16    }    
17 }

4行目でわかるように、 browser-language pt-br pt に、 en-us en になるようにトリミングされます。に。それはおそらくそこにあるので、異なる場所にいるが同じ言語を持つユーザーは両方ともリダイレクトされるでしょう。

実際の問題は10行目にあります。 languageUrls はそれぞれのURLを持つすべての言語コードを含む配列ですが、コードはトリミングされません。

languageUrls[]
en: "http://sitehere.com"
es: "http://sitehere.com?lang=es"
pt-br: "http://sitehere.com?lang=pt-br"

したがって、 browserLanguage がトリミングされている場合、10行目のif条件はfalseを返し、リダイレクトされることはありません。

if (languageUrls[pt] != undefined ) {
    // this part doesn't runs
}

また、 browserLanguage がまったくトリミングされていなくても、完全には機能しません。なぜなら pt_BR のように大文字で browserLanguage を渡すブラウザがあるからです。一致。

私の修正は2つの browserLanguage 変数を使うことです。それから、 pageLanguage を両方と比較します。そのため、「別の場所、同じ言語」のユーザーの動作は同じままになり、バグが修正されます。


ソリューション

/wp-content/plugins/sitepress-multilingual-cms/res/js/browser-redirect.js の内容を次のように置き換えます。

jQuery(document).ready(function(){
    if(jQuery.cookie != undefined) {
        // Check if cookie are enabled
        jQuery.cookie('wpml_browser_redirect_test', '1');
        var cookie_enabled = jQuery.cookie('wpml_browser_redirect_test') == 1;
        jQuery.removeCookie('wpml_browser_redirect_test');

        if (cookie_enabled) {
            var cookie_params = wpml_browser_redirect_params.cookie
            var cookie_name = cookie_params.name;
            // Check if we already did a redirect

            if (!jQuery.cookie(cookie_name)) {
                // Get page language and browser language
                var pageLanguage = wpml_browser_redirect_params.pageLanguage;
                var browserLanguage = navigator.language? navigator.language : navigator.userLanguage;
                browserLanguage = browserLanguage.toLowerCase()
                browserLanguageTrim = browserLanguage.substr(0,2); // browser language may have double code (i.e. en-us)

                // Build cookie options
                var cookie_options = {
                    expires: cookie_params.expiration / 24,
                    path: cookie_params.path? cookie_params.path : '/',
                    domain: cookie_params.domain? cookie_params.domain : ''
                };

                // Set the cookie so that the check is made only on the first visit
                jQuery.cookie(cookie_name, browserLanguage, cookie_options);

                // Compare page language and browser language
                if ((pageLanguage != browserLanguage) && (pageLanguage != browserLanguageTrim)) {
                    var redirectUrl;
                    // First try to find the redirect url from parameters passed to javascript
                    var languageUrls = wpml_browser_redirect_params.languageUrls;
                    if (languageUrls[browserLanguage] != undefined) {
                        redirectUrl = languageUrls[browserLanguage];
                    } else if (languageUrls[browserLanguageTrim] != undefined) {
                        redirectUrl = languageUrls[browserLanguageTrim];
                    }
                    // Finally do the redirect
                    if (redirectUrl != undefined) {
                        window.location = redirectUrl;
                    }    
                }
            }
        }
    }
});

ボーナスソリューション

ユーザーは一度だけリダイレクトされます。これは正当な(そして恐ろしい)振る舞いです。あなたがそれに満足していない場合は、別の方法を試すことができます。どんな言語を選択しても、これはブラウザの言語に基づいてすべてのユーザをリダイレクトするハックであることを覚えておいてください。したがって、 _ must _ すべてのページを翻訳してください。作業。

jQuery(document).ready(function(){
    if(jQuery.cookie != undefined) {
        // Check if cookies are enabled
        jQuery.cookie('wpml_browser_redirect_test', '1');
        var cookie_enabled = jQuery.cookie('wpml_browser_redirect_test') == 1;
        jQuery.removeCookie('wpml_browser_redirect_test');

        if (cookie_enabled) {
            var cookie_params = wpml_browser_redirect_params.cookie
            var cookie_name = cookie_params.name;
            var pageLanguage = wpml_browser_redirect_params.pageLanguage;
            var browserLanguage = navigator.language? navigator.language : navigator.userLanguage;
            var languageUrls = wpml_browser_redirect_params.languageUrls;
            browserLanguage = browserLanguage.toLowerCase()
            browserLanguageTrim = browserLanguage.substr(0,2);

            // First time cookie gets set
            if (!jQuery.cookie(cookie_name)) {
                // Build cookie options
                var cookie_options = {
                    expires: cookie_params.expiration / 24,
                    path: cookie_params.path? cookie_params.path : '/',
                    domain: cookie_params.domain? cookie_params.domain : ''
                };
                // Sets the cookie in a way that matches avaible languageUrls
                if (languageUrls[browserLanguage] != undefined) {
                    jQuery.cookie(cookie_name, browserLanguage, cookie_options);
                } else if (languageUrls[browserLanguageTrim] != undefined) {
                    jQuery.cookie(cookie_name, browserLanguageTrim, cookie_options);
                }  
            }
            /* If cookie language != page language then redirect
               !! WARNING: THIS DOESN'T ALLOWS LANGUAGE SWITCHING,
               !! BUT GUARANTEES ALL USERS ALWAYS GET REDIRECTED,
               !! ASSUMING BROWSERLANGUAGE IS THE RIGHT LANGUAGE.
               For better behaviour you should make the language switcher
               update the cookie. Bad, bad hack, but I like it better. */
            if (jQuery.cookie(cookie_name) != pageLanguage) {
                var redirectUrl;
                // Sets the url for redirection
                if (languageUrls[jQuery.cookie(cookie_name)] != undefined) {
                    redirectUrl = languageUrls[jQuery.cookie(cookie_name)];
                }
                // Finally do the redirect
                if (redirectUrl != undefined) {
                    window.location = redirectUrl;
                }
            }
        }
    }
});
2
emi