
Embora existam diferentes opiniões sobre qual é o melhor plugin para criar um blogue multilingue, e todos eles tenham evoluído muito desde as suas primeiras versões, simplificando e facilitando a tarefa, um dos mais utilizados é o Polylang.
Com mais de 700.000 instalações activas até à data, continua a ser uma das opções mais leves e eficazes.
Aqui está uma pequena lista de snippets com funções e filtros que podem ser úteis em algum momento. Todos eles funcionam na versão gratuita do Polylang e foram testados e/ou usados aqui.
Copiar o conteúdo da publicação original utilizando o Polylang na sua versão gratuita
Se utiliza a versão gratuita do plugin Polylang para WordPress, já sabe que a nova página ou publicação que gera para tradução não copia o conteúdo original. Esta é uma das caraterísticas da sua versão paga e, na versão gratuita, tem de colar o conteúdo à mão.
Para resolver isto e acelerar o processo, basta adicionar estas funções no ficheiro functions.php do seu modelo. Agora, quando adicionar uma nova tradução, ela será aberta com o conteúdo original copiado (título e conteúdo).
// Copying content when creating a translation with Polylang
function jb_editor_content( $content ) {
// Polylang sets the 'from_post' parameter
if ( isset( $_GET['from_post'] ) ) {
$my_post = get_post( $_GET['from_post'] );
if ( $my_post )
return $my_post->post_content;
}
return $content;
}
add_filter( 'default_content', 'jb_editor_content' );
// Copy title when creating a translation with Polylang
function jb_editor_title( $title ) {
// Polylang sets the 'from_post' parameter
if ( isset( $_GET['from_post'] ) ) {
$my_post = get_post( $_GET['from_post'] );
if ( $my_post )
return $my_post->post_title;
}
return $title;
}
add_filter( 'default_title', 'jb_editor_title' );
*Este trechofoi encontrado numa nota de dezembro de 2020. Embora ainda funcione, não faria mal nenhum ficar de olho nela para o caso de, com o tempo e futuras actualizações do Polylang, falhar.
Mostrar o número total de mensagens traduzidas com a Polylang em cada língua
Esta função permite-lhe adicionar um shortcode para cada língua que mostrará o número total de posts publicados numa língua em que existem traduções adicionadas com o plugin Polylang.
Esta função está mais do que testada e a funcionar corretamente na minha página de estatísticas e é útil para manter uma lista de contadores que são actualizados automaticamente.
O snippet é adicionado ao functions.php do modelo :
// Function to display number of published posts by language for Polylang
function polylang_post_count_by_language($atts) {
// Atributos del shortcode
$atts = shortcode_atts(array(
'lang' => '', // Código de idioma (ej: 'es', 'en', etc.)
), $atts, 'post_count_by_lang');
// Check if Polylang is active
if (!function_exists('pll_languages_list')) {
return 'Polylang plugin is not active.';
}
// Get the language code
$lang = $atts['lang'];
if (empty($lang)) {
return 'Language code is required.';
}
// Single key for transient
$transient_key = 'post_count_by_lang_' . $lang;
// Trying to get the count from the cache
$post_count = get_transient($transient_key);
// If there is no cache, perform the query
if (false === $post_count) {
// Configure the query to count posts by language
$args = array(
'lang' => $lang,
'post_type' => 'post', // Type of post (you can change it if necessary)
'post_status' => 'publish', // Only published posts
'fields' => 'ids', // Only obtain IDs to reduce the burden
'numberposts' => -1, // All posts
);
// Make an enquiry
$query = new WP_Query($args);
// Get the total number of posts
$post_count = $query->found_posts;
// Cache for 12 hours (43200 seconds)
set_transient($transient_key, $post_count, 43200);
}
// Return the number of posts
return $post_count;
}
add_shortcode('post_count_by_lang', 'polylang_post_count_by_language');
Um dos problemas que enfrentamos aqui é que, se tiver muitos posts em muitas línguas diferentes no seu sítio, como é o caso deste blogue, o impacto da consulta da base de dados pode diminuir a velocidade de carregamento. O código tem isso em conta e a consulta é optimizada utilizando WP_Query com campos => 'ids' para reduzir a sobrecarga de memória ao não carregar objectos de posts inteiros.
A contagem de mensagens é armazenada utilizando set_transient e evita consultas repetitivas à base de dados. No exemplo, a cache é actualizada a cada 12 horas, expressas em segundos (pode ajustar este tempo de acordo com as suas necessidades).
Para otimizar a consulta, é utilizado WP_Query em vez de get_posts para aceder a found_posts, que devolve o número total de mensagens sem necessidade de carregar todos os objectos.
O parâmetro fields => 'ids' reduz a carga de memória, recuperando apenas os IDs dos posts.
Se, a dada altura, precisar de limpar a cache manualmente (por exemplo, depois de publicar uma nova publicação) para que não sejam apresentados dados obsoletos, pode utilizá-la:
delete_transient('post_count_by_lang_' . $lang);
Se preferir automatizar este processo, a seguinte função irá eliminar o transiente sempre que um post for publicado, atualizado ou eliminado. Se a adicionar no functions.php do seu modelo, o hook será ativado para todas estas acções:
//Deleting the transient when publishing, updating or deleting a post
function clear_post_count_transient($post_id) {
// Check if the post is of type 'post' (or the type you are counting).
if (get_post_type($post_id) === 'post') {
// Get the language of the post using Polylang
if (function_exists('pll_get_post_language')) {
$lang = pll_get_post_language($post_id);
// If the language is obtained, delete the corresponding transient.
if ($lang) {
delete_transient('post_count_by_lang_' . $lang);
}
}
}
}
add_action('save_post', 'clear_post_count_transient'); // When publishing or updating
add_action('delete_post', 'clear_post_count_transient'); // By deleting
E este limpa a cache automaticamente de acordo com uma série de cenários possíveis(incluindo o acima referido):
// Function to delete the transient when necessary
function clear_post_count_transient($post_id) {
if (get_post_type($post_id) === 'post') {
if (function_exists('pll_get_post_language')) {
$lang = pll_get_post_language($post_id);
if ($lang) {
delete_transient('post_count_by_lang_' . $lang);
}
}
}
}
add_action('save_post', 'clear_post_count_transient');
add_action('delete_post', 'clear_post_count_transient');
//Function to delete transient when changing the language of a post
function clear_post_count_transient_on_language_change($post_id, $lang) {
$old_lang = pll_get_post_language($post_id);
if ($old_lang) {
delete_transient('post_count_by_lang_' . $old_lang);
}
if ($lang) {
delete_transient('post_count_by_lang_' . $lang);
}
}
add_action('pll_save_post', 'clear_post_count_transient_on_language_change', 10, 2);
// Function to delete all transients when uninstalling or deactivating Polylang
function clear_all_post_count_transients() {
if (function_exists('pll_languages_list')) {
$languages = pll_languages_list();
foreach ($languages as $lang) {
delete_transient('post_count_by_lang_' . $lang);
}
}
}
register_deactivation_hook(__FILE__, 'clear_all_post_count_transients');
register_uninstall_hook(__FILE__, 'clear_all_post_count_transients');
Os números são apresentados utilizando o shortcode para cada língua com o código correspondente onde quer que pretenda apresentar o número. Tem o seguinte aspeto:
For Spanish: [post_count_by_lang lang="es"]
For English: [post_count_by_lang lang="en"]
For German: [post_count_by_lang lang="de"]
For French: [post_count_by_lang lang="fr"]
etc.
Pode modificar o'post_type' no código se quiser contar outros tipos de conteúdo (páginas, tipos de post personalizados, etc.).
Neste URL tem um exemplo do funcionamento dos códigos de acesso.
Adicionar banners Polylang nativos a qualquer página ou publicação
Uma vez que o Polylang inclui uma coleção de 249 bandeiras 16x11 em .png, podemos usá-las para decorar listas, adicioná-las a tabelas, parágrafos, etc. sem ter de escrever HTML ou CSS.
Esta função permite-lhe adicionar a imagem de qualquer banner nativo utilizado pelo plugin através de um shortcode.
Para os tornar disponíveis, adicione o snippet no functions.php do seu tema filho, num plugin personalizado ou com o Code Snippet, se o utilizar.
function polylang_flag_shortcode($atts) {
// Shortcode attributes
$atts = shortcode_atts(array(
'code' => '', // Flag code (e.g. 'es', 'en', 'fr')
'size' => '16', // Flag size (width in pixels)
), $atts, 'polylang_flag');
// Check if a flag code was provided
if (empty($atts['code'])) {
return 'Flag code not provided.';
}
// Polylang flag base route
$flag_path = plugins_url('polylang/flags/' . $atts['code'] . '.png');
// Create the HTML of the flag image
$flag_html = '<img src="' . esc_url($flag_path) . '" alt="' . esc_attr($atts['code']) . '" width="' . esc_attr($atts['size']) . '" height="auto" />';
return $flag_html;
}
add_shortcode('polylang_flag', 'polylang_flag_shortcode');
Depois de adicionar o código, pode utilizar o shortcode com o código do país correspondente em qualquer página ou publicação do WordPress , certificando-se de que corresponde exatamente aos nomes dos ficheiros das bandeiras na pasta /wp-content/plugins/polylang/flags/.
[polylang_flag code="en" size="32"]
[polylang_flag code="fr" size="24"]
//Original size
[polylang_flag code="de"]
Para brincar com o tamanho das bandeiras, basta alterar o valor do atributo size no shortcode.
Se quiser criar e utilizar os seus próprios banners ou ter outra coleção com um design diferente, basta alojar os novos banners (em .png) numa nova pasta com um nome diferente (caso contrário, perderá as alterações quando o plugin for atualizado) e adicionar o novo caminho ao código. Por exemplo:
$flag_path = plugins_url('polylang/nuevas_banderas/' . $atts['code'] . '.png');
Adicionar um ícone SVG junto ao seletor de idioma
Este excerto acrescenta um ícone SVG com o símbolo "Translate" à esquerda do seletor da língua materna do Polylang para o tornar visualmente mais apelativo e chamar a atenção do visitante. No exemplo, o ícone é o que utilizo neste blogue. Pode procurar o que mais lhe agrada e substituí-lo. Aqui estão alguns deles.
function polylang_add_translate_icon($output) {
//SVG icon for "translate".
$translate_icon = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 5px;"><path d="M24 24h-2.784l-1.07-3h-4.875l-1.077 3h-2.697l4.941-13h2.604l4.958 13zm-4.573-5.069l-1.705-4.903-1.712 4.903h3.417zm-9.252-12.804c.126-.486.201-.852.271-1.212l-2.199-.428c-.036.185-.102.533-.22 1-.742-.109-1.532-.122-2.332-.041.019-.537.052-1.063.098-1.569h2.456v-2.083h-2.161c.106-.531.198-.849.288-1.149l-2.147-.645c-.158.526-.29 1.042-.422 1.794h-2.451v2.083h2.184c-.058.673-.093 1.371-.103 2.077-2.413.886-3.437 2.575-3.437 4.107 0 1.809 1.427 3.399 3.684 3.194 2.802-.255 4.673-2.371 5.77-4.974 1.134.654 1.608 1.753 1.181 2.771-.396.941-1.561 1.838-3.785 1.792v2.242c2.469.038 4.898-.899 5.85-3.166.93-2.214-.132-4.635-2.525-5.793zm-2.892 1.531c-.349.774-.809 1.544-1.395 2.15-.09-.646-.151-1.353-.184-2.108.533-.07 1.072-.083 1.579-.042zm-3.788.724c.062.947.169 1.818.317 2.596-1.996.365-2.076-1.603-.317-2.596zm11.236-1.745l-2.075-5.533 5.414-1.104-.976 1.868c2.999 2.418 4.116 5.645 4.532 8.132-1.736-2.913-3.826-4.478-5.885-5.321l-1.01 1.958zm-7.895 10.781l1.985 5.566-5.43 1.016 1.006-1.852c-2.96-2.465-4.021-5.654-4.397-8.148 1.689 2.94 3.749 4.483 5.794 5.36l1.042-1.942zm10.795-6.029"/></svg>';
// Add the icon before the selector
return $translate_icon . '<span style="margin-left: 5px;">' . $output . '</span>';
}
add_filter('pll_the_languages', 'polylang_add_translate_icon');
Mostrar um aviso personalizável da existência de uma versão em língua estrangeira
Esta função cria um shortcode para apresentar um aviso com um fundo amarelo que pode ser adicionado em qualquer parte de uma publicação ou página. Esta mensagem avisa que o artigo tem uma tradução em inglês com Polylang e fornece uma hiperligação para a versão em inglês.
Escolhi este exemplo porque já o utilizei quando um artigo, em qualquer língua, recebeu mais tráfego de países anglófonos e de navegadores de língua inglesa (o que também não garante que a pessoa que estava atrás dele estivesse a procurar a versão inglesa). Ainda assim, é uma forma de garantir a retenção de visitantes em alguns casos.
Código a adicionar a functions.php
// English version notice
function polylang_translation_notice_shortcode() {
// Verifica si el plugin Polylang está activo
if (!function_exists('pll_the_languages')) {
return '';
}
// Get the ID of the current post
$post_id = get_the_ID();
// Get the English translation of the current post
$english_post_id = pll_get_post($post_id, 'en'); // 'en' es el código del idioma inglés
// Si no hay una traducción en inglés, no mostrará nada
if (!$english_post_id) {
return '';
}
// Get the link to the English version
$english_post_url = get_permalink($english_post_id);
// Crear el contenido del aviso
$ticker_content = sprintf(
'<div style="background-color: #ffffcc; padding: 10px; border-radius: 5px; margin-bottom: 20px; font-size: 14px;">
This article has an English version. <a href="%s" style="color: #0073e6; text-decoration: none; font-weight: bold;">Read</a>
</div>',
esc_url($english_post_url)
);
return $ticker_content;
}
add_shortcode('polylang_translation_notice', 'polylang_translation_notice_shortcode');
No estilo, pode modificar a mensagem, o tamanho do texto, as cores do texto, o fundo e a ligação a seu gosto.
Para adicionar a mensagem onde quiser, basta utilizar este código curto:
[polylang_translation_notice]
Com o CSS do exemplo, fica com o seguinte aspeto.

Se quiser adicionar um aviso à tradução noutra língua, basta alterar o código da língua em pll_get_post($post_id, 'en'); para 'fr', 'de', 'it', etc. Se precisar de utilizar vários posts, pode adicionar diferentes snippets, um para cada língua. Podia adicioná-los todos num único snippet, mas eu só precisava de um.