Contents
Introducción
Este tutorial muestra, con todo lujo de detalles, cómo crear un selector de idioma simple en WordPress y cómo persistir la elección del usuario usando JavaScript. La solución propuesta combina una interfaz mínima (un select), persistencia en localStorage y/o una cookie para que la preferencia sobreviva entre páginas y sesiones, y una pequeña capa en PHP para aplicar la preferencia en el servidor (p. ej. para que WordPress use el locale elegido).
Objetivo
- Crear un selector de idioma visible en el frontend.
- Persistir la selección del usuario en el navegador (localStorage) y en una cookie para uso del servidor.
- Opcionalmente, aplicar el idioma en el servidor con el filtro locale de WordPress.
- Ser compatible con implementaciones simples y servir como base para integrarlo con plugins de traducción (Polylang, WPML) si se desea.
Requisitos previos
- Conocimientos básicos de WordPress (functions.php, encolar scripts).
- Acceso para editar el tema hijo o plugin propio para añadir PHP/JS.
- Archivos .mo/.po del idioma si se desea que WordPress traduzca las cadenas core y del tema.
Enfoque general
Explicación rápida de la estrategia:
- Interfaz: un select con los idiomas disponibles (valores cortos como en, es, fr).
- Persistencia en cliente: guardar en localStorage para recuperar la preferencia sin necesidad de recarga guardar en cookie con expiración larga para que el servidor pueda leerla.
- Aplicación en servidor: usar el filtro locale para devolver el locale correspondiente si la cookie está presente (esto afecta las cadenas traducidas por WP core y temas/plugins que respeten la locale).
- Si se usan plugins de traducción, integrar con sus APIs (información al final).
Implementación paso a paso
1) HTML del selector
Coloca el selector donde quieras (header, footer, widget). En el ejemplo usamos un select con id language-switcher.
ltselect id=language-switcher aria-label=Seleccionar idiomagt ltoption value=engtEnglishlt/optiongt ltoption value=esgtEspañollt/optiongt ltoption value=frgtFrançaislt/optiongt lt/selectgt
2) CSS (opcional)
/ Estilos mínimos para el selector /
#language-switcher{
padding:6px 8px
border-radius:4px
border:1px solid #ccc
background:white
}
Este script inicializa el selector con la preferencia guardada (localStorage o cookie) y, cuando el usuario cambia el idioma, guarda la preferencia tanto en localStorage como en una cookie y recarga la página para que el servidor pueda actuar si corresponde.
(function(){
var SELECTOR_ID = language-switcher
var COOKIE_NAME = site_lang
var COOKIE_DAYS = 365
function setCookie(name, value, days){
var d = new Date()
d.setTime(d.getTime() (days2460601000))
var expires = expires= d.toUTCString()
document.cookie = name = encodeURIComponent(value) expires path=/
}
function getCookie(name){
var pattern = new RegExp((?:^ ) name =([^]))
var match = document.cookie.match(pattern)
return match ? decodeURIComponent(match[1]) : null
}
var sel = document.getElementById(SELECTOR_ID)
if(!sel) return
// Preferencia: localStorage primero, luego cookie, luego valor por defecto del select.
var saved = null
try {
saved = window.localStorage localStorage.getItem(site_lang)
} catch(e) {
saved = null
}
if(!saved){
saved = getCookie(COOKIE_NAME)
}
if(saved){
for(var i=0i
4) Encolar el script en WordPress y pasar información útil
En functions.php (tema hijo) encola el fichero JS. Además, puedes pasar desde PHP un array con idiomas disponibles y el idioma actual, para que el selector se genere dinámicamente o para usar datos desde JS.
// functions.php (tema hijo)
function mytheme_enqueue_lang_switcher(){
// Ajusta la ruta según tu tema / plugin
wp_enqueue_script( my-lang-switcher, get_stylesheet_directory_uri() . /js/lang-switcher.js, array(), 1.0, true )
available = array(
en => en_US,
es => es_ES,
fr => fr_FR,
)
wp_localize_script( my-lang-switcher, LangSwitcherData, array(
available => available,
current => get_locale(),
))
}
add_action( wp_enqueue_scripts, mytheme_enqueue_lang_switcher )
5) Aplicar la preferencia en el servidor (filtro locale)
Si deseas que WordPress cargue el locale elegido (y por tanto los .mo del core/tema/plugins), puedes usar el filtro locale y leer la cookie que puso el script. Esto debe usarse con cuidado: cambiar el locale no traduce automáticamente el contenido guardado (páginas/posts), solo las cadenas traducibles del sistema y los archivos de traducción disponibles.
// functions.php: forzar locale segun cookie site_lang
function mytheme_set_locale_from_cookie( locale ) {
if ( isset( _COOKIE[site_lang] ) ) {
lang = sanitize_text_field( wp_unslash( _COOKIE[site_lang] ) )
// Mapea códigos cortos a locales WP
map = array(
en => en_US,
es => es_ES,
fr => fr_FR,
)
if ( isset( map[ lang ] ) ) {
return map[ lang ]
}
}
return locale
}
add_filter( locale, mytheme_set_locale_from_cookie, 10 )
6) Alternativa: usar parámetro en la URL
En lugar de cookies, podrías añadir un query param (?lang=es) y en PHP detectar _GET[lang] para setear una cookie y redirigir al mismo URL sin el parámetro (limpia la URL). Esto es útil si quieres enlaces compartibles que fuerzan idioma.
// Ejemplo simplificado: si recibimos ?lang=xx, guardamos cookie y redirigimos
if ( isset( _GET[lang] ) ) {
lang = sanitize_text_field( wp_unslash( _GET[lang] ) )
setcookie( site_lang, lang, time() YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN )
// redirigir a la misma URL sin ?lang
url = remove_query_arg( lang )
wp_safe_redirect( url )
exit
}
Consideraciones prácticas y compatibilidad
Compatibilidad con plugins de traducción (Polylang, WPML)
- Los plugins de traducción manejan las URLs y la asociación de contenido en cada idioma. Si usas Polylang o WPML, lo ideal es usar la API del plugin para cambiar idioma y obtener la URL de la traducción de la página actual.
- Por ejemplo, Polylang tiene funciones como pll_the_languages() para mostrar un selector o pll_get_post() para obtener la versión traducida de un post. Evita sobrescribir la lógica del plugin con cookies si quieres mantener enlaces correctos.
- Si no usas plugin y solo quieres cambiar el locale de WP core (cadenas), la solución de cookie filtro locale es suficiente.
Accesibilidad
- Añade atributos ARIA (aria-label) al selector.
- Permite controlar el selector con teclado y ofrece textos alternativos visibles.
- Considera también alternativas no-JS para usuarios que tengan JavaScript deshabilitado (p. ej. enlaces de idioma que añadan ?lang=xx y que el servidor detecte).
SEO y webs multilenguaje
- Para SEO, lo correcto es servir contenido específico por URL (subdirectorios /es/, dominio por idioma, o subdominios). Un simple selector que solo cambia locale pero no la URL no es ideal para SEO si el contenido no está realmente traducido.
- Si cambias idioma mediante cookie pero no cambias URL, los motores de búsqueda podrían no ver versiones separadas para SEO robusto usa URLs separadas y etiquetas hreflang.
Privacidad y consentimiento
Guardar cookies para preferencias del usuario suele ser aceptable, pero revisa la política de cookies de tu sitio y el RGPD si aplica por ejemplo, algunas jurisdicciones requieren informar el tipo de cookie y su propósito.
Depuración y pruebas
- Prueba en modo incógnito, en diferentes navegadores y con cookies desactivadas para validar comportamientos alternativos.
- Revisa la carga de ficheros .mo/.po si usas el filtro locale para confirmar que WP carga los ficheros correctos.
Resumen y recomendaciones finales
La solución propuesta es simple y eficaz para ofrecer al usuario una manera de elegir idioma y mantener su preferencia entre páginas: un selector en HTML JS que guarda en localStorage y cookie, y un filtro locale en PHP que aplica la preferencia en el servidor. Para sitios con necesidades avanzadas (SEO, contenido traducido), complementa esto con URLs por idioma y/o integra completamente con plugins profesionales de traducción como Polylang o WPML.
Implementa primero la versión básica descrita aquí y luego adapta según la arquitectura de tu sitio (¿necesitas URLs por idioma? ¿usas un plugin ya?).
Acepto donaciones de BAT's mediante el navegador Brave 🙂
