Formulaire menu_lang plat sans URL sur la langue sélectionnée

Une variation sur le choix des langues et de l’aspect de l’URL engendrée

Dans un site multilingue, #MENU_LANG permet aux visiteurs de passer d’une langue à l’autre. Pour cela, il dépose un cookie sur l’ordinateur du visiteur où il indique en quelle langue naviguer. Cette contrib agit exactement pareil, mais n’affiche pas le choix des langues de la même manière.

Il s’agit d’afficher #MENU_LANG mais :
-  une langue à côté de l’autre
-  sans URL pour la langue dans laquelle on navigue

Installation

Configuration site

Vous avez dans un premier temps configuré, dans la partie privée de SPIP (configuration : gestion des langues > multilinguisme), toutes les langues dans lesquelles sera traduit votre site, en cochant / décochant celles-ci dans la longue liste.

Préparation de « mes_fonctions.php »

Si vous n’avez pas encore créé le fichier mes_fonctions.php, créez un fichier et nommez-le mes_fonctions.php dans votre répertoire /squelettes. Collez le code suivant dans un premier temps, en veillant bien à ne pas avoir de caractères (espaces, retour de chariot…) ni avant, ni après :

<?php

?>

Puis, entre les deux balises ci-dessus, copiez/collez dans ce fichier la fonction qui suit (fonction mise à jour le 22/05/08) :

Pour afficher les langues en deux lettres (EN - FR) :

// menu_lang plat sans URL sur la langue sélectionnée
function url_lang ($langues) {
    include_spip('inc/charsets');    
    $texte = '';
    $tab_langues = explode(',', $GLOBALS['meta']['langues_multilingue']);
    while ( list($clef, $valeur) = each($tab_langues) ) 
	if ($valeur == $GLOBALS['spip_lang']) { 
	$texte .= '<span class="languencours">'.$valeur.'</span>&nbsp;'; 
	}
	else { $GLOBALS['delais'] = 0;
	$texte .= '<a href="'.parametre_url(generer_url_action('cookie'), 'url', parametre_url(self(true), '&'), '&').'&amp;amp;var_lang='.$valeur.'" alt="'.traduire_nom_langue($valeur).'">'.$valeur.'&nbsp;</a>'; 
	}
    return $texte;
}
//fin

Pour afficher les langues en entier (English - Français) :

// menu_lang plat sans URL sur la langue sélectionnée
function url_lang ($langues) {
    include_spip('inc/charsets');
    $texte = '';
    $tab_langues = explode(',', $GLOBALS['meta']['langues_multilingue']);
    while ( list($clef, $valeur) = each($tab_langues) ) 
	if ($valeur == $GLOBALS['spip_lang']) { 
	$texte .= '<span class="languencours">'.traduire_nom_langue($valeur).'</span>&nbsp;'; 
	}
	else { $GLOBALS['delais'] = 0;
	$texte .= '<a href="'.parametre_url(generer_url_action('cookie'), 'url', parametre_url(self(true), '&'), '&').'&amp;amp;var_lang='.$valeur.'" alt="'.traduire_nom_langue($valeur).'">'.traduire_nom_langue($valeur).'&nbsp;</a>'; 
	}
    return $texte;
}
//fin

Utilisation

Squelettes

Dans vos squelettes, appelez le menu avec la balise #CONFIG{langues_utilisees} suivie du filtre url_lang :

[<div class="menu_langues">(#CONFIG{langues_utilisees}|url_lang)</div>]

Feuilles de styles

Dans vos CSS, vous pouvez personnaliser la balise avec la classe « .menu_langues » et « .languencours »

Exemple

Exemple de résultat visible ici.

Discussion

18 discussions

  • 2
    Rainer

    Bonjour,

    Je viens d’essayer ce menu avec un spip 1.9.3 dev [11578] et chaque fois que je clique sur le lien je suis renvoié à l’espace interne.

    Comment faire pour faire cette contrib compatible avec 1.9.3

    Merci
    Rainer

    • natalia

      Je ne pense pas travailler sur la question avant la sortie effective de la 1.9.3...

      Si vous avez des idées, n’hésitez pas !

    • Rainer

      En fait, en cherchant un peu les différent propositions de code je me suis bricolé celui ci

      <?php
      function url_lang ($langues) {
          $texte = '';
      	$tab_langues = explode(',', $GLOBALS['meta']['langues_multilingue']);
          while ( list($clef, $valeur) = each($tab_langues) ) 
      	if ($valeur == $GLOBALS['spip_lang']) { 
      	$texte .= '<li>  | '.traduire_nom_langue($valeur).'</li>'; 
      	}
      	else { 
      	$cible = str_replace('&amp;', '&', parametre_url(self( /* racine */ true), 'lang', ''.$valeur.'','&')) ;
      	$texte .= '<li> | <a href="'.parametre_url(generer_url_action('cookie'), 'url', $cible, '&').'">'.traduire_nom_langue($valeur).'</a></li>'; 
      	}
          return $texte;
      }
      ?>

      Si ce code crée bien les liens de langue (fonctionnant aussi avec les URLs propres)il ne paraît pas poser le cookie de langue ce qui oblige a faire parametre_urllang,#ENVlang pour les liens en question.

      Quelqu’un pourrait me dire ce qui cloche ?

      Merci
      Rainer

    Répondre à ce message

  • 3

    Bonjour,
    j’essaie de mettre en place un site multilingue fr-en-es.
    J’ai du mal à comprendre et ma logique actuelle serait de traduire les rubriques.
    par exemple rubrique 1 présentation [en français] puis une traduction de la rubrique en espagnol et une autre traduction pour l’affichage de la rubrique 1 en anglais
    Seulement acuellement je n’ai pas la possibilité de traduire les rubriques. Pourtant j’ai bien configuré la gestion des langues sur « Activer le menu de langue sur les rubriques »

    ou alors une langue par rubrique ?

    merci de vos éclaircissements.

    Fourmy

    • Tu peux d’abord lire ca si tu ne l’a pas encore fait :

      http://www.spip.net/fr_rubrique467.html

      Apres, y’a un super plugin basé sur l’utilisation des blocs multi. Qui permet donc de garder une seule arborescence : extension_multilingue_pour_BTV2

    • Bonjour et merci,

      J’ai lu un peu tout ce qui existe sur le sujet mais suis parfois un peu flippé de lire des articles plus adaptés à la version 9.2 de spip. Quoi qu’il en soit j’ai effectivement mis en place une arborescence via les blocs multi ( donc sans duplication de l’arbo par secteur langue)
      ensuite je procede par traduction d’articles.
      ça marche niquel !

      Pour le plugin dont tu me parles. Il permettrait donc aux utilisateurs du back office de creer des rubriques et sous rubriques sans avoir a saisir les balises multi et [es][fr][en] ? j’ai juste ?

      sais tu s’il rentre en conflit avec fckeditor ?

      Voilà j’ai des milliers d’autres questions parceque je démarre juste mais c’est plutot super bien foutu spip !.

      Merci de ton aide

      Fourmy

      [ j’ai biensur répondu à l’alerte mail (ce qu’il ne fallait pas faire !) avant de capter le lien vers le forum- Désolé]

    • Pour le plugin dont tu me parles. Il permettrait donc aux utilisateurs du back office de creer des rubriques et sous rubriques sans avoir a saisir les balises multi et [es][fr][en] ? j’ai juste ?

      Tout a fait

      Mais pour le conflit avec fckeditor, je ne sais pas... Essaye

    Répondre à ce message

  • 8

    Dans un site (SPIP 1.9.2c [10268]) configuré en multilingue, avec un menu de langue activé sur les articles et les rubriques, tous les titres : du site, des rubriques et des articles sont bien gérés au changement de langue avec les balises (utilisation du plugin : extension_multilingue_pour_BTV2). L’affichage des bons textes des différentes traductions se fait bien aussi dans toutes les pages. L’option : $forcer_lang = true ; est présente dans mes_options.php (dossier ecrire) et filtre lang est utilisé sur les boucles.
    Pourtant ce script présent dans mes_fonction.php (dossier squelettes) et bien appelé dans les squelettes ne donne RIEN.
    J’ai sans doute oublié quelque chose, mais quoi ?
    Antoine

    • Une source d’erreur certaine : le fichier mes_options.php se range désormais dans config/ avec la version 1.9.2. Pour plus de détails : http://www.spip.net/fr_article3567.html, paragraphe sur la réorganisation des répertoires !

    • Tout petit détail complémentaire : vérifie que tu as bien un fichier mes_fonctions.php dans squelettes/ et pas mes_fonction.php comme écrit dans ton message ;-)

    • Cela ne donne toujours rien (même avec les bons fichiers « options.. » et « fonctions.. » au bon emplacement). Sur la page « config_multilang » le « Français » (lien vert) est affiché mais pas le lien « Anglais » alors que cette langue est cochée plus bas dans la liste. Il n’y a pas de traduction d’articles en anglais, mais les titres et les textes sont présents dans les articles en français et en anglais avec les balises , et le changement de langue fonctionne bien dans le site public et privé avec la balise #MENU_LANG.
      Cependant, quand j’utilise un menu PLAT pour le choix entre l’anglais et le français, toutes les formules ne donnent que le français, car c’est la seule langue reconnue comme étant utilisée dans le site, pourquoi ?

    • Sur la page « config_multilang » le « Français » (lien vert) est affiché mais pas le lien « Anglais » alors que cette langue est cochée plus bas dans la liste.

      Le français apparaît ainsi car c’est la langue principale du site. Les langues de traduction sont simplement cochées dans la liste.

      Cependant, quand j’utilise un menu PLAT pour le choix entre l’anglais et le français, toutes les formules ne donnent que le français.

      Nous en sommes au même point : j’obtiens exactement le même comportement sur mon site. J’ai testé un double affichage (#MENU_LANG et menu_lang plat) dans ma page sommaire. Résultat : le français est affiché seul à plat alors que le menu local me propose bien les deux langues.

    • Bonjour, merci à Michael d’avoir « sonné » ma boîte mail pour que je vienne faire un tour ici :-)

      Avant toute chose j’ai besoin de l’URL du site qui pose problème ?
      Et de celle du plugin « multilingue » que je ne connais pas et que je soupçonne un peu.

      Voilà une URL où ça marche avec Spip 1.9.2c : http://www.new-school-of-athens.org/

    • Merci de ton retour dans le débat Natalia !

      Voici la méthode de contournement trouvée ce matin. Il suffit de remplacer la déclaration de la variable $tab_langues

      $tab_langues = explode(",",$langues);

      par

      $tab_langues = explode(',', $GLOBALS['meta']['langues_multilingue']);

      Avantage de la méthode : elle fonctionne aussi au niveau des articles et des brèves avec l’appel proposé dans la contrib :

      [<div class="menu_langues">(#CONFIG{langues_utilisees}|url_lang)</div>]

      Comme je en suis pas un codeur, pas même un patcheur, je m’inquiète d’éventuelles conséquences imprévues. Une idée sur le sujet ? Est-ce “safe” ?

    • Bravo cette modification me donne parfaitement satisfaction et j’obtiens enfin un menu de langues plat dans un site multiligue qui n’utilise que la gestion des différentes traductions avec les balise « multi ». Gestion très facile avec le plugin « extension_multilingue_pour_BTV2 ».
      J’espère aussi que ce code, qui marche apparemment bien, est fiable et sans effet négatif sur le fonctionnement général de Spip.
      Merci beaucoup
      Antoine

    • Merci beaucoup pour ta contribution Michael, ça marche impec.
      A priori je trouve ça plutôt safe, on verra à l’usage !

      J’ai mis à jour la contrib, du coup :-)

    Répondre à ce message

  • 7

    Et pourquoi pas une solution purement SPIP, sans PHP, ni de fichier mes_fonctions.php ?

    -  Une BOUCLE de Menu de langues

    -  Exemple d’application

    • Je l’ai cherchée cette contrib !! Merci !!

      Mais ça ne me satisfait pas sur un point : les langues changent d’ordre en fonction de la langue choisie... et sur mon cahier des charges l’ordre ne doit pas bouger :-(....

    • laurent

      Cela peut être utile lorsque l’on a décidé de ne pas appliquer le multilinguisme aux rubriques mais seulement aux articles, non ?

    • Ce que je me dis : #Menu_LANG sert à changer la langue de l’interface, et non pas des articles. Les langues des articles sont gérées par les boucles de traduction...

      ... mais il y a pas mal de combinaisons possibles, alors si ça peut être utile dans l’une ou l’autre, tant mieux :-)

    • Gilles Vincent

      la contrib utilise un tableau PHP qui est alimenté à chaque appel de page par SPIP. Il n’y a donc aucun parcours dans la base. L’avantage est que la construction du menu est très rapide.

      A l’inverse, le menu tel qu’il est calculé dans le squelette Alternative à l’inconvénient majeur de reparcourir l’ensemble des rubriques à chaque fois qu’il est reconstruit. Il n’y a rien de pire côté perfs que des boucles qui parcourent la totalité d’une table : derrière, c’est des requetes SQL qui tournent et un parcourt complet ne permet aucune optimisation (utilisation des index, etc..). Pour peu que le site présente un grand nombre de rubriques, avec une mauvaise mise en cache du menu, la chute des perfs devient vite sensible.

      Au passage le fichier inc-bas_menu-lang.html ne possède pas d’instruction #CACHE{} ...

      Pour ma part, je préfère avoir un côté pragmatique, lorsque la beauté du code ne se justifie pas. Cette contrib est à mes yeux nettement meilleure .

    • Gilles Vincent

      Je vais nuancer quand même mon propos :

      La requete générée par la boucle d’Alternative utilise en fait le champ « lang » qui est un champ indexé dans les tables MySQL. La consommation est donc assez faible.

      Cependant, ce calcul a déjà été fait par SPIP (via la fonction calculer_langues_utilisees).

      Conclusion : c’est pas trop grave de refaire la même chose, mais on consomme un peu quand même..

    • Les répertoires d’Alternatives ont été remaniés. Voici le bon lien :
      -  inc-bas_menu-lang.html

      Pour information : ce menu de langues fonctionne mieux si on indique dans mes_options.php : $forcer_lang = true ;

    Répondre à ce message

  • 6

    Intéressant, mais si c’est basé sur les deux premières lettres de la langue, ça ne marche pas pour le néerlandais. En effet, on symbolise cette langue par NL et non NE...
    Il faudrait plutôt un système basé sur des symboles textes ou images préencodés dans l’interface privée. On pourrait y mettre des lettre, mais aussi des drapeaux,...

    • Peut-être qu’avec des drapeux dont le nom seraient fr.png, en.png, ... cela devrait fonctionné tel quel

    • Je n’aime pas beaucoup les drapeaux dans les choix des langues... l’espagnol est parlé aussi bien en Argentine qu’en Espagne, pourquoi mettre un drapeau espagnol ? Etc...

      Après, tout est possible pour le menu de choix des langues, cette contrib ne fait que répondre à une demande bien spécifique : ne pas mettre de lien sur la langue en cours dans le type de sites où une rubrique n’a pas de langue spécifique.

    • C’était un exemple, mais moi non plus je n’aime pas les drapeaux. Ici, en Wallonie, on parle français et nous sommes en Belgique...

      Par contre pour le problème NL à la place de NE pour le néerlandais, il suffit à mon avis d’ajouter un condition en php qui redéfinit la variable $texte en NL si elle est égale à NE...

      Je vais essayer...

    • Fausse alerte, j’ai parlé trop vite. La variable transmise pour le néerlandais est bien NL. Donc tout est ok Natalia. Désolé pour les chipos inutiles...

    • marabbeh

      Mais un exemple où les drapeaux ont leur sens : je gère des sites franco-allemands au sens France-Allemagne. Donc ils ne concernent ni l’Autriche, ni la Suisse, ni la Belgique...

    • Mais vous parlez le FRANCAIS, il est donc normal pour symboliser le FRANCAIS de mettre un drapeau FRANCAIS, au même titre que de mettre un drapeau ESPAGNOL pour l’ESPAGNOL, même s’il est parlé dans d’autres pays.

    Répondre à ce message

  • 2

    Mise à jour de la fonction suite au passage en 1.9.2a :

    function url_lang ($langues) {
        $texte = '';
        $tab_langues = explode(",",$langues);
        while ( list($clef, $valeur) = each($tab_langues) ) 
    	if ($valeur == $GLOBALS['spip_lang']) { 
    	$texte .= ''.$valeur.'&nbsp;'; 
    	}
    	else { 
    	$cible = str_replace('&', '&', parametre_url(self(true), 'lang', ''.$valeur.''));
    	$texte .= '<a href="'.parametre_url(generer_url_action('cookie'), 'url', $cible, '&').'">'.$valeur.'&nbsp;</a>'; 
    	}
        return $texte;
    }

    Il faut juste remplacer la fonction de l’article par celle-ci dans le fichier mes_fonctions.php

    • natalia

      Fonction simplifiée qui devrait marcher sur toutes les versions de spip.... (à confirmer) :

      // menu_lang plat sans URL sur la langue sélectionnée
      function url_lang ($langues) {
          $texte = '';
          $tab_langues = explode(",",$langues);
          while ( list($clef, $valeur) = each($tab_langues) ) 
      	if ($valeur == $GLOBALS['spip_lang']) { 
      	$texte .= '<span class="languencours">'.$valeur.'</span>&nbsp;'; 
      	}
      	else { 
      	$texte .= '<a href="spip.php?action=cookie&url=%2Fspip.php%3Frubrique11&var_lang='.$valeur.'">'.$valeur.'&nbsp;</a>'; 
      	}
          return $texte;
      }
      //fin

      J’ai ajouté une classe sur la langue en cours, afin de la personnaliser. Remplacez la fonction + ajoutez une classe nommée « languencours » à votre feuille de styles.

    • Après test des 2 modifications proposées pour la fonction url_lang() sur un spip version 1.9.3 [9398] utilisant les url_propres, seul le code de la première mise à jour (celle du 16 mars) semble fonctionner.

      Pour compléter, si on veut afficher les langues en entier (English - Français...) cette fonction donne donc :

      function url_lang ($langues) {
          $texte = '';
          $tab_langues = explode(",",$langues);
          while ( list($clef, $valeur) = each($tab_langues) ) 
      	if ($valeur == $GLOBALS['spip_lang']) { 
      	$texte .= ''.traduire_nom_langue($valeur).'&nbsp;'; 
      	}
      	else { 
      	$cible = str_replace('&', '&', parametre_url(self(true), 'lang', ''.$valeur.''));
      	$texte .= '<a href="'.parametre_url(generer_url_action('cookie'), 'url', $cible, '&').'">'.traduire_nom_langue($valeur).'&nbsp;</a>'; 
      	}
          return $texte;
      }

      Ne pas oublier de paramétrer la variable de personnalisation $forcer_lang à true dans le fichier mes_options.php si on souhaite que l’intégralité de la navigation passe dans la langue souhaitée lors du clic sur un lien de traduction.

      Merci pour cette contrib très pratique !

    Répondre à ce message

  • C’est sympa comme approche, mais qu’est-ce qu’on fait avec les url_propres ?

    FDM

    Répondre à ce message

  • 4

    Bon, j’ai utilisé la fonction telle quelle, mais ça ne marche pas. L’url ne correspond pas au lien et la variable langue n’est pas transmise. On dirait qu’il y a des « amp » qui se perdent et le n° de la rubrique ou de l’article reste bloqué...

    • Quelle version de spip ?

    • La dernière version : 1.9.2

    • Je vais bientôt passer le site sur lequel j’ai dû mettre en place cette contrib sur 1.9.2, je vous tiens au courant...

    • J’ai eu ce même problème et j’ai pu le corriger en modifiant légèrement la fonction :
      Il faut remplacer la ligne :

      $cible = str_replace(’&’, ’&’, parametre_url(self( /* racine */ true), ’lang’, ’’.$valeur.’’)) ;

      par :

      $cible = str_replace(’& amp ;’, ’&’, parametre_url(self( /* racine */ true), ’lang’, ’’.$valeur.’’,’&’)) ;

      Bien entendu il faut enlever l’espace entre « & » et « amp ; »

      A+++

    Répondre à ce message

Ajouter un commentaire

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
  • 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 apparaît.

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.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom