为什么WMPL不能基于浏览器语言正确地重定向用户?

时间:2013-05-08 作者:emi

尽管我在WMPL的设置屏幕上激活了“浏览器语言重定向”,但用户并没有根据浏览器语言正确重定向。

我目前选择了三种语言:en (default), espt-br.只有es 用户将自动重定向到西班牙语页面。pt-br 无论我使用什么浏览器,用户都不是。

1 个回复
SO网友:emi

我已经找到了发生的事情,所以我将回答它以供将来参考,因为这是一个没有明确解决方案的常见问题。

TL;DR: 如果未重定向的WPML语言具有国家代码(例如。en-US 而不是en) 那么你可能也有同样的bug。跳转到节"How to fix it".

问题出现在WPML提供的重定向javascript上(browser-redirect.js):

[...]

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行所示,browserLanguage 在某种程度上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 根本没有修剪,它仍然不能完全工作,因为有些浏览器通过browserLanguage 用大写字母,如pt_BR, 这根本不匹配。

我的解决方法是使用两个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;
                    }    
                }
            }
        }
    }
});

奖金解决方案

用户只会被重定向一次。这是不切实际的(可怕的)行为。如果您对此不满意,可以尝试另一种选择。请记住,这是一种黑客行为,无论用户选择何种语言,都会根据其浏览器语言重定向所有用户,因此您必须翻译所有页面,并避免显示语言切换器,因为它不起作用。

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;
                }
            }
        }
    }
});

结束

相关推荐

multi-language WordPress site

我正在制作由WordPress支持的多语言网站。WPML 不是免费的,而且它对数据库进行了太多额外的sql查询,所以对于我的站点来说,这不是一个好的解决方案。qTranslate 将所有语言保存在一个数据库行中,以后移动到另一个多语言插件非常复杂。<?php _e( \'<!--:en-->english text<!--:--><!--:de-->german text<!--:-->\' ); ?> xLanguage 两年多没有更新