Escrito originalmente
enero 16, 2013
Actualizado
marzo 19, 2020

Los desarrolladores pueden crear sus propios selectores de idiomas personalizados utilizando la llamada API icl_get_languages de WPML. En este tutorial podrá encontrar todos los detalles de icl_get_languages y ejemplos de selectores de idiomas personalizados creados con esta herramienta.

Descripción rápida:

  1. Llame a icl_get_languages para obtener la lista de las traducciones para la página actual.
  2. Escriba su propia función PHP que representa al selector de idiomas.
  3. Coloque el selector de idiomas en su tema

Obtener la lista de (otros) idiomas

Utilizar icl_get_languages() para obtener una lista de traducciones para cualquier página. Si está utilizando WPML 3.2 o superior, deberá considerar utilizar el filtro de llave similar wpml_active_languages.

Uso:

icl_get_languages('skip_missing=N&orderby=KEY&order=DIR&link_empty_to=str')

* N=0/1
* KEY=id/code/name/custom (name -> translated_name), (predeterminado: id)
* DIR=asc/desc (predeterminado: asc.)
* link_empty_to = str (predeterminado: vacío, funciona conjuntamente con skip_missing=0 y permite utilizar enlaces personalizados para los idiomas que no tienen traducciones para el elemento actual. {%lang} puede utilizarse como un marcador de posición para el código del idioma)

Notas:

  • El parámetro skip_missing indica a la función como tratar a los idiomas que no tienen traducción.
  • La combinación de orderby y order permite crear un selector de idiomas desplegable o selectores de idiomas en los que los idiomas siempre aparecen en la misma posición.
  • El orden personalizado se puede definir en el administrador de WordPress en WPML » Idiomas » Opciones del selector de idiomas

La función devuelve una matriz con entradas por idioma. Por ejemplo, para un sitio de WordPress que funciona en inglés, francés e italiano va a devolver lo siguiente:

Matriz
(
 [en] => Matriz
 (
 [id] => 1
 [active] => 1
 [native_name] => English
 [missing] => 0
 [translated_name] => English
 [language_code] => en
 [country_flag_url] => http://yourdomain/wpmlpath/res/flags/en.png
 [url] => http://yourdomain/about
 )

 [fr] => Matriz
 (
 [id] => 4
 [active] => 0
 [native_name] => Français
 [missing] => 0
 [translated_name] => French
 [language_code] => fr
 [country_flag_url] => http://yourdomain/wpmlpath/res/flags/fr.png
 [url] => http://yourdomain/fr/a-propos
 )

 [it] => Matriz
 (
 [id] => 27
 [active] => 0
 [native_name] => Italiano
 [missing] => 0
 [translated_name] => Italian
 [language_code] => it
 [country_flag_url] => http://yourdomain/wpmlpath/res/flags/it.png
 [url] => http://yourdomain/it/circa
 )
)

Cada idioma tiene su propia matriz de parámetros que puede ser utilizada por la función de su tema para crear cualquier selector de idiomas.

  • id: Id de referencia interna
  • active: idioma activo actualmente (hay exactamente un solo idioma activo)
  • native_name: el nombre nativo del idioma (no se traduce nunca)
  • translated_name: el nombre del idioma traducido al idioma activo actualmente
  • country_flag_url: la URL para una imagen PNG con la bandera del país
  • url: el enlace a la traducción en ese idioma
  • falta: 1 si falta la traducción de ese elemento, 0 si existe.

Tratamiento de traducciones que faltan

Es posible que algunas páginas no se traduzcan a todos los idiomas. Usted puede indicar a icl_get_languages qué se debe devolver a los idiomas sin traducciones.

Si ‘skip_missing=1’, estos idiomas no aparecerán en la salida. Si ‘skip_missing=0’, todos los idiomas y los idiomas con traducciones faltantes van a vincularse a la página de inicio en ese idioma.

Cómo utilizar en las funciones de su tema

Usted podrá crear sus propios selectores de idiomas de cualquier manera. Aquí le mostramos dos formas muy comunes.

El ejemplo de funciones PHP que mostramos aquí debería ir en su archivo functions.php (en la carpeta de tema) – no incluido en el plugin.

Esta entrada también está disponible en…

Suponiendo que desea agregar una línea, en la parte inferior (o superior) de cada entrada, indicando el orden en que los idiomas están disponibles. Esta función solo debe devolver las entradas traducidas existentes y si no hay traducciones disponibles, no se muestra nada.

function icl_post_languages(){
 $languages = icl_get_languages('skip_missing=1');
 if(1 < count($languages)){
 echo __('Esta entrada también está disponible en: ');
 foreach($languages as $l){
 if(!$l['active']) $langs[] = '<a href="'.$l['url'].'">'.$l['translated_name'].'</a>';
 }
 echo join(', ', $langs);
 }
}

Esta función actúa de la siguiente manera:

  1. Obtiene la lista de idiomas desde WPML – $languages = icl_get_languages(‘skip_missing=1’);
  2. Verifica que haya más de un idioma para esta entrada – if(1 < count($languages))
  3. Crea la salida, saltando el idioma actual – if(!$l[‘active’])

Notas:

  1. El mensaje pasa a través de gettext. Esto es muy importante para que este mensaje, que se anexará a las entradas de diferentes idiomas, aparezca en el idioma correcto: __(‘Esta entrada también está disponible en: ‘);
  2. Los nombres de idiomas que se utilizan son los nombres de idiomas traducidos. Esto garantiza que toda la frase esté escrita en el idioma correcto: $l[‘translated_name’]

El resultado es el siguiente:

Mensaje sobre entrada disponible en otros idiomas
Mensaje sobre entrada disponible en otros idiomas

Para incluir este mensaje en las entradas, se debe agregar una llamada a icl_post_languages() desde single.php.

Lista de nombres de idiomas y banderas para el pie de página

Aunque tenga un selector de idiomas en la parte superior de la página, es una buena idea agregar una lista de nombres de idiomas y banderas en el pie de página. Muchas personas se desplazan de inmediato hacia la parte inferior de la página, para tener una idea de lo que hay adelante, por eso es importante colocar un selector de idiomas prominente para ayudar a los visitantes extranjeros.

function languages_list_footer(){
 $languages = icl_get_languages('skip_missing=0&orderby=code');
 if(!empty($languages)){
 echo '<div id="footer_language_list"><ul>';
 foreach($languages as $l){
 echo '<li>';
 if($l['country_flag_url']){
 if(!$l['active']) echo '<a href="'.$l['url'].'">';
 echo '<img src="'.$l['country_flag_url'].'" height="12" alt="'.$l['language_code'].'" width="18" />';
 if(!$l['active']) echo '</a>';
 }
 if(!$l['active']) echo '<a href="'.$l['url'].'">';
 echo icl_disp_language($l['native_name'], $l['translated_name']);
 if(!$l['active']) echo '</a>';
 echo '</li>';
 }
 echo '</ul></div>';
 }
}

Esta función actúa de la siguiente manera:

  1. Si hay algún idioma de traducción, crea un DIV y comienza una lista sin ordenar: if(!empty($languages)){ echo ‘<div id=»footer_language_list»><ul>’;
  2. Pasa por cada uno de los idiomas y los agrega como un elemento de la lista.
  3. Si no es el idioma activo, también establece un enlace a la página en ese idioma: if(!$l[‘active’]) echo ‘<a href=»‘.$l[‘url’].'»>’;
  4. Agrega la bandera del idioma: <img src=»‘.$l[‘country_flag_url’].'» alt=»‘.$l[‘language_code’].'» width=»18″ height=»12″ />
  5. Agrega los nombres del idioma nativo y de los idiomas traducidos, si son diferentes: echo icl_disp_language($l[‘native_name’], $l[‘translated_name’]);

WPML crea la función icl_disp_language(). Esta función verifica si los dos argumentos (native_language_name, translated_language_name) son diferentes. Si es así, devuelve los dos, o de lo contrario, los devuelve solo una vez.

También se deben agregar algunos CSS para darle un estilo a esta lista de idiomas. Este CSS permitirá centrar la lista de idiomas en su pie de página y formatearla un poco:

#footer_language_list{
 margin-bottom: 25px;
 text-align: center;
}

#footer_language_list ul{
 list-style: none;
 margin:0;
 padding:0;
}

#footer_language_list ul li img{
 margin-right:5px;
}

#footer_language_list ul li{
 display:inline;
 margin:0 5px 0 5px;
 padding:0;
}

#footer_language_list ul li a, #footer_language_list ul li a:visited{
 color: #fff;
 text-decoration:underline;
}

#footer_language_list ul li a:hover, #footer_language_list ul li a:active{
 color: #fff;
}

Este es el selector de idiomas:

Pie de página de idioma
Pie de página de idioma

Para incorporarlo al tema, incluya la llamada a languages_list_footer en el archivo footer.php .

* Nota: es posible cambiar fácilmente este selector de idiomas horizontal por un selector de idiomas vertical . Solo debe eliminar la instrucción display: inline del CSS.

Selector de idiomas solamente con banderas

Función simple para exhibir banderas con enlace a las traducciones de la página actual.

Language selector with flags only
function language_selector_flags(){
    $languages = icl_get_languages('skip_missing=0&orderby=code');
    if(!empty($languages)){
        foreach($languages as $l){
            if(!$l['active']) echo '<a class="wpml-ls-item" href="'.$l['url'].'">';
            echo '<img src="'.$l['country_flag_url'].'" height="12" alt="'.$l['language_code'].'" width="18" />';
            if(!$l['active']) echo '</a>';
        }
    }
}

La salida de esta función debe configurarse por separado. Por ejemplo, se coloca la función en un bloque div y se definen estilos personalizados para las etiquetas img.

<div id="flags_language_selector"><?php language_selector_flags(); ?></div >

El CSS:

#flags_language_selector img{
 margin:1px;
 border:1px solid #333;
}
Selector de idiomas con banderas

Selector de idiomas solo con los idiomas inactivos

El ejemplo de código en este artículo puede utilizarse para crear un selector de idiomas con las siguientes características:

  • Exhibición horizontal
  • Se anexa a un menú específico
  • Utiliza banderas de idiomas y nombres nativos
  • Muestra solo idiomas inactivos

Este código se debe incorporar al archivo functions.php de su tema. Una solución aún mejor es incluirlo en el archivo functions.php del tema secundario de su tema.

De manera predeterminada, el código funciona muy bien con los temas predefinidos de WordPress (Twenty Sixteen, Twenty Fifteen, etc.) con theme_location == ‘primary’.

Este es el selector de idiomas del tema Twenty Sixteen cuando el idioma actual es inglés.
Este es el resultado del tema Twenty Sixteen cuando el idioma actual es inglés.

Hacer funcionar el código con su tema

Otros temas pueden utilizar otras ubicaciones de tema. Por lo tanto, si el código no funciona con su tema, siga estos pasos para lograr que funcione.

  1. Quite la marca de comentarios de la línea. En otras palabras, elimine la doble barra (//) al inicio de la línea que contiene el código antes mencionado.
  2. Visite la interfaz de usuario de su sitio. Podrá ver la ubicación de su tema como [theme_location] => my-theme-location.
  3. Seleccione la ubicación de menú que desee, p. ej.: my-theme-location y cambie la línea:
if ( $languages && $args->theme_location == 'primary') {

A:

si ( $languages && $args->theme_location == 'my-theme-location') {

Si no tiene la seguridad sobre cuál es la ubicación correcta para utilizar, simplemente puede probar cada una de las ubicaciones de menú.

  1. Revierta los cambios realizados en el primer paso, de manera tal que la línea sea la misma que el código original.

El código

// Filtrar wp_nav_menu() para agregar más enlaces y otra salida
// Mostrar otro idioma solamente en el selector de idiomas
// Utilizar el nuevo filtro: https://wpml.org/wpml-hook/wpml_active_languages/ 
add_filter('wp_nav_menu_items', 'new_nav_menu_items', 10, 2);
function new_nav_menu_items($items, $args) {
 // quitar la marca de comentarios aquí para encontrar la ubicación del menú de su tema
 //echo "args:<pre>"; print_r($args); echo "</pre>";

 // obtener idiomas
 $languages = apply_filters( 'wpml_active_languages', NULL, 'skip_missing=0' );

 // agregar $args->theme_location == 'primary-menu' en la condicional si desea especificar la ubicación del menú.

 if ( $languages && $args->theme_location == 'primary') {

 if(!empty($languages)){

 foreach($languages as $l){
 if(!$l['active']){
 // bandera con nombre nativo
 $items = $items . '
<li class="menu-item"><a href="' . $l['url'] . '"><img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /> ' . $l['native_name'] . '</a></li>

';
 //solo bandera
 //$items = $items . '
<li class="menu-item menu-item-language"><a href="' . $l['url'] . '"><img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /></a></li>

';
 }
 }
 }
 }

 return $items;
}

Reemplazo de las banderas y cambio de nombres de idiomas

WPML incluye una GUI para editar la información de los idiomas. Diríjase a WPML->Idiomas y haga clic en Editar idiomas. Podrá cambiar los nombres de los idiomas, editar sus valores locales y elegir banderas diferentes.

'skip_missing=0&orderby=name'

5 respuestas para “Selector de idiomas personalizado”

  1. Hola, cuando se utiliza un link de categoría en un menú, no aparecen los links de las traducciones para cada idioma…creo que esto es un bug, hay alguna solución?
    Gracias

  2. Ahi Explican los Idiomas Horizontalmente es asi exactamente como los Quiero, pero en el Header se podra hacer cambiando la palabra footer por header y tambien me podrian explicar a cual parte iria en la parte de functions asi como la parte del header y si va codigo en CSS

    Gracias

    Y estoy a sus Ordenes

  3. Hola buen dìa, tengo un problema, quiero agregar la barra de idiomas que aparece en el footer, en mi header.php, ya intente muchas formas y no me aparece, y ya me estoy desesperando, por favor alguie que me ayude

    • Para conseguir esto puedes editar el fichero header.php de tu tema e insertar esta linea justo despues del tag BODY:
      language_selector_footer() ?>