Module "page title" et traduction

  • warning: array_map(): Argument #2 should be an array in /var/www/titouille.ch/www/modules/system/system.module on line 1050.
  • warning: array_keys() expects parameter 1 to be array, null given in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
  • warning: Invalid argument supplied for foreach() in /var/www/titouille.ch/www/includes/theme.inc on line 1845.
Portrait de titouille

Longtemps que je n'ai pas écrit, mais je ne résistais à l'envie de partager cette petite astuce.

Posons les bases : dans l'optique d'avoir un site en Drupal 7 multilingue, j'aimerai que les titres de page (utilisés dans la balise body->head->title) soient traduisibles, c'est mieux pour le SEO. Ayant installé le module page_title ainsi que divers modules d'internationalisation, j'ai fait quelques tests sans grand succès... Je ne peux malheureusement pas utiliser la puissance de page_title avec les token (jetons de remplacement). La seule solution serait de le faire au cas par cas (donc pour chaque noeud dans sa configuration page-title), ce qui est plutôt moyen, comme procédure.

Illustrons de manière plus cohérente le truc : en allant sur /admin/config/search/page-title, j'ai la possibilité de créer des automatisations pour les titres de page. Admettons que j'ai un type de contenu "billet de blog" sur lequel j'aimerai appliquer le modèle suivant :

[titre du billet de blog] sur le blog [nom du site]

Si j'applique ça à mon blog, ça donnerai quelque chose du genre :

Module "page title" et traduction sur le blog life laboratory

Pour ce faire, je vais utiliser les jetons suivants :

[current-page:page-title] sur le blog [site:name]

Je valide et je teste. Cool, j'ai bien le titre qui suit mon modèle. Mon problème, c'est que si je traduis mon billet de blog en anglais, j'aurais donc :

"Page title" module and translation sur le blog life laboratory

Et là, comme vous pouvez le constater, ça en jette tout de suite moins...

Je me suis alors posé la question... Je sais qu'il existe un module "variable" qui permet de modifier les variables stockées dans la table "variable" (ça en fait des variables)... Il existe également un module "i18n_variable" qui permet de rendre ces variables traduisibles. Un petit coup de baguette magique et on devrai pouvoir mettre tout ça à profit, non ?

J'ai donc installé les modules variable et i18n_variable, puis je suis allé faire un tour dans la configuration de ces 2 modules :

variable : /admin/config/system/variable/
i18n_variable : /admin/config/regional/i18n/variable

Malheureusement, point de page_title à l'horizon... Donc nativement, ce n'est pas possible de pouvoir rendre ma chaine de caractère incluant des tokens traduisible. Qu'à cela ne tienne, c'est pas ce genre de chose qui m'arrête.

Ce qu'il y a de bien avec Drupal, c'est que les modules les plus intéressants proposent souvent des hooks afin de pouvoir "surdéfinir" des comportements standard. Et c'est justement le cas du module "variable", qui permet d'implémenter ses propres fonctions de surdéfinition, afin d'ajouter de nouvelles variables qui pourront devenir traduisibles avec "i18n_variable".

Pour ce faire, j'ai utilisé 2 hooks : hook_variable_info et hook_variable_group_info. La première permet de définir de nouvelles variables (stockées dans la table variable bien entendu) qui doivent être soumises au système de variables. La seconde permet simplement de créer un nouveau groupe pour y organiser mes variables. Après avoir créé un petit module custom, j'ai implémenté les fonctions de la manière suivante :

/**
 * Implements hook_variable_info().
 */
function mymodule_variable_info($options) {
 
  $variable = array();
 
  $types = node_type_get_types();
  foreach( $types as $type ) {
    $variable['page_title_type_' . $type->type] = array(
      'type' => 'string',
      'title' => t('Page title for @type', array('@type' => $type->type), $options),
      'description' => t('Page title that will be used for @type', array( '@type' => $type->name ) ),
      'default' => '',
      'group' => 'page_title',
    );
  }
 
  return $variable;
}
 
/**
 * Implements hook_variable_group_info
 */
function mymodule_variable_group_info() {
  $groups['page_title'] = array(
    'title' => t('Page title'), 
    'description' => t('Page title settings'), 
    'access' => 'administer page titles', 
    'path' => array('admin/config/search/page-title'),
  );
  return $groups;
}

Comme vous pouvez le voir, hook_variable_info itère sur tous les types de contenus disponible du système et inclut pour chacun une nouvelle entrée dans le tableau $variable. Cette entrée est relativement simple, elle défini le nom de la variable :
$variable['page_title_type_' . $type->type]
qui doit bien entendu correspondre au nom de la variable utilisée par page_title, ainsi que quelques informations et le groupe dans lequel la variable sera stockée.

hook_variable_group_info, quand à lui, permet simplement de définir le groupe "page title" dans lequel on va retrouver nos variables déclarées dans hook_variable_info.

Après un vidage de cache, je revisite /admin/config/regional/i18n/variable. Cette fois, je peux voir un nouveau groupe nommé "Page title" qui contient un listing de tous mes types de contenus disponibles. Je coche ceux qui doivent être traduisibles, et je visite maintenant /admin/config/system/variable.

C'est ici que ça se complique un peu. J'ai plusieurs possibilités... En haut à droite, il y a 3 sous-menus : Groups, Modules et Realms.

Par défaut, j'arrive sur "Groups". Je vois bien mon nouveau groupe "Page title" qui contient ma configuration par défaut (établie via le module page-title). Je peux cliquer sur un type de contenu et tenter de l'éditer dans les différentes langues, mais rien ne change lors de la sauvegarde. Ce n'est donc pas le bon endroit pour faire ma modification.

Si je vais sur "Modules" (toujours en haut à droite), cette fois-ci je ne vois pas le groupe "Page title" mais un groupe du nom de mon module. Je peux également tenter d'éditer les variables mais encore une fois, rien n'y fait...

Espérons que cette fois c'est la bonne... Je clique sur "Realms" en haut à droite, ce qui m'affiche un listing avec 2 entrées : Global et Language. C'est language qui nous intéresse. Si je cliques sur "configure" dans les options, je vais à nouveau voir les groupes, dont "Page title", et je vais voir que les types de contenus que j'avais cochés dans la configuration de i18n_variable sont également cochés ici. Je reviens en arrière et cette fois je clique sur l'option "edit".

Sur ce formulaire, seul les variables "activées" sont disponibles. Je vois le groupe "Page title" qui me propose "Page title for Blog entry". Je clique sur la langue anglaise au sommet, je mets le modèle qui m'intéresse, à savoir :

[current-page:page-title] on [site:name]'s Blog

Et je sauvegarde. Je passe ensuite en langue française et je fais pareil, en mettant cette fois le modèle en français :

[current-page:page-title] sur le blog [site:name]

Je valide, je repasse en anglais... Le modèle anglais est bien correct. A priori, tout s'est bien passé. Je n'ai plus qu'à tester les 2 versions de mon billet de blog, et j'ai bien le modèle français qui s'applique sur la version française du billet, le modèle anglais qui s'applique sur la version anglaise du billet.

Yeah !! Encore une victoire de canard !