Como crear un selector de idioma simple y persistirlo en JS en WordPress

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

  1. Crear un selector de idioma visible en el frontend.
  2. Persistir la selección del usuario en el navegador (localStorage) y en una cookie para uso del servidor.
  3. Opcionalmente, aplicar el idioma en el servidor con el filtro locale de WordPress.
  4. 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
}

3) JavaScript: persistir la elección (localStorage cookie)

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 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *