Traduire les champs des rubriques par local_xx.php3 ou Trad-Lang

Navigation multilingue

Une structure de rubriques unique

A l’heure actuelle, les fonctionnalités d’internationalisation dans SPIP ne concernent que les squelettes, par l’intermédiaire des balises <:toto:>.

Les champs de saisie de contenu dans la partie admin, en revanche, sont statiques d’un point de vue linguistique. Ce qui fait qu’aujourd’hui, la règle de base pour créer un site multilingue, qui est reprise partout dans la doc sur le multilinguisme (voir ici et ici pour un tour d’horizon), est qu’il faut créer un secteur par langue, et répliquer la structure de son site autant de fois qu’il y a de langues.

Autant cela peut être utile et pertinent pour des sites multilingues avec des différences significatives de structure entre les langues, autant dans la plupart des cas il s’agit d’une contrainte assez lourde.

On peut souhaiter une structure unique de site, peuplée d’articles de différentes langues, dont on gère l’affichage simplement grâce, justement, à la facilité avec laquelle SPIP permet de gérer tout ça. Mais SPIP n’offre pas la possibilité de traduire les noms de rubriques (comme il le permet pour les articles), ce qui est gênant notamment dans la mesure où beaucoup de sites génèrent leurs menus de navigation à partir des noms des rubriques.

Une des solutions consiste à utiliser les champs <MULTI>[fr]...[xx]...</MULTI>, comme certains le suggèrent. Cependant, c’est ingérable, d’un point de vue usabilité, au-delà de deux langues. Et même là, je trouve ça peu efficace. Si par ailleurs on utilise les champs sur-titre, sous-titre, texte, etc., des rubriques, ça devient vraiment difficile.

Utiliser l’internationalisation de SPIP

Il faut donc pouvoir utiliser les mêmes fichiers permettant d’internationaliser les squelettes grâce aux balises <:toto:>, de façon à ce qu’ils soient accessibles au sein du contenu. Ces fichiers sont les fichiers local_xx.php3, où xx correspond au code de la langue. Il faut les créer, si on en a besoin, dans le répertoire du squelette (à partir de 1.8 seulement - pour les versions antérieures, c’est dans ecrire/lang/perso_xx.php3). Voir ici pour de plus amples infos sur cette fonctionnalité. Ceci permet d’utiliser Trad-Lang pour traduire facilement tous les titres de rubriques dans le même mouvement que tout le reste des chaînes du site. Trad-Lang est un super outil facilitant la traduction sous forme de tableaux de chaînes, et qui met à jour les fameux fichiers *_xx.php3. Cela évite aux rédacteurs/traducteurs d’accéder directement aux fichiers. Voir ici ce qu’en dit la communauté des traducteurs de Spip.

Bref, pour rendre cela possible, on utilise la fonction apres_typo() pour insérer la traduction dans le contenu du champ qui va s’afficher. Il faut s’arranger pour créer l’expression _T('public/spip/ecrire:toto') à ce moment là.

Une balise spéciale : [:toto:]

On pourra donc utiliser les champs des rubriques pour y mettre les balises. Il suffira de donner comme titre aux rubriques à traduire la balise de traduction que l’on souhaite, mais en utilisant des ’[’ plutôt que des ’<’, sinon ça met le menu rollover de l’espace privé en vrac.

Par exemple, donc, [:toto:]. De fait, ce type de balise pourra s’insérer n’importe où dans n’importe quel champ et sera remplacée par la valeur correspondante de local_xx.php3. Ceci permet également l’utilisation de raccourcis texte ou de terminologie standard au sein du contenu, par exemple.

En plus, on garde le bénéfice des autres filtres de formatage. C’est bien fait SPIP, quand même. En revanche, noter que le classement alphabétique ne se fera plus correctement pour les rubriques ainsi traduites, forcément.

Deux fonctions : avant_typo() et apres_typo()

Voici donc les deux fonctions à créer dans mes_fonctions.php3.

/*
 *   +----------------------------------+
 *    Nom du Filtre :    TradChamps                                              
 *   +----------------------------------+
 *    Date : mardi 23 août 2005
 *    Auteur :  anonyme                                      
 *   +-------------------------------------+
 *    Fonctions de ce filtre :
 *     Permet d'insérer des balises de traduction dans les
 *     champs de saisie de contenu dans Spip (titres de rubriques
 *     notamment).
 *   +-------------------------------------+ 
 *  
 * Pour toute suggestion, remarque, proposition d'ajout
 * reportez-vous au forum de l'article :
 * http://www.spip-contrib.net/article.php3?id_article=1073
*/

// On met la balise de traduction à l'abri avant
// traitement de la typo par SPIP

function avant_typo($texte) {
   $texte = str_replace("[:","CHAMP_A_TRADUIRE_G",$texte);
   $texte = str_replace(":]","CHAMP_A_TRADUIRE_D",$texte);
   return $texte;
}


// Après le traitement typo, on peut maintenant mettre
// dans notre champ ce qu'on veut

function apres_typo($texte) {

   // Si on trouve cette balise, on lance la procédure

   if(strpos($texte,"CHAMP_A_TRADUIRE") !== false) {

   // je n'ai pas vraiment compris comment accéder à ce
   // paramètre par le code.
   // je le mets donc à la main. C'est le chemin des
   // entrées de local_xx.php3,
   // et ça marche comme ça sur les deux sites où
   // j'ai appliqué ça.

      $acces_local = "public/spip/ecrire:";

   // Bon, ensuite, on remplace en utilisant preg_replace().
   // Noter que les balises ne peuvent
   // contenir que des lettres, des chiffres et des '_'.
   // On remplace ce qu'il y a entre les balises par
   // l'entrée correspondante
   // dans local_xx.php3, ce qui est possible avec
   // la fonction _T().
   // preg_replace() ne marche qu'avec PHP 3.0.9 et
   // supérieurs, si j'ai bien lu.

      $texte = preg_replace_callback(
         // Expression régulière à remplacer :

         '/(CHAMP_A_TRADUIRE_G)
         ([A-Za-z0-9_]*)
         (CHAMP_A_TRADUIRE_D)/',

         // fonction résultats qui extrait la valeur de
         // balise :

            create_function(
                     '$matches',
                     '$valeur = _T($acces_local.$matches[2]);
                     return $valeur;'),
         $texte);
	}
// et zou.							
	return $texte;
}

Discussion

7 discussions

  • 1

    Bonjour, je viens de tomber sur la contrib après être tombé ... sur un os.

    La solution que tu propose corrpspond à ce que je veux utiliser.
    Je travaille en ce moment sur un site dont l’interface doit appraître dans 2 langues. les artcles et leur traduction sont rangés ensemble dans une seule arborescence de rubriques thématiques qui les concernent (et pas 2 abrorescence parallèles avec un secteur pour chaque langue, chose que tu évoques et que je faisais avant.)
    J’ai Spip 2.0.3 en local (Debian Lenny et XP) pour tester mes habillages. le site est pas visible encore.

    J’ai commencé par cocher certains reglages dont “activer le menu de langues pour les rubriques” dans Configuration>Langues du site>Multilinguisme. Et j’ai peur d’avoir fait une connerie.
    En effet les rubriques se voient dès lors attibuer une langue, ce qui est tout l’inverse de ce qu’on cherche.
    Je pensais m’en tirer avec une balise comuniqués ne me donne que “comunicats” si j’ai coché occitan, c’est a priori normal.

    Je suis retourné dans la page de configuration et j’ai coché non pour le menu de langues des rubriques mais j’ai toujours une trace de la langue que je leur ai attribué précédemment. Est ce que je dois créer de nouvelles rubriques vierges et recopier mes articles dedans pour pouvoir applique ensuite ta solutin ? Est ce que je peux corriger mes rubrique existantes ?

    Merci.

    • Bonjour,

      comme je le signale dans le message précédent, cette contrib ne fonctionne plus telle quelle depuis SPIP 1.9...

      En revanche, non, il n’est pas nécessaire de recréer toutes tes rubriques. D’ailleurs, quand tu dis “j’ai toujours une trace de la langue que je leur ai attribué précédemment”, on ne sait pas de quelle trace tu parles. Mais quoiqu’il arrive, le fait d’activer puis de désactiver le menu langue ne crée pas de problèmes.

      Mais comme je dis, SPIP 2 a changé beaucoup de choses dans la gestion de ce genre de trucs, et je ne me suis pas encore penché dessus. Je t’engage cependant à regarder le thread suivant et d’enquêter à partir de là :
      http://www.mail-archive.com/spip@rezo.net/msg09412.html

      Comme je dis, si j’arrive à comprendre comment tout ça a changé dans SPIP 2, je mettrai à jour cette contrib. Mais je ne vois pas ça arriver bientôt. J’ai bien peur qu’il faille que tu fasses davantage de recherches et de tentatives.

      Ciao.

    Reply to this message

  • 2

    bonjour,

    J’ai crée le fichier mes_fonctions.php et même php3 au cas où...

    J’ai mes fichiers lang locals qui fonctionnent bien avec les balises traditionnelles.

    Mais depuis que j’ai installé mes_fonctions.php dans le répertoire squelette, ça affiche ce code au dessus du logo du site.

    Visible sur
    http://test.colliez.info
    (jusqu’à ce que je modifie)

    J’ai bien entendu vidé le cache.

    Merci pour votre aide...

    /* * +----------------------------------+ * Nom du Filtre : TradChamps * +----------------------------------+ * Date : mardi 23 ao�t 2005 * Auteur : Vincent Henderson - vfwh + AT + infomotel.com * +-------------------------------------+ * Fonctions de ce filtre : * Permet d’ins�rer des balises de traduction dans les * champs de saisie de contenu dans Spip (titres de rubriques * notamment). * +-------------------------------------+ * * Pour toute suggestion, remarque, proposition d’ajout * reportez-vous au forum de l’article : * http://www.spip-contrib.net/article.php3?id_article=1073 */ // On met la balise de traduction � l’abri avant // traitement de la typo par SPIP function avant_typo($texte) $texte = str_replace(“[:”,“CHAMP_A_TRADUIRE_G”,$texte); $texte = str_replace(“:]”,“CHAMP_A_TRADUIRE_D”,$texte); return $texte; // Apr�s le traitement typo, on peut maintenant mettre // dans notre champ ce qu’on veut function apres_typo($texte) // Si on trouve cette balise, on lance la proc�dure if(strpos($texte,“CHAMP_A_TRADUIRE”) !== false) // je n’ai pas vraiment compris comment acc�der � ce // param�tre par le code. // je le mets donc � la main. C’est le chemin des // entr�es de local_xx.php3, // et �a marche comme �a sur les deux sites o� // j’ai appliqu� �a. $acces_local = “public/spip/ecrire:”; // Bon, ensuite, on remplace en utilisant preg_replace(). // Noter que les balises ne peuvent // contenir que des lettres, des chiffres et des ’_’. // On remplace ce qu’il y a entre les balises par // l’entr�e correspondante // dans local_xx.php3, ce qui est possible avec // la fonction _T(). // preg_replace() ne marche qu’avec PHP 3.0.9 et // sup�rieurs, si j’ai bien lu. $texte = preg_replace_callback( // Expression r�guli�re � remplacer : ’/(CHAMP_A_TRADUIRE_G) ([A-Za-z0-9_]*) (CHAMP_A_TRADUIRE_D)/’, // fonction r�sultats qui extrait la valeur de // balise : create_function( ’$matches’, ’$valeur = _T($acces_local.$matches[2]); return $valeur;’), $texte); // et zou. return $texte;

    • A la fois ce commentaire et le précédent me laisse croire que la version 1.9 rend cette méthode obsolète.
      Il me semble comprendre qu’il existe maintenant des plugins qui permettent des actions “pre_typo” et “post_typo”.

      Je n’ai pas regardé dans le détail car je n’ai pas encore fait d’install SPIP 1.9, donc je ne saurais pas vous le dire. Je vais sans doute bientôt en faire une donc je mettrai cette contrib à jour à ce moment-là lorsque j’aurai compris comment ça marche.

      De fait, cette solution ne fonctionne que pour 1.8 pour l’instant.

    • Merci de ta réponse rapide !

      Du coup, je retourne dans ma panade... je ne comprends pas pourquoi les développeurs de spip n’ont pas permis d’utiliser les même “ruse” <:tutu:> , peut etre dans la prochaine version...?

      Dommage que l’on a pas une spip fondation riche pour soutenir et aider les développeurs...

      Bon courage à tous nos developpeurs bénévoles ! Et bonne année 2008 à tous !

    Reply to this message

  • 2

    Bonjour,
    Cette méthode conviendrait bien pour un site en 1.9.2 que je démarre mais je me retrouve avec du texte “parasite” dans la partie publique :
    par exemple le code source du titre de la rubrique indique :
    <h1 class="titre">CHAMP_A_TRADUIRE_GViolonCHAMP_A_TRADUIRE_D</h1>

    j’ai mis comme titre de rubrique de rubrique : [:Violon:]

    et dans squelettes/local_en.php :
    // Rubriques
    ’Galerie’=> ’Gallery’,
    ’Violon’ => ’Violin’,

    est-ce j’ai déraillé quelque part ?
    merci
    dd

    • Bonjour,

      le résultat que vous obtenez est exactement le même que celui que vous obtiendriez en n’utilisant que la fonction avant_typo() qui est définie ci-dessus, sans la fonction apres_typo() qui doit venir après.

      Cela signifie que pour une quelconque raison, tout se passe comme si la fonction apres_typo() n’était pas appelée ou ne fonctionnait pas.

      Je vois plusieurs pistes d’investigation:

      1- avez-vous effectivement bien mis la fonction apres_typo() dans mes_fonctions.php3, en utilisant les bonnes règles typographiques pour séparer les fonctions, etc. ?

      2- Si oui, dans ce qui vous est affiché dans votre titre avec les balises CHAMP_A_TRADUIRE, le texte Violon est-il dans la langue que vous attendez (change-t-il de langue lorsque vous changez la langue d’environnement) ?

      3- Si oui, alors c’est incompréhensible, ou cela signifie que votre version de PHP n’est pas compatible et qu’elle a changé la syntaxe de preg_replace_callback() ou quelque chose comme ça (ça me semble improbable)

      4- Si ce texte ne change pas lorsque vous changez de langue, alors nous sommes revenus à l’option 1, c’est à dire que la fonction apres_typo() n’est pas appelée correctement.

      En principe, si vous faites un copier-coller du premier au dernier caractère du champ gris dans mes_fonctions.php3 (dont vous aurez au préalable vérifié la syntaxe dans la documentation de SPIP), cela devrait fonctionner. Si cela n’est pas le cas, alors cela peut être dû soit au fait que SPIP 1.9 ne supporte plus cette fonction (je n’en sais rien), ou que vous l’avez mal typographiée.

      Il n’y a pas d’autre explication à ma connaissance.

      Sauf peut-être si vous n’avez pas activé correctement la gestion des langues, auquel cas peut-être la fonction _T() ne fonctionne pas correctement et du coup avorte le traitement de apres_typo(). Supposition.

      Les pistes à privilégier sont à mon avis de d’abord bien vérifier la syntaxe de votre fonction apres_typo() et de mes_fonctions.php3 en général, et vérifier que la fonction apres_typo() est toujours supportée par votre version de SPIP, car c’est clairement apres_typo() qui n’est pas traitée.

    • Bonjour,
      merci pour la réponse rapide.

      Pour le contenu de mes_fonctions.php3 j’ai recopié le code tel que dans cet contrib. La différence et je ne sais pas si le problème vient de là c’est qu’à partir de SPIP 1.9 le fichier s’appelle mes_fonctions.php

      j’ai d’autres fonctions dans mes_fonctions.php qui..fonctionnent.

      le texte qui apparait (violon) n’est pas la traduction mais l’original donc effectivement je pense que la fonction n’est pas interprétée.

      Ma version de PHP est 5.1.6 et les seules fonctions qui ressemblent à preg_replace_callback() sont:
      assert.callback no value
      unserialize_callback_func no value

      Sur un autre site encore mais en 1.9.1 (sur le même serveur local) c’est différent : il n’y a pas de message d’erreur mais les traductions ne s’affichent pas, simplement le titre de la rubrique à traduire [:violon:] tel quel.

      Voila, en gros je ne vois pas ce qui cloche. en essayant sur un autre site en 1.9.2 j’obtiens le même message d’erreur CHAMP_A_TRADUIRE_GViolonCHAMP_A_TRADUIRE_D

      PS j’ai ajouté * dans les squelettes [#TITRE*] pour courtcircuiter l’ajout d’un espace insécable devant les “:” mais cela ne change rien.

      voila, maintenant je ne sais plus trop quoi tester..
      dd

    Reply to this message

  • 1
    Jean Bptiste Pressac

    Bonjour,
    Merci pour cette contribution. Je ne comprends pas comment utiliser ces 2 fonctions : je suppose qu’il s’agit de filtres que l’on rajoute derriere une balise, par exemple #TITRE|apres_typo. Mais dans ce cas, pourquoi 2 balises ? Faut-il les utiliser en même temps ?

    • Bonjour ,

      avant_typo() et apres_typo() sont des fonctions qui sont exécutées automatiquement par SPIP à partir du moment où elles sont définies dans mes_fonctions.php3. Il y a une fonction typo qui gère les règles typographiques pour l’affichage du texte. Les fonctions avant_typo et apres_typo permettent de faire quelque chose avant et après que cette fonction soit appliquée.

      Il n’est donc pas nécessaire de faire référence à ces fonctions dans les squelettes. A partir du moment où elles sont définies dans mes_fonctions.php3 elles seront traitées, car ce sont des fonctions standard de SPIP. Ce que font ces fonctions telles que je les ai définies, c’est qu’elles cherchent, dans tout le texte juste avant qu’il soit traité pour l’affichage (donc après tous les autres traitements de SPIP), des balises ’[:’ et ’:]’ et les remplace par CHAMP_A_TRADUIRE_G et CHAMP_A_TRADUIRE_D pour que les balises ne soient pas altérées par le traitement typo (qui met des espaces ou pas avant les deux-points selon les règles de la langue). Ca c’est ce que fait avant_typo(). La fonction apres_typo() fait le travail le plus important, c’est à dire chercher la valeur de ’toto’ dans local_xx.php3 et la remplacer dans le texte juste avant l’affichage.

      Il n’y a rien d’autre à faire dans les squelettes, si ce n’est évidemment de bien gérer les filtres linguistiques dans les boucles. Et evidemment définir ces valeurs de toto dans local_xx.php3 et utiliser les balises [:toto:] dans le contenu (pas dans les squelettes).

      Voilà, j’espère que ça clarifie un peu. Cependant, cette contribution suppose déjà une connaissance des fonctions linguistiques de SPIP.

    Reply to this message

  • 1

    attention quand vous copier coller cette contrib, il ne doit pas y avoir d’espace dans ce code:

    ’/(CHAMP_A_TRADUIRE_G)
    ([A-Za-z0-9_]*)
    (CHAMP_A_TRADUIRE_D)/’,

    utiliser docn plutot cela:

    ’/(CHAMP_A_TRADUIRE_G)([A-Za-z0-9_]*)(CHAMP_A_TRADUIRE_D)/’,

    PAS D’ESPACES

    ;)

    sinon ca marche c’est nickel

    • Certes. Nénamoins, la façon dont cela est affiché dans cette contrib, avec un retour ligne, fonctionne très bien, en tous cas chez moi.

      Sinon, merci.

    Reply to this message

  • 1

    Attenion # 2

    pour que ce scritp marche, il faut bine parametrer dans ecrire/mes_options.php

    le ligne:

    $forcer_lang = true;

    Sinon seul les rubriques associe avec la langues courante s’affichent

    Grace a forcer_lang, on change la traduction des [:titre:] en ignorant la langue choisie pour cette rubrique dans l’admin

    • La question du forcer_lang n’a pas grand chose à voir avec ce script à proprement parler. Ce script traduit dans la langue de l’environnement du moment les chaînes taguées.

      Les choix des paramètres de la langue du site n’ont rien à voir avec ce script, qui fonctionne quel que soit le mode linguistique choisi, i.e. forcer_lang=true ou false.

    Reply to this message

  • 1

    Bonsoir!

    D’un côté je suis tenté par ce procédé - surtout s’il peut s’intégrer dans le noyau de Spip.

    Mais il y a un désavantage. Voici un des titres des mes articles:

    050. <multi>[en]By train[ar]بالقطار[de]Mit der Bahn[cs]Vlakem[es]En tren[et]Rongiga[fi]Junalla[fr]Horaires de train[hr]Vlakom[hu]Vonattal[id]Dengan kereta[it]Con il treno[ja]電車で[ko]기차편[lt]Traukiniu[lv]Ar vilcienu[nl]Met de trein[no]Med tog[pl]Pociągiem[pt]De comboio[ro]Cu trenul[ru]Поездом[sk]Vlakom do/z Taizé[sl]Z vlakom[sv]Med tåg[zh]乘火車而至</multi>

    — et si un néerlandais cherche “trein” dans la case de recherche du site, il tombe tout-de-suite sur la bonne page.

    Avec le système proposé dans cet article, les titres (qui se trouvent maintenant dans les fichiers local_xx.php3) ne sont pas indexés.

    Donc je serais plutôt pour avoir une façon plus simple pour entrer un champ “multi” dans un titre. Par ex. une boîte de dialogue qui présente une ligne par langue, étiquetée avec la langue, pour que les rédacteurs ne doivent plus s’occuper des balises multi et [en], [fr], etc.

    Paolo

    • En effet, les titres ne sont plus accesibles au moteur de recherche, ce qui est un vrai problème de cette méthode.

      L’idée d’une boîte de dialogue qui permettrait d’entrer chaque traduction et créerait le contenu des champs multi est en effet une très bonne idée. Je ne sais pas faire ça, mais j’imagine que pour un développeur confirmé, ce serait l’affaire d’une heure ou deux de développement.

      Avis aux amateurs.

    Reply to this message

Add a comment

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite / PostgreSQL
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparait.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Who are you?
[Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom