
🔄 Seletor de idiomas WPML: apenas códigos ISO, sem bandeiras nem nomes
As bandeiras de países num menu de site são uma escolha questionável. Metade da audiência vê a Union Jack como a sua própria bandeira, enquanto a outra metade não. A bandeira dos EUA a representar o inglês? Isso ignora completamente canadianos e australianos. E os nomes completos dos idiomas ("Русский," "Українська," "English") ocupam metade do menu num ecrã móvel.
Um formato compacto RU | UK | EN resolve ambos os problemas: lê-se instantaneamente, ocupa quase nenhum espaço e não está associado a geografia. São códigos ISO de idioma padrão de duas letras, compreendidos sem tradução em qualquer país.
Abaixo estão duas formas de substituir o seletor padrão do WPML por códigos ISO. A primeira utiliza um filtro de itens de menu (uma simples inserção no functions.php). A segunda é um shortcode que apresenta o seletor em qualquer parte do site.
💡 Visão geral rápida:
- Método 1: substituição dos itens do menu de navegação através do hook
wp_nav_menu_items, para um seletor incorporado no cabeçalho - Método 2: o shortcode
[wpml_custom_lang_ISO], que pode ser inserido em qualquer parte do tema (widget, rodapé, menu mobile) - CSS: estilização do separador
|, ocultação do idioma ativo, design responsivo
Como fica o resultado
Depois de o código ser adicionado, o seletor de idiomas é apresentado no formato RU | UK | EN, curto e limpo. O idioma ativo é destacado ou ocultado (controlado via CSS), enquanto os restantes idiomas são clicáveis e levam à respetiva tradução da página.

O código utiliza a função integrada do WPML icl_get_languages(), que devolve um array com os idiomas ativos do site e todos os dados relevantes: URL de tradução, código de idioma, estado ativo. Não existem dependências de terceiros, apenas a própria API do WPML.
Método 1: substituir itens do menu através de wp_nav_menu_items
Este método intercepta a saída do menu de navegação do WordPress e substitui os itens de idioma padrão por códigos ISO compactos e um separador.
Onde inserir: no functions.php do tema-filho (child theme) ou através do plugin Code Snippets (mais seguro, não é apagado quando o tema é atualizado).
Antes de adicionar o código, faça uma cópia de segurança do site completa. O código não é destrutivo e apenas adiciona saída, mas fazer uma cópia de segurança é uma boa prática sempre que se edita o functions.php.
1 /** 2 * Substitui os itens de idiomas do WPML no menu por códigos ISO. 3 * theme_location é definido conforme o seu menu. 4 */ 5 add_filter( 'wp_nav_menu_items', 'wpml_iso_menu_items', 10, 2 ); 6 7 function wpml_iso_menu_items( $items, $args ) { 8 // Verifica se a função WPML está disponível 9 if ( ! function_exists( 'icl_get_languages' ) ) { 10 return $items; 11 } 12 13 $languages = icl_get_languages( 'skip_missing=0&orderby=code' ); 14 15 // Indique aqui o theme_location do seu menu (por exemplo 'primary', 'top') 16 if ( empty( $languages ) || $args->theme_location !== 'primary' ) { 17 return $items; 18 } 19 20 $lang_links = ''; 21 22 foreach ( $languages as $lang ) { 23 $code = strtoupper( $lang['language_code'] ); 24 25 if ( $lang['active'] ) { 26 $lang_links .= '<span class="wpml-lang-item active">' . $code . '</span>'; 27 } else { 28 $lang_links .= '<a href="' . esc_url( $lang['url'] ) . '" class="wpml-lang-item">' . $code . '</a>'; 29 } 30 31 $lang_links .= '<span class="wpml-lang-sep">|</span>'; 32 } 33 34 // Remove o último separador 35 $lang_links = rtrim( $lang_links, '<span class="wpml-lang-sep">|</span>' ); 36 37 return $items . '<li class="menu-item wpml-iso-switcher">' . $lang_links . '</li>'; 38 }
O que acontece aqui. O hook wp_nav_menu_items é acionado sempre que cada menu do site está a ser construído. A condição $args->theme_location !== 'primary' restringe a substituição apenas ao menu que precisa; substitua 'primary' pelo theme_location do seu menu (verifique wp_nav_menu() no seu template ou no painel de administração em Aparência > Menus > Locais de exibição).
A função icl_get_languages('skip_missing=0') obtém todos os idiomas publicados. skip_missing=0 significa "mostrar o idioma mesmo que a página atual não tenha tradução", pelo que o utilizador é direcionado para a página inicial desse idioma em vez de um erro 404.
strtoupper() converte os códigos para maiúsculas: ru → RU. Se precisar de minúsculas, remova a chamada.
Método 2: o shortcode [wpml_custom_lang_ISO]
O shortcode é mais versátil: insira [wpml_custom_lang_ISO] em qualquer lugar — um widget, o corpo de uma página ou um template PHP através de do_shortcode(). Funciona bem num menu mobile, rodapé ou num bloco abaixo do cabeçalho.
Onde inserir: no functions.php (o mesmo ficheiro do Método 1). Pode manter ambos os métodos ativos em simultâneo; não entram em conflito.
1 /** 2 * Shortcode [wpml_custom_lang_ISO] — apresenta o seletor de idiomas em formato ISO. 3 * Inserção: [wpml_custom_lang_ISO] no texto ou <?php echo do_shortcode('[wpml_custom_lang_ISO]'); ?> no template. 4 */ 5 add_shortcode( 'wpml_custom_lang_ISO', 'wpml_shortcode_lang_iso' ); 6 7 function wpml_shortcode_lang_iso() { 8 if ( ! function_exists( 'icl_get_languages' ) ) { 9 return ''; 10 } 11 12 $languages = icl_get_languages( 'skip_missing=0&orderby=code&order=desc' ); 13 $output = ''; 14 15 if ( empty( $languages ) ) { 16 return ''; 17 } 18 19 foreach ( $languages as $lang ) { 20 $code = strtoupper( $lang['language_code'] ); 21 22 if ( $lang['active'] ) { 23 $output .= '<span class="wpml-lang-item active">' . $code . '</span>'; 24 } else { 25 $output .= '<a href="' . esc_url( $lang['url'] ) . '" class="wpml-lang-item">' . $code . '</a>'; 26 } 27 28 $output .= '<span class="wpml-lang-sep">|</span>'; 29 } 30 31 // Remove o último separador 32 $output = rtrim( $output, '<span class="wpml-lang-sep">|</span>' ); 33 34 return '<div class="wpml-iso-lang-switcher">' . $output . '</div>'; 35 }
A diferença em relação ao Método 1: o shortcode devolve uma string HTML em vez de acrescentar itens a um menu. Isto significa que pode colocá-lo em qualquer lugar, sem depender do theme_location. O parâmetro order=desc inverte a ordem dos idiomas (opcional; remova-o se não precisar dele).
Como encontrar o theme_location do seu menu
Se estiver a usar o Método 1, precisa de especificar exatamente o argumento theme_location. Abra o ficheiro de template onde o menu é chamado (normalmente header.php) e procure uma linha como:
1 wp_nav_menu( array( 'theme_location' => 'primary', 'menu_id' => 'primary-menu' ) );
O valor entre aspas simples, por exemplo 'primary', é o seu theme_location. Nomes comuns são primary para o menu principal e top para a barra superior. Substitua pelo seu na condição $args->theme_location !== 'primary' no código acima.
Outra forma: no painel de administração, vá a Aparência > Menus > separador "Gerir Locais", que lista todos os valores de theme_location registados para o seu tema.
Estilos CSS para o seletor
Um conjunto mínimo de estilos para manter o seletor com um aspeto limpo. Adicione-os em Aparência > Personalizar > CSS Adicional ou no ficheiro style.css do tema-filho.
1 /* Contentor do seletor */ 2 .wpml-iso-lang-switcher, 3 .wpml-iso-switcher { 4 display: flex; 5 align-items: center; 6 gap: 0; 7 font-family: 'Oswald', sans-serif; 8 font-size: 16px; 9 font-weight: 600; 10 text-transform: uppercase; 11 } 12 13 /* Ligações e idioma ativo */ 14 .wpml-lang-item { 15 color: #33445d; 16 text-decoration: none; 17 padding: 4px 2px; 18 transition: color 0.2s; 19 } 20 21 a.wpml-lang-item:hover { 22 color: #0073aa; 23 } 24 25 .wpml-lang-item.active { 26 color: #999; 27 cursor: default; 28 } 29 30 /* Separador */ 31 .wpml-lang-sep { 32 margin: 0 6px; 33 color: #ccc; 34 font-weight: 400; 35 } 36 37 /* Ocultar o idioma ativo e o separador seguinte */ 38 .wpml-lang-item.active, 39 .wpml-lang-item.active + .wpml-lang-sep { 40 display: none; 41 } 42 43 /* Adaptação para dispositivos móveis */ 44 @media screen and (max-width: 768px) { 45 .wpml-iso-lang-switcher, 46 .wpml-iso-switcher { 47 font-size: 18px; 48 padding: 8px 0; 49 } 50 }
O truque principal aqui: o seletor .wpml-lang-item.active + .wpml-lang-sep oculta o separador imediatamente a seguir ao idioma ativo. Se o idioma ativo estiver oculto, o separador ao lado dele também desaparece, pelo que não fica um | solto no início ou no fim da linha.
A fonte Oswald é usada como exemplo. Substitua-a pela fonte do seu tema ou remova completamente a linha font-family para herdar do tema. Depois de adicionar o CSS, teste o seletor em resoluções móveis usando as ferramentas de programador (F12 > Toggle device toolbar).
⁉️🤔 Perguntas frequentes
Posso mostrar nomes de idiomas em vez de códigos ISO?
> Sim, substitua $lang['language_code'] por $lang['native_name'] em ambas as variantes de código. Vai obter "Русский | English | Українська." Em alternativa, $lang['translated_name'] apresenta os nomes no idioma da página atual: se o visitante estiver na versão em inglês, verá "Russian | English | Ukrainian." Todas as chaves de array disponíveis estão listadas na documentação oficial do WPML para a função icl_get_languages().
Como removo um idioma que não tem tradução para a página atual?
Altere o parâmetro
skip_missing=0paraskip_missing=1na chamada aicl_get_languages(). Os idiomas sem tradução simplesmente desaparecem do seletor, sem deixar um link quebrado no seu lugar. Isto é útil para sites onde nem todas as páginas estão traduzidas: o menu mantém-se limpo, sem links que levem à página inicial ou a um erro 404.
O seletor não aparece. O que está errado?
Verifique três coisas. Primeiro, o plugin WPML está ativo e os idiomas foram adicionados em WPML > Languages? Segundo, o
theme_locationno código corresponde ao menu real (Método 1)? Terceiro, o shortcode está a ser chamado viado_shortcode()se o estiver a usar num template PHP em vez de no conteúdo da página (Método 2)? Se tudo estiver correto e o seletor continuar sem aparecer, ative oWP_DEBUGno wp-config.php e verifique o error.log; pode haver um erro de sintaxe no functions.php.
Como adiciono bandeiras junto aos códigos, por exemplo 🇬🇧 + EN?
Adicione um emoji de bandeira antes de
$codecom uma condição:if ($lang['language_code'] === 'en') $code = '🇬🇧 ' . $code;. Tenha em conta, no entanto, que os emojis de bandeiras podem não ser apresentados no Windows. Uma abordagem mais fiável é usar bandeiras em CSS através de::beforecom background-image, ou as bandeiras integradas do WPML.
Este código funciona com o Polylang ou o TranslatePress?
Não:
icl_get_languages()é especificamente uma API do WPML. Para o Polylang, a função equivalente épll_the_languages(), e o TranslatePress tem o seu próprio conjunto de hooks. A lógica é a mesma, mas os nomes das funções são diferentes.
Conclusões: menu ou shortcode
O método do filtro de menu é para quem precisa do seletor estritamente na navegação e conhece com certeza o seu theme_location. Esforço mínimo: insira o código, substitua o nome do local, e está feito. A desvantagem: está associado a um único menu; para um segundo seria necessário duplicar o hook com um theme_location diferente.
O shortcode é o caminho a seguir se o seletor precisar de estar num local não convencional: um painel mobile, rodapé ou barra lateral. Adicione o shortcode a um widget "HTML" ou a um template e controle a sua posição através das ferramentas padrão do WordPress. A vantagem: pode inseri-lo em vários locais sem duplicar código.
Na prática, ambos os métodos coexistem pacificamente num único functions.php. Configure o filtro para o menu principal e o shortcode para a versão mobile, e obtém um RU | UK | EN limpo em todos os dispositivos. E se precisar do seletor uma terceira vez (por exemplo, no rodapé), basta adicionar outro do_shortcode('[wpml_custom_lang_ISO]') ao template apropriado.
Que formato de seletor utiliza: bandeiras, nomes ou códigos ISO? Partilhe a sua experiência a configurar sites multilingues nos comentários; seria interessante comparar abordagens.



