Trouver les « traductions » des rubriques

Voici une méthode simple — sans mots clefs — pour lier les rubriques de même contenu dans différentes langues.
On simule alors les liens de traductions des articles retournés par le critère {traduction}

Les liens de traduction entre rubriques n’existent pas dans SPIP. Quand on pense à un site comme spip-contrib, les secteurs de langues différentes n’ont pas le même plan et des liens de traduction entre rubriques n’auraient aucun sens.

Pourtant, beaucoup de sites adoptent le multilinguisme en dupliquant le plan des rubriques de la langue principale dans les secteurs des autres langues. C’est alors tentant et censé d’afficher à l’utilisateur une liste de liens vers les autres langues.

Si on pense au site adoptant la structure stricte décrite plus haut, les « traductions » d’une rubrique sont les rubriques qui contiennent les traductions des articles de cette rubrique.

On voit alors une solution se profiler : Faire une boucle qui trouve ces rubriques en parcourant la liste des traductions des articles de la rubrique actuelle.

<BOUCLE_rub_pr(RUBRIQUES) {id_rubrique}>

ici le contenu habituel de la rubrique.

    <B_art_traduits>    

        Ici le texte avant s'il y a au moins une traduction
    
    <BOUCLE_art_traduits(ARTICLES) {id_trad > 0} {id_rubrique} {par lang}>
        <BOUCLE_trad(ARTICLES) {traduction} {exclus}>
            <BOUCLE_rub(RUBRIQUES) {id_rubrique} {doublons}>
                <a href="#URL_RUBRIQUE">[(#LANG|traduire_nom_langue)]</a>
            </BOUCLE_rub>
        </BOUCLE_trad>
    </BOUCLE_art_traduits>
    
        Ici le texte après s'il y a au moins une traduction

    </B_art_traduits>

    Ici le texte s'il n'y aucune traduction de la rubrique.

    <//B_art_traduits>


ici le contenu habituel de la rubrique.

</BOUCLE_rub_pr>

La boucle rub_pr est la boucle principale qui détermine dans quel rubrique on se trouve actuellement. Si on édite le squelette rubrique.html, alors elle s’y trouve déjà.

La boucle art_traduits liste les articles de la rubrique. Le critère {id_trad > 0} nous permet de limiter l’affichage aux articles ayant au moins une traduction. C’est cette boucle qui détermine si une liste de rubrique va être affichée. C’est donc à elle que l’on ajoutera les balises « optionnelles » s’il y en a besoin.

La boucle trad cherche les traductions des articles de la rubrique.

La boucle rub va afficher un lien vers la rubrique qui contient la traduction trouvée. On utilise le critère {doublons} pour s’assurer que l’on affiche pas deux fois la même rubrique. En effet, comme on regarde plusieurs articles de la rubrique principale, on pourrait trouver plusieurs traductions se trouvant dans la même rubrique.

Remarque : il n’y a pas moyen de trier cette liste selon beaucoup de critère. On peut juste la trier selon les langues avec le critère {par lang} dans la boucle art_traduits.

Nouveau critère

Pour contourner le problème des tris, on peut, à partir de [SPIP 1.8], déclarer une nouvelle version du critère {traduction} qui fera la même chose.

C’est ce qui est fait par le code proposé dans le fichier

Le critère {traduction} étendu aux rubriques

à insérer dans son fichier mes_fonctions.php3.

On pourra alors faire directement une boucle :

<BOUCLE_rub(RUBRIQUES)>
<hr>
#TITRE #ID_RUBRIQUE
<BOUCLE_trad(RUBRIQUES){traduction}>
<br />#PUCE #TITRE #ID_RUBRIQUE
</BOUCLE_trad>
</BOUCLE_rub>

Dernière modification de cette page le 16 décembre 2006

Discussion

Une discussion

  • 3

    Bonsoir,

    Cette solution est très intéressante, surtout dans des cas où le méthode du mot-clef est peu attirante, car on va avoir un nombre constamment grandissant de rubriques.

    Je cependant eu du mal à faire fonctionner la fonction avec SPIP 1.8.2 ; je vous explique plus en détails :


    Ligne 7 : $not, spécifié en paramètre de fonction, n’est pas trouvé (la fonction est appelée avec 3 paramètres). Je l’ai donc enlevé.


    Ligne 13 : $param est un objet, la propriété ->op contient la valeur ’traduction’, j’ai changé en conséquence.


    Ligne 14 à 28 : J’avais du mal à suivre la construction de la requête dans l’instance $boucle (je suis nouveau sur SPIP, c’est peut-être pour ça), alors je l’ai modifiée pour ceci :

    $boucle->from[] = "spip_articles AS source, spip_articles AS dest";
    $boucle->where[] = 
       " source.id_trad = dest.id_trad
       AND source.id_rubrique = \"." . calculer_argument_precedent($idb, 'id_rubrique', $boucles) . ".\"
       AND dest.id_rubrique != \"." . calculer_argument_precedent($idb, 'id_rubrique', $boucles). ".\"
       AND dest.id_rubrique = rubriques.id_rubrique";

    Une fois ces modifications faites, ça marche.

    Enfin voilà. Cette solution ne satisfait pas mon cas, car je vais me retrouver avec des rubriques ne contenant que des sous-rubriques (pas d’articles), je ne pourrai donc pas me fier sur cette fonction. Pour être vraiment solide, il faudrait une inspection récursive des sous-rubriques, s’il n’y a pas d’articles directement dans la rubrique. Mais avec si peu de connaissance (pour l’instant) sur le core de SPIP, je ne sais pas comment y arriver. Ou peut-être est-ce rêver en couleur ? Est-ce que qqun a déjà fait ça ? Qu’en pensez-vous ? J’aimerais beaucoup avoir de vos commentaires.

    PS : Peut-être que qqn peux me répondre ici : j’aimerais savoir si la possibilité de faire un lien de « traduction » entre les rubriques est une fonctionnalité qui est présentement planifiée, et sinon pourquoi ?

    Merci beaucoup

    François

    • OK, c’est encore moi.

      J’ai reprogrammé la fonction critere_traduction (et programmé deux fonctions récursives) qui font ce que j’ai décrit plus haut. L’article utilisé pour trouver l’équivalent dans l’autre langue n’est pas seulement recherché dans la rubrique, mais dans toutes ses sous-rubriques. Donc, si on a une rubrique qui ne contient que des sous-rubriques, on peut quand même avoir la « traduction ».

      Je vous averti, cette fonction sent le hack a plein nez, et il me semble qu’elle brise le modèle de fonctionnement de l’application, et c’est très peu testé, et pas commenté, etc, etc.

      Mais, je crois qu’elle marche (SPIP 1.8.2) ! Est-ce que ça intéresse qqn ? Si oui, je pourrais la rendre un peu plus sérieuse.

      function critere_traduction($idb, &$boucles, $param) {
      	$boucle = &$boucles[$idb];
      	
      	// cas des rubriques : on va chercher toutes les rubriques contenant
      	// des trads *publiees* de nos articles *publies*
      	if ($boucle->id_table == 'rubriques') {
      	if ($param->op == 'traduction') {
      	
      		global $id_rubrique;
      		$art_traduit = _recur_trouver_article(array('id_rubrique' => $id_rubrique, 'profondeur' => 0));
      		$rub_traduit = _recur_descendre_arbo($art_traduit);
      		
      		$boucle->where[] = "id_rubrique = {$rub_traduit[id_rubrique]}";
      			
      		return;
      	} else
      		erreur_squelette(_T('zbug_info_erreur_squelette'), $param);
      	}
      
      	// cas normal (articles) : la table possede un champ id_trad
      	if ($param == 'traduction') {
      		$boucle->where[] = "((".$boucle->id_table.".id_trad > 0 AND "
      			. $boucle->id_table.".id_trad ='\"."
      			. calculer_argument_precedent($idb, 'id_trad',
      				$boucles)
      			. ".\"')
      		OR
      			(" . $boucle->id_table.".".$boucle->primary." ='\"."
      			. calculer_argument_precedent($idb, $boucle->primary,
      				$boucles)
      			. ".\"'))";
      	} else
      		erreur_squelette(_T('zbug_info_erreur_squelette'), $param);
      }
      
      function _recur_trouver_article($params)
      {
      	$select[] = "dest.id_rubrique";
      	$from[] = "spip_articles AS source, spip_articles AS dest";
      	$where[] = " source.id_trad = dest.id_trad
            			AND source.id_rubrique = {$params[id_rubrique]}
            			AND dest.id_rubrique != {$params[id_rubrique]}";
            	
          $result = spip_abstract_select($select, $from, $where);	
          
          if($rangee = mysql_fetch_assoc($result)) {
          	return array('id_rubrique' => $rangee['id_rubrique'], 'profondeur' => $params['profondeur']);
          } else {
          	
          	unset($select);
          	unset($from);
          	unset($where);
          
          	$select[] = "sous.id_rubrique";
          	$from[] = "spip_rubriques AS sous";
          	$where[] = "sous.id_parent = {$params[id_rubrique]}";
          	$result = spip_abstract_select($select, $from, $where);	
          	
          	while($rangee = mysql_fetch_assoc($result)) {
          		$res = _recur_trouver_article(array('id_rubrique' => $rangee['id_rubrique'], 'profondeur' => $params['profondeur']+1));
          		
          		if($res['id_rubrique'] != -1) {
          			return $res;
          		}
          	}
          	
          	return array('id_rubrique' => -1, 'profondeur' => $profondeur);
          }
      }
      
      function _recur_descendre_arbo($params)
      {
      	if($params['profondeur'] == 0) {
      		return $params['id_rubrique'];
      	} else {
      		
      		$select[] = "id_parent";
      		$from[] = "spip_rubriques";
      		$where[] = "id_rubrique = {$params[id_rubrique]}";
       		$result = spip_abstract_select($select, $from, $where);
       		
      		if($rangee = mysql_fetch_assoc($result)) {
          		return _recur_descendre_arbo(
          			array('id_rubrique' => $rangee['id_parent'], 'profondeur' => $params['profondeur']-1)
          		);
          	}
      	}
      }
    • Salut,

      oui, ça a changé dans la 1.8.2.

      pour les codes que tu proposes, tu pourrais le faire en extension de la contrib sur le wiki (voir le lien en dessous de la contrib)

    • cela n’a plus l’air de passer en SPIP 1.9... Quelqu’un a t’il un patch pour trouver ce fameux critère {traduction} pour les rubriques ?

    Répondre à ce message

Ajouter un commentaire

Qui êtes-vous ?

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