Cinco snippets útiles para Polylang

Publicado: 05/02/2025 : 18:29 | Actualizado: 05/02/2025 : 18:54 |

Sin comentarios

 

Cinco snippets útiles para Polylang 0
Captura del 5 de febrero de 2025

Aunque hay distintas opiniones sobre cuál es el mejor plugin para crear un blog multilingüe, y todos han evolucionado mucho desde sus primeras versiones simplificando y facilitando bastante la tarea, uno de los más usados es Polylang.

Con más de 700.000 instalaciones activas a día de hoy sigue siendo una de las opciones más ligeras y efectivas.

Aquí dejo una pequeña lista de snippets con funciones y filtros que podrían ser de utilidad en algún momento. Todas ellas funcionan para la versión gratis de Polylang y han sido probadas y/o usadas aquí.

Copiar contenido del post original usando Polylang en su versión gratis

Si utilizas la versión gratuita del plugin Polylang para WordPress, ya sabes que la nueva página o post que genera para su traducción no copia el contenido original. Esta es una de las características de su versión de pago y en la gratis hay que pegar el contenido a mano.

Para solucionar esto y agilizar el proceso, bastará añadir estas funciones en el archivo functions.php de tu plantilla. Ahora, al añadir una nueva traducción se abrirá con el contenido original copiado (título y contenido).

// Copiar contenido al crear una traducción con 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' );
// Copiar título al crear una traducción con 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 snippet lo encontré en una nota de diciembre de 2020. Aunque sigue funcionando no estaría de más estar atento por si, con el tiempo y futuras actualizaciones de Polylang, fallara.

Mostrar la cifra total de post traducidos con Polylang en cada idioma

Esta función te permite añadir un shortcode para cada idioma que mostrará la cifra total de los post publicados en un idioma en el que existan traducciones añadidas con el plugin Polylang.

Esta función está más que probada y funcionando correctamente en mi página de estadísticas y es útil para mantener una lista con contadores que se actualicen automáticamente.

Se añade el snippet en el functions.php de la plantilla:

// Función para mostrar cifra de post publicados por idioma para 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');

    // Verificar si Polylang está activo
    if (!function_exists('pll_languages_list')) {
        return 'Polylang plugin is not active.';
    }

    // Obtener el código de idioma
    $lang = $atts['lang'];
    if (empty($lang)) {
        return 'Language code is required.';
    }

    // Clave única para el transient
    $transient_key = 'post_count_by_lang_' . $lang;

    // Intentar obtener el conteo desde el caché
    $post_count = get_transient($transient_key);

    // Si no hay caché, realizar la consulta
    if (false === $post_count) {
        // Configurar la consulta para contar posts por idioma
        $args = array(
            'lang'        => $lang,
            'post_type'   => 'post', // Tipo de post (puedes cambiarlo si es necesario)
            'post_status' => 'publish', // Solo posts publicados
            'fields'      => 'ids', // Solo obtener IDs para reducir la carga
            'numberposts' => -1, // Todos los posts
        );

        // Realizar la consulta
        $query = new WP_Query($args);

        // Obtener el número total de posts
        $post_count = $query->found_posts;

        // Almacenar en caché por 12 horas (43200 segundos)
        set_transient($transient_key, $post_count, 43200);
    }

    // Devolver la cantidad de posts
    return $post_count;
}
add_shortcode('post_count_by_lang', 'polylang_post_count_by_language');

Uno de los problemas a los que nos enfrentamos aquí es que, si en tu página tienes muchos post de muchos idiomas diferentes, como es el caso de este blog, el impacto de la consulta a la base de datos podría lastrar la velocidad de carga. En el código se tiene en cuenta esto y la consulta se optimiza usando WP_Query con fields => 'ids' para reducir la sobrecarga de memoria al no cargar objetos completos de posts.

El conteo de post se almacena usando set_transient y se evita que se hagan consultas repetitivas a la base de datos. En el ejemplo, la caché se actualiza cada 12 horas, expresado en segundos (puedes ajustar este tiempo según tus necesidades).

Para optimizar la consulta se usa WP_Query en lugar de get_posts para acceder a found_posts, lo que devuelve el número total de posts sin necesidad de cargar todos los objetos.

El parámetro fields => 'ids' reduce la carga de memoria al recuperar solo los IDs de los posts.

Si en algún momento necesitas borrar el caché manualmente (por ejemplo, después de publicar un nuevo post) para que no muestre datos obsoletos puedes usar:

delete_transient('post_count_by_lang_' . $lang);

Si prefieres automatizar este proceso, con la siguiente función se borrará el transient cada vez que se publique, actualice o elimine un post. Si la añades en el functions.php de tu plantilla, el hook se activará en todas estas acciones:

//Borrar el transient al publicar, actualizar o eliminar un post
function clear_post_count_transient($post_id) {
    // Verificar si el post es del tipo 'post' (o el tipo que estás contando)
    if (get_post_type($post_id) === 'post') {
        // Obtener el idioma del post usando Polylang
        if (function_exists('pll_get_post_language')) {
            $lang = pll_get_post_language($post_id);
            
            // Si se obtiene el idioma, borrar el transient correspondiente
            if ($lang) {
                delete_transient('post_count_by_lang_' . $lang);
            }
        }
    }
}
add_action('save_post', 'clear_post_count_transient'); // Al publicar o actualizar
add_action('delete_post', 'clear_post_count_transient'); // Al eliminar

Y con esta otra se borra el caché automáticamente según una serie de distintos escenarios posibles, (incluyendo el anterior):

// Función para borrar el transient cuando sea necesario
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');

// Función para borrar el transient al cambiar el idioma de un 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);

// Función para borrar todos los transients al desinstalar o desactivar 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');

Las cifras se muestran usando el shortcode para cada idioma con su código correspondiente allá donde quieras mostrar la cifra. Tal que así:

Para español: [post_count_by_lang lang="es"]
Para inglés: [post_count_by_lang lang="en"]
Para alemán: [post_count_by_lang lang="de"]
Para francés: [post_count_by_lang lang="fr"]
etc.
Puedes modificar el 'post_type' en el código si deseas contar otro tipo de contenido (páginas, custom post types, etc.)

En esta URL tienes un ejemplo de los shortcodes funcionando.

Añadir las banderas nativas de Polylang en cualquier página o post

Ya que Polylang incluye una colección de 249 banderas de 16x11 en .png, podemos aprovecharlas para adornar listas, añadirlas a tablas, párrafos, etc. sin necesidad de escribir HTML o CSS.

Esta función permite añadir la imagen de cualquier bandera nativa que usa el plugin mediante un shortcode.

Para poder disponer de ellas se añade el snippet en el functions.php de tu tema hijo, en un plugin personalizado o con Code Snippet, si lo usas.

function polylang_flag_shortcode($atts) {
    // Atributos del shortcode
    $atts = shortcode_atts(array(
        'code' => '', // Código de la bandera (ej: 'es', 'en', 'fr')
        'size' => '16', // Tamaño de la bandera (ancho en píxeles)
    ), $atts, 'polylang_flag');

    // Verificar si se proporcionó un código de bandera
    if (empty($atts['code'])) {
        return 'Código de bandera no proporcionado.';
    }

    // Ruta base de las banderas de Polylang
    $flag_path = plugins_url('polylang/flags/' . $atts['code'] . '.png');

    // Crear el HTML de la imagen de la bandera
    $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');

Una vez añadido el código ya puedes usar el shortcode con su correspondiente código de país en cualquier página o entrada de WordPress asegurándote de que coincida exactamente con los nombres de los archivos de las banderas que están en la carpeta  /wp-content/plugins/polylang/flags/

[polylang_flag code="en" size="32"]
[polylang_flag code="fr" size="24"]

//Tamaño original
[polylang_flag code="de"]

Para jugar con el tamaño de las banderas, simplemente cambia el valor del atributo size en el shortcode.

Si quieres crear y usar tus propias banderas o tener otra colección con otro diseño, bastará con que alojes las nuevas (en .png) en una nueva carpeta con un nombre diferente (si no perderás los cambios cuando se actualice el plugin) y añadas la nueva ruta al código. Como por ejemplo:

$flag_path = plugins_url('polylang/nuevas_banderas/' . $atts['code'] . '.png');

Añadir un icono SVG junto al selector de idiomas

Este snippet añade un icono SVG con el símbolo de "Traducir" a la izquierda del selector nativo de idiomas de Polylang para que sea algo más atractivo visualmente y llame más la atención del visitante. En el ejemplo, el icono es el que uso en este blog. Puedes buscar el que más te guste y sustituirlo. Aquí tienes unos cuantos.

function polylang_add_translate_icon($output) {
    // Icono SVG de "traducir"
    $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>';

    // Añadir el icono antes del selector
    return $translate_icon . '<span style="margin-left: 5px;">' . $output . '</span>';
}
add_filter('pll_the_languages', 'polylang_add_translate_icon');


Mostrar aviso personalizable de la existencia de una versión en otro idioma

Con esta función se crea un shortcode para mostrar un aviso con fondo amarillo que se puede añadir en cualquier lugar de un post o página. Este mensaje avisa de que el artículo tiene una traducción en inglés con Polylang y proporciona un enlace a la versión en inglés.

He elegido este ejemplo porque yo lo he usado cuando un artículo, en cualquier idioma, recibía más tráfico de países donde se habla inglés y desde navegadores con idioma en inglés (lo que tampoco garantiza que la persona que esté detrás haya llegado buscando la versión inglesa). Aún así, es una forma de asegurarte la retención de la visita en algunos casos.

Código para añadir al functions.php

  // Aviso de versión en inglés
function polylang_translation_notice_shortcode() {
    // Verifica si el plugin Polylang está activo
    if (!function_exists('pll_the_languages')) {
        return '';
    }

    // Obtener el ID del post actual
    $post_id = get_the_ID();

    // Obtiene la traducción en inglés del post actual
    $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 '';
    }

    // Obtiene el enlace a la versión en inglés
    $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');

En style puedes modificar a tu gusto el mensaje, el tamaño del texto, los colores del texto, del fondo y del enlace.

Para añadir el mensaje donde quieras solo hay que usar este shortcode:

[polylang_translation_notice]

Con el CSS del ejemplo tiene este aspecto.

Ejemplo del aspecto del aviso, texto negro de 14px sobre fondo amarillo claro y enlace en azul.

Si quieres añadir un aviso a la traducción en otro idioma solo tendrás que cambiar el código del idioma en pll_get_post($post_id, 'en'); por 'fr', 'de', 'it', etc. Si necesitas usar varios mensajes, puedes añadir distintos snippets, uno para cada idioma. Se podrían añadir todos en un mismo snippet, pero yo sólo necesité uno.


Suscríbete por email para recibir las viñetas y los artículos completos y sin publicidad

Artículos relacionados



Repositorio de documentales sobre dibujantes de cómic y humor gráfico.

Tontolares. Los titulares más gilipollas de la prensa. Envía los tuyos

Deja un comentario

Tu WordPress puede volar

Servicio de optimización

Suscripción por e-mail

Recibe gratis los artículos completos en tu correo sin publicidad en el momento que se publiquen. Se envía el contenido íntegro del feed sin anuncios a través de un servicio externo.