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=0i4) 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 🙂