我已经找到了发生的事情,所以我将回答它以供将来参考,因为这是一个没有明确解决方案的常见问题。
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;
}
}
}
}
});