GNU/Linux, Open Source, Cloud Computing, DevOps y más...

Solucionando problemas de Qtranslate con la traducción del slug

1 comentario

A la hora de crear un sitio web multi-idioma basado en WordPress son básicamente dos las opciones que tenemos. Una implica crear páginas y artículos distintos, cada uno en su idioma, usando plugins del tipo de WPML, Polylang o xili-language. Otra introduce el contenido traducido en todos los idiomas que manejemos en el mismo post, separado por unas meta-etiquetas dentro del propio contenido, y es el propio plugin el que los separa en pestañas distintas dentro del editor de un único post existente.

Nota:

Los problemas y las soluciones descritas en este artículo son aplicables a estas versiones de los plugins:

  • Qtranslate 2.5.39
  • Qtranslate Slug 1.1.7

Este es el caso de Qtranslate, que resulta ser la solución más sencilla desde mi punto de vista, pues no es necesario modificar la base de datos de WordPress para crear relaciones entre un artículo y sus traducciones, al igual que para el resto de objetos de WordPress: etiquetas, categorías, widgets, menús, etc. Por eso Qtranslate es mi opción preferida a la hora de crear un sitio web multi-idioma en WordPress.

Sin embargo, Qtranslate no está exento de complicaciones, pues tiene algunos fallos que es necesario solventar para que nuestro sitio sea realmente multi-idioma:

1. Qtranslate no ofrece soporte para traducción de URL’s y slugs

El principal impedimento que encontramos es que Qtranslate no ofrece soporte para la traducción de las URL’s de nuestro sitio, lo cual supone una gran limitación que puede invalidar completamente su uso y forzarnos a optar por otra alternativa. Afortunadamente existe un plugin complementario que nos permitirá traducir nuestras URL’s: Qtranslate Slug. Soporta la traducción no sólo de los slugs de nuestros artículos y páginas, sino también de etiquetas y categorías.

Qtranslate Slug

2. Qtranslate Slug provoca que se genere contenido duplicado en nuestro sitio

Sin embargo, Qtranslate no resuelve otro incómodo problema: aunque nuestras URL’s sean traducidas correctamente con Qtranslate Slug, cuando solicitemos cualquier artículo, página o categoría empleando el slug en el idioma por defecto de nuestro sitio, da igual qué variable o subdirectorio de idioma indiquemos en nuestra URL, pues se mostrará el mismo contenido siempre. Así, siendo el idioma por defecto de nuestro sitio el inglés, si solicitamos la URL /en/article-name obtendremos exactamente el mismo resultado que si solicitamos /es/article-name, lo cual es erróneo, pues la dirección del artículo en español es /es/nombre-articulo. La dirección /es/article-name no tiene sentido y debería devolver un error 404: no encontrado. Sin embargo se nos muestra el artículo en inglés, con exactamente el mismo contenido que en el caso de /en/article-name, lo cual es contenido duplicado que Google y otros buscadores pueden llegar a indexar o al menos marcar como contenido duplicado y crearnos problemas.

Esto mismo ocurre con páginas, categorías y etiquetas. Por ejemplo, la dirección /es/category/programming mostrará el mismo contenido que /en/category/programming.

Para solventar esto y mostrar errores 404 de página no encontrada cuando solicitamos URL’s incorrectas debemos hacer algunas modificaciones en el fichero wp-content/plugins/qtranslate-slug/qtranslate-slug.php del plugin Qtranslate Slug.

882                         // <DLA>
883                         if (!$post)
884                         {
885                                 $query['name'] = 'dladladladla';
886                                 return $query;
887                         }
888                         // </DLA>

...

900                         // <DLA>
901                         if (!$term)
902                         {
903                                 $query['category_name'] = 'dladladladla';
904                                 return $query;
905                         }
906                         // </DLA>

...

1068                     /*} else {
1069                         $last_part = array_pop($parts);
1070                         $page_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_name = '$last_part' AND (post_type = '$post_type_sql' OR post_type = 'attachment')" );
1071 
1072                         if ( $page_id )
1073                                 return $page_id;
1074                     }*/

...

1560                 /*if ( !$term && 'slug' == $original_field ) {
1561                         $field = 't.slug';
1562                         $term = $wpdb->get_row( $wpdb->prepare( "SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = %s AND $field = %     s LIMIT 1", $taxonomy, $value) );
1563                 }*/

3. La paginación no funciona correctamente

Cuando nos encontramos en una página interna del blog, de una categoría o de posts archivados y seleccionamos otro idioma desde el widget de cambio de idioma la información de paginación se pierde y siempre nos lleva a la página principal, con lo cual nunca podemos ver la versión de dicha página en los otros idiomas disponibles de nuestro sitio web. Es decir, si accedemos a /es/blog/page/2 y cambiamos el idioma a inglés, en lugar de mostrarse la página /en/blog/page/2 se muestra /en/blog.

Yo lo he solucionado añadiendo las siguientes líneas al final de la función filter_request() del fichero qtranslate-slug.php, aunque probablemente haya una forma mejor si buceamos más en el código de Qtranslate Slug:

 972                 // <DLA>
 973                 // Add support for pagination to qtranslate slug widget
 974                 if (isset($query['paged']))
 975                 {
 976                         if ($this->current_url == null)
 977                         {
 978                                 global $q_config;
 979                                 foreach ($q_config['enabled_languages'] as $lang)
 980                                 {
 981                                         $this->current_url[$lang] = '/'.$lang . str_replace('/'.qtrans_getLanguage().'/', '/'.$lang.'/', $_SERVER['REQUEST_URI']);
 982                                 }
 983                         }
 984                         else
 985                         {
 986                                 foreach ($this->current_url as $lang => $language_url)
 987                                 {
 988                                         $this->current_url[$lang] .= 'page/'.$query['paged'];
 989                                 }
 990                         }
 991                 }
 992                 // </DLA>

4. Qtranslate genera enlaces hreflang erróneos

Otro efecto colateral indeseable que sufriremos por no ofrecer Qtranslate soporte para traducir el slug de las URL’s es el de que se creen enlaces hreflang erróneos en la sección HEAD de todas nuestras páginas. Así, la URL de este mismo post aparecería como /en/solucionando-problemas-qtranslate-slug/ en lugar de /es/solucionando-problemas-qtranslate-slug/ en la versión en español, mientras que en la versión en inglés aparecería como /es/fixing-qtranslate-slug-problems/ en lugar de /en/fixing-qtranslate-slug-problems/, lo que resulta en un montón de errores 404 de página no encontrada en las Webmaster Tools de Google.

Podemos solucionar esto realizando una pequeña modificación en el fichero wp-content/plugins/qtranslate/qtranslate_hooks.php:

Antes:
 41         foreach($q_config['enabled_languages'] as $language) {
 42                 if($language != qtrans_getLanguage())
 43                         echo '<link hreflang="'.$language.'" href="'.qtrans_convertURL('',$language).'" rel="alternate" />'."\n";
 44         }        
Después:
 41         foreach($q_config['enabled_languages'] as $language) {
 42                 if($language != qtrans_getLanguage())
 43                 // <DLA>
 44                 {       
 45                         global $qtranslate_slug;
 46                         $language_url = $qtranslate_slug->get_current_url($language);
 47                         //echo '<link hreflang="'.$language.'" href="'.qtrans_convertURL('',$language).'" rel="alternate" />'."\n";
 48                         echo '<link hreflang="'.$language.'" href="'.$language_url.'" rel="alternate" />'."\n";
 49                 }
 50                 // </DLA>
 51         }

5. Comments reply links doesn’t include language

Todos los comentarios de un post incluyen normalmente un enlace “Responder” que no es filtrado por Qtranslate para añadir la variable o subdirectorio de idioma a la URL que aparece en el atributo href de dicho enlace. Esto provoca que enlaces que deberían ser como /es/solucionando-problemas-de-qtranslate-con-la-traduccion-del-slug/?replytocom=1868#respond aparezcan como /solucionando-problemas-de-qtranslate-con-la-traduccion-del-slug/?replytocom=1868#respond, lo que provoca también más errores 404 en las Herramientas para Webmasters de Google.

Podemos solucionarlo añadiendo estas líneas al fichero qtranslate-slug.php:

 533                 // <DLA>
 534                 add_filter( 'comment_reply_link', array(&$this, 'fix_comment_reply_link'));
 535                 add_filter( 'cancel_comment_reply_link', array(&$this, 'fix_cancel_comment_reply_link'));
 536                 // </DLA>
 537 
 538         }
 539 
 540         // <DLA>
 541         /*
 542          * fixes comments reply link adding language subdirectory to href URL
 543          */
 544         function fix_comment_reply_link($link)
 545         {
 546                 preg_match('/href=\'([^\']*)\'/', $link, $href);
 547 
 548                 return str_replace($href[1], qtrans_convertURL($href[1]), $link);
 549         }
 550         /*
 551          * Fixes cancel comment reply link by adding language subdirectory to href URL
 552          */
 553         function fix_cancel_comment_reply_link($link)
 554         {
 555                 preg_match('/href=\"([^\']*)\"/', $link, $href);
 556 
 557                 return str_replace($href[1], qtrans_convertURL($href[1]), $link);
 558         }
 559         // </DLA>

6. Google XML Sitemaps v3 for Qtranslate no funciona con Qtranslate Slug

Este problema hace que se generen URL’s incorrectas en nuestro mapa del sitio, las cuales provocarán que se genere un sitemap plagado de URL’s que devuelven un error 404 de página no encontrada. En este otro artículo describo mejor la problemática y su resolución: Google XML Sitemaps v3 for Qtranslate no funciona con Qtranslate Slug.

 

Sobre el autor

Daniel López Azaña
Arquitecto de soluciones Cloud

Emprendedor, generador de ideas y mente inquieta. Apasionado de las nuevas tecnologías, especialmente de los sistemas Linux y del software libre. Me gusta escribir además sobre actualidad tecnológica, Cloud Computing, DevOps, seguridad, desarrollo web y programación, SEO, ciencia, innovación, emprendimiento, etc.

DanielSolucionando problemas de Qtranslate con la traducción del slug

Artículos relacionados

1 comentario

Unirte a la conversación
  • sara - 27/12/2016 responder

    Buenas,
    Esto ya no funciona así, verdad?
    Tengo el problema nº4 y estoy usando las versiones:
    QTranslate Slug 1.1.18
    QTranslate X 3.4.6.8
    He colocado el código que indicas en q-translate-hooks.php pero me devuelve error 500.
    ¿Alguien sabe cómo solucionarlo?

    Muchas gracias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *