Originalmente escrito em
janeiro 29, 2013
Atualizado
janeiro 2, 2020

Os programadores podem criar seus próprios seletores de idioma personalizados usando a chamada de API icl_get_languages do WPML. Neste tutorial, você descobrirá todos os detalhes da icl_get_languages e exemplos de seletores de idioma personalizados criados com ela.

Rápida visão geral:

  1. Chamar icl_get_languages para obter a lista de traduções da página exibida no momento
  2. Escrever sua própria função PHP que renderiza o seletor de idioma
  3. Colocar o seletor de idioma no seu tema

Obter a lista dos (outros) idiomas

Use icl_get_languages() para obter uma lista de traduções para qualquer página. Se estiver usando o WPML 3.2 ou superior, deve considerar a possibilidade de usar o filtro de hook 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), (padrão: id)
* DIR=asc/desc (padrão: asc)
* link_empty_to = str (padrão: vazio; funciona em conjunto com skip_missing=0 e permite usar links personalizados para os idiomas que não tiverem traduções do elemento atual. {%lang} pode ser usado como espaço reservado para o código de idioma)

Observações:

  • O parâmetro skip_missing diz à função como lidar com idiomas sem traduções.
  • A combinação de orderby e order permite criar o seletor de idioma suspenso ou seletores de idioma nos quais os idiomas sempre são exibidos na mesma posição.
  • A ordem personalizada pode ser definida na administração do WordPress em WPML » Idiomas » Opções de seletor de idioma.

A função retorna uma matriz com entradas por idioma. Por exemplo, para um site WordPress em inglês, francês e italiano, ela retornaria isso:

Array
(
 [en] => Array
 (
 [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] => Array
 (
 [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] => Array
 (
 [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 tem sua própria matriz de parâmetros, que a função de seu tema pode usar para criar qualquer seletor de idioma.

  • id: ID de referência interna.
  • active: É o idioma ativo no momento (apenas um idioma está ativo).
  • native_name: O nome nativo do idioma (nunca traduzido).
  • translated_name: O nome do idioma traduzido para o idioma ativo no momento.
  • country_flag_url: O URL para uma imagem PNG da bandeira do país.
  • url: O link para a tradução no idioma.
  • missing: 1 se a tradução para o elemento estiver faltando; 0 se existir.

Quando não há traduções

Algumas páginas talvez não sejam traduzidas para todos os idiomas. Você pode solicitar a icl_get_languages o que retornar para idiomas que não tenham traduções.

Se ‘skip_missing=1’, esses idiomas não aparecerão na saída gerada. Se ‘skip_missing=0’, todos os idiomas aparecerão, e os idiomas que não tiverem traduções conterão um link para a página inicial naquele idioma.

Como usar nas funções de seu tema

É possível criar seus próprios seletores de idioma da forma que preferir. Vamos mostrar duas formas comuns de utilização:

As funções de PHP que mostramos aqui devem ser inseridas no arquivo functions.php (na pasta do tema) e não no plugin.

Este post também está disponível em…

Suponhamos que você queira adicionar uma linha na parte inferior ou superior de cada post para mostrar em quais outros idiomas ele está disponível. Essa função só deve retornar posts já traduzidos e, caso não haja nenhuma tradução disponível, não deve gerar nada.

function icl_post_languages(){
 $languages = icl_get_languages('skip_missing=1');
 if(1 < count($languages)){
 echo __('This post is also available in: ');
 foreach($languages as $l){
 if(!$l['active']) $langs[] = '<a href="'.$l['url'].'">'.$l['translated_name'].'</a>';
 }
 echo join(', ', $langs);
 }
}

O que essa função faz é:

  1. Obter a lista de idiomas do WPML — $languages = icl_get_languages(‘skip_missing=1’);
  2. Verificar se o post existe em mais de um idioma — if(1 < count($languages))
  3. Gerar a saída, ignorando o idioma que está sendo exibido no momento — if(!$l[‘active’])

Observações:

  1. A mensagem passa por gettext. Isso é muito importante para que essa mensagem (a qual você deverá acrescentar a posts em diferentes idiomas) apareça no idioma correto: __(‘This post is also available in: ‘);
  2. Os nomes dos idiomas usados são os traduzidos. Isso garante que a frase inteira seja escrita no idioma certo: $l[‘translated_name’]

O resultado é este:

Mensagem (em inglês) sobre post disponível em outros idiomas
Mensagem (em inglês) sobre post disponível em outros idiomas

Para incluir essa mensagem nos posts, adicione uma chamada a icl_post_languages() do single.php.

Lista de nomes de idiomas e bandeiras para o rodapé

Mesmo que você já tenha um seletor de idiomas no topo da página, é bom adicionar uma lista de idiomas e bandeiras ao rodapé. Muitas pessoas imediatamente vão até o final da página para ter uma ideia melhor do que ela contém, por isso, colocar um seletor de idioma chamativo ali provavelmente ajudará visitantes estrangeiros.

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

Essa função faz o seguinte:

  1. Se houver qualquer idioma com tradução, ela cria um DIV e inicia uma lista não ordenada: if(!empty($languages)){ echo ‘<div id=”footer_language_list”><ul>’;
  2. Processa cada idioma e o adiciona como item da lista.
  3. Se não for o idioma ativo, insere um link para a página no idioma: if(!$l[‘active’]) echo ‘<a href=”‘.$l[‘url’].'”>’;
  4. Adiciona a bandeira do idioma: <img src=”‘.$l[‘country_flag_url’].'” alt=”‘.$l[‘language_code’].'” width=”18″ height=”12″ />
  5. Adiciona tanto o nome do idioma nativo quanto traduzido, caso sejam diferentes: echo icl_disp_language($l[‘native_name’], $l[‘translated_name’]);

A função icl_disp_language() é criada pelo WPML. O que ela faz é conferir se os dois argumentos (native_language_name, translated_language_name) são diferentes. Em caso afirmativo, ambos são gerados; do contrário, apenas um deles.

Devemos adicionar também um pouco de CSS para estilizar esta lista de idiomas. O CSS irá centralizar a lista de idiomas no rodapé e formatá-la um pouco.

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

Aqui está o seletor de idioma:

Rodapé com idiomas
Rodapé com idiomas

Para inseri-lo em seu tema, adicione a chamada a languages_list_footer ao arquivo footer.php .

* Observação: você pode transformar com facilidade esse seletor de idioma horizontal em vertical. É só remover a declaração display: inline do CSS.

Seletor de idioma só com bandeiras

Função simples para exibir bandeiras com links para as traduções da página atual.

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

O resultado gerado por essa função precisa ser estilizado separadamente. Por exemplo, a função poderia ser colocada dentro de um bloco div, e estilos personalizados poderiam ser definidos para as tags img.

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

O CSS:

#flags_language_selector img{
 margin:1px;
 border:1px solid #333;
}
Seletor de idioma de bandeiras

Seletor de idioma que exiba apenas idiomas inativos

O exemplo de programação nesse artigo pode ser usado para criar um seletor de idioma com as seguintes características:

  • Exibição horizontal;
  • Incorporado a um menu específico;
  • Com bandeiras e nomes nativos de idiomas;
  • Apenas idiomas inativos exibidos.

Esse código de programação deve ser adicionado ao arquivo functions.php de seu tema. Uma solução ainda melhor é adicioná-lo ao functions.php do tema filho de seu tema.

Por padrão, ele funciona bem com os temas padrão do WordPress (Twenty Sixteen, Twenty Fifteen, etc.) com theme_location == ‘primary’.

Este é o seletor de idioma no tema Twenty Sixteen quando o idioma atual é o inglês.
Este é o resultado no tema Twenty Sixteen quando o idioma atual é o inglês.

Como fazer a programação funcionar com seu tema

Outros temas talvez usem outras localizações. Assim, se o código de programação não estiver funcionando no seu tema, siga as etapas abaixo.

  1. Faça com que a linha não seja mais um comentário. Ou seja, retire as barras duplas (//) do início da linha de programação mencionada.
  2. Acesse a interface de seu site. Você verá local(is) de tema como [theme_location] => meu-local-de-tema.
  3. Selecione o local de menu que quiser (p. ex.: meu-local-de-tema) e mude a linha:
if ( $languages && $args->theme_location == 'primary') {

Para:

if ( $languages && $args->theme_location == 'meu-local-de-tema') {

Se não tiver certeza sobre o local certo a utilizar, pode experimentar os locais de menu um por um.

  1. Desfaça as alterações que realizamos no primeiro passo para que a linha volte a ficar igual à da programação original.

A programação

// Filtrar wp_nav_menu() para adicionar links extras e outras saídas
// Mostrar apenas outros idiomas no seletor de idioma
// Usar o novo 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) {
 // faça com que isso não seja mais um comentário para encontrar o local do menu em seu tema
 //echo "args:&lt;pre&gt;"; print_r($args); echo "&lt;/pre&gt;";

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

 // adicionar $args-&gt;theme_location == 'primary-menu' na condicional se quiser especificar o local do menu.

 if ( $languages &amp;&amp; $args-&gt;theme_location == 'primary') {

 if(!empty($languages)){

 foreach($languages as $l){
 if(!$l['active']){
 // bandeira com o nome nativo
 $items = $items . '
&lt;li class="menu-item"&gt;&lt;a href="' . $l['url'] . '"&gt;&lt;img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /&gt; ' . $l['native_name'] . '&lt;/a&gt;&lt;/li&gt;

';
 // apenas bandeira
 //$items = $items . '
&lt;li class="menu-item menu-item-language"&gt;&lt;a href="' . $l['url'] . '"&gt;&lt;img src="' . $l['country_flag_url'] . '" height="12" alt="' . $l['language_code'] . '" width="18" /&gt;&lt;/a&gt;&lt;/li&gt;

';
 }
 }
 }
 }

 return $items;
}

Como substituir as bandeiras e mudar os nomes dos idiomas

O WPML inclui uma interface gráfica para edição das informações de idiomas. Acesse WPML Idiomas e clique em Editar idiomas. Você poderá mudar os nomes dos idiomas, editar os valores de locale deles e escolher bandeiras diferentes.

'skip_missing=0&orderby=name'