Por que o WMPL não está redirecionando os usuários de acordo com o idioma do navegador?

Embora eu tenha “redirecionamento do idioma do navegador” ativado na canvas de configuração do WMPL, os usuários não estão sendo redirecionados corretamente de acordo com o idioma do navegador.

Atualmente, eu tenho três idiomas selecionados: en (default) , es e pt-br . Somente os usuários são automaticamente redirecionados para a página em espanhol. Usuários do pt-br não são, independentemente do navegador que eu uso.

Solutions Collecting From Web of "Por que o WMPL não está redirecionando os usuários de acordo com o idioma do navegador?"

Eu encontrei o que estava acontecendo, então vou respondê-lo para referência futura, pois é um problema comum sem uma solução clara.

TL; DR: Se o idioma WPML que não está redirecionando tiver um código de país (por exemplo, en-US em vez de en ), provavelmente você terá o mesmo bug. Ir para a seção “Como corrigi-lo” .


O problema

O problema surge no javascript de redirecionamento fornecido pelo WPML (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 (ie 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 } 

Como você pode ver na linha 4, o browserLanguage é aparado, de uma forma que pt-br se torna pt , en-us torna se en , e assim por diante. Provavelmente lá, portanto, usuários de diferentes locais, mas com o mesmo idioma, seriam redirecionados.

O problema real é na linha 10. languageUrls é uma matriz que contém todos os códigos de idiomas com suas respectivas URL, mas os códigos não são cortados!

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

Então, se o browserLanguage foi cortado, a condição if na linha 10 retorna falsa e, então, você não será redirecionado:

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

Além disso, mesmo que o browserLanguage não tenha sido cortado, ainda não funcionará completamente, porque alguns navegadores passam o browserLanguage com letras maiúsculas, como pt_BR , e ele simplesmente não combinaria.

Minha correção é usar duas variables browserLanguage , uma aparada e outra em minúscula. Então você compara a páginaLanguage com ambas, então o comportamento para usuários de “localização diferente, mesmo idioma” provavelmente permanecerá o mesmo e você corrigirá o erro.


A solução

Substitua o conteúdo de /wp-content/plugins/sitepress-multilingual-cms/res/js/browser-redirect.js com isso:

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

Solução de bônus

Os usuários serão redirecionados apenas uma vez. Este é um comportamento proposital (e horrível). Se você não está satisfeito com isso, você pode tentar outra alternativa. Basta ter em mente que este é um hack que redirectá todos os usuários com base no idioma do navegador, independentemente do idioma que escolher, então você DEVE ter todas as páginas traduzidas e evitar mostrar um switcher de idiomas, pois não funcionará.

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