fastclemmy.com

Intéressant phénomène que celui qui fait grand bruit chez nos amis anglophones (et à peine chez nous). L'objet de tant d'ébullitions ? Les tags. Aucun lien avec une quelconque activité illégale de peinture urbaine, il s'agit simplement du développement d'un système permettant aux internautes d'enrichir l'information disponible sur le net grâce à des métadonnées. Porte-étendards de ce mouvement : del.icio.us qui permet de partager ses favoris et flickr qui permet de publier ses photos en ligne. Explications et pistes de réflexion sur ce qui pourrait bien dépasser le stade de l'épiphénomène...

Tout vient en fait d'un constat assez simple : le déferlement journalier de l'information a atteint un point qu'il devient de plus en plus difficile de la classifier, de l'archiver et surtout de la restituer à ceux qui la recherche par la suite. Même si certains doutent de la réalité de ce déluge (non je n'ai pas osé dire tsunami), il est sûr qu'une course est engagée tous azimuts pour ne rien en manquer (agrégateurs RSS, blogmarks, Google News, etc.).

Le phénomène del.icio.us

C'est dans ce cadre qu'on a vu débarquer del.icio.us. Au-delà de l'astuce du nom de domaine, le service web répond à une vraie demande de la part des utilisateurs. Malgré un format normalisé pour les favoris (XBEL), les différents navigateurs utilisent leur propre format pour stocker les bookmarks. Par ailleurs le stockage en local expose potentiellement l'utilisateur à la perte de ses informations (virus, plantage de machine, formatage...), la bonne solution est donc évidemment de profiter du réseau pour une sécurité et une mobilité accrue. C'est justement ce que propose del.icio.us, mais à la différence d'un mylinea par exemple, il offre un double avantage : l'aspect collaboratif et l'exploitation des métadonnées.

Métadonnées, mouais, concrètement, ça veut dire quoi ? Traditionnellement les métadonnées sont définies comme de l'information sur l'information ("data about data"). Les internautes partagent grâce à del.icio.us leurs marque-pages, ils ne les classent pas dans des dossiers mais leur attribuent des "tags" ou "mots-clés", ils enrichissent l'information brute (l'URL) par une autre information (le mot-clé). Ainsi, fastclemmy.com par exemple est marqué par les termes suivants : "blogs", "css", "xhtml", "français", "standards-web", "web"... Le résultat peut paraître chaotique (il l'est d'ailleurs certainement de facto) et pourtant il s'avère terriblement efficace. Contrairement aux usines à gaz de la métadonnée (Dublin Core, DocBook...), la mise en oeuvre est intuitive, rapide et pertinente.

Le processus est intéressant dans la mesure où, à l'instar des wikis, le marquage des tags est collaboratif. Le travail de classification de l'information n'est plus subordonné à une équipe ou à un outil informatique (par définition non-intelligent) mais à un nombre élevé d'utilisateurs. On parle de classification distribuée.

Le phénomène s'étend... et trouve déjà ses limites

D'autres services ont emboité le pas à del.icio.us. J'ai parlé plus haut de Flickr, qui permet de partager ses photos et de les annoter avec des tags. Récemment c'est aussi Technorati, sorte de baromètre des weblogs, qui proposait une syntaxe simple <a rel="tag" href="http://technorati.com/tag/[tagname]"> pour voir de quoi on parle dans la blogosphère.

Autant dire que ça bouge pas mal dans le domaine en ce moment... et on ne tarde pas à cerner rapidement les limites de ce système : les conséquences sociales, la montée en charge des systèmes de tags, les abus, etc. On l'aura compris, ce nouvel outil n'est pas parfait, le contraire serait étonnant pour un phénomène aussi jeune. Les métadonnées c'est l'avenir mais c'est encore un peu jeune...

Et Google dans tout ça ?

A mon avis, tout ce mouvement doit en faire réfléchir plus d'un chez Google... Je ne doute pas qu'ils soient toujours à l'affût des nouveautés en termes de technologie de l'information. On l'a déjà vu avec l'expérimentation de Google Suggest, ce petit "plus" qui permet d'affiner sa recherche en temps réel grâce à l'utilisation de javascript/xmlhttprequest. Leur intérêt pour des techniques alternatives de ce genre est d'autant plus probable que leur décision d'introduire l'attribut rel="nofollow" sonne comme un aveu d'échec de leur algorythme de recherche PageRank. Pourtant, cet échec (relatif, Google reste l'un des moteurs de recherche les plus pertinents) n'est pas le premier : l'indexation manuelle des sites dans des annuaires a fait long feu (que ce soit par une "petite" équipe chez Yahoo ou l'appel international de DMOZ), les méta-moteurs ont fait un flop, etc. La distribution classifiée pourrait être l'un des moyens pour Google d'améliorer un peu plus sa pertinence.

Imaginez un Google qui combinerait ses différentes sources d'informations : DMOZ, informations HTML des pages (balises <title>, titrages, emphases), PageRank ET tagging. Car s'il est illusoire de penser que le phénomène de tagging est une révolution, il me semble plutôt qu'il s'agit d'un outil de plus pour mettre en place une approche combinatoire de la recherche d'information.

Tout ceci bien sûr en attendant que les metadonnées atteignent enfin votre bureau...

#conceptionWeb

Vous êtes ici !

# 06-01-2005

Qu'il est agréable de trouver sur un plan le fameux macaron rouge "vous êtes ici". Sur un site web, c'est un peu pareil, il est de bon ton de dire au visiteur où il se situe dans le site. Généralement cela consiste à différencier dans la barre de navigation l'item correspondant à la page active.

Une pratique courante consiste à effectuer cette opération côté serveur. Comme dans l'exemple donné dans A List Apart, on renseigne sur chaque page une variable appelée par exemple $pageCourante ($pageCourante = "accueil") puis on vérifie à l'affichage de la navigation pour chaque item si il s'agit de la $pageCourante. Si c'est le cas, on affecte un id spécifique pour différencier l'item des autres. Grossièrement, le code PHP ressemble à ça :


<ul id="nav">
	<li<?php if ($pageCourante=="accueil") 
		echo " id=\"pageActive\""; ?>>
	<a href="index.php">Accueil</a></li>
	<li<?php if ($pageCourante=="produits") 
		echo " id=\"pageActive\""; ?>>
	<a href="produits.php">Produits</a></li>
	<li<?php if ($pageCourante=="services") 
		echo " id=\"pageActive\""; ?>>
	<a href="services.php">Services</a></li>
	<li<?php if ($pageCourante=="contact") 
		echo " id=\"pageActive\""; ?>>
	<a href="contact.php">Contact</a></li>
</ul>

Côté serveur ou côté client ?

Ca fonctionne bien, d'ailleurs j'ai moi-même adopté cette technique sur de nombreux sites. Néanmoins, je me demande maintenant si le fait que ce soit le serveur qui s'en occupe offre vraiment un intérêt et ce, pour au moins deux raisons. D'une part parce que cela oblige à rajouter pour chaque fichier du site le nom de la page en cours ($pageCourante = "accueil"), ce qui implique au pire de la maintenance fastidieuse ou au mieux un développement supplémentaire pour le gérer automatiquement. D'autre part, parce que je ne vois pas de valeur ajoutée à l'utilisation d'un langage serveur pour ça. Pas de problème de sécurité, simple information visuelle, bref, tout me fait plutôt pencher pour une solution côté client avec javascript.

La structure du code

Avant de nous plonger dans le code, dégageons la structure du script que nous allons écrire.

  1. Récupérer le nom la page en cours
  2. Faire une boucle pour récupérer le lien href contenu dans les balises <a>
  3. Comparer le lien avec le nom de la page en cours
  4. Modifier l'apparence du lien pointant vers la page en cours

Côté résultat final, ça se passe par là. Côté code, ça donne :


function highlightNav() {
	var chemin = "";
	var cheminComplet = "";
	
	// on essaye de détecter la page en cours pour modifier le style du lien actif
	if(document.getElementById("nav")) {
		
		// on récupère la page en cours
		
		// si l'URL comporte une query string, on la retire
		if(document.location.search) {
			cheminComplet = document.location.href;
			cheminCompletSansQueryString = cheminComplet.split(document.location.search);
			cheminComplet = cheminCompletSansQueryString[0];
		} else {
			cheminComplet = document.location.href;
		}

		// si il n'y a pas de fichier après le dernier slash, on doit être sur la page index.php
		cheminCompletDecoupe = cheminComplet.split("/");
		if (cheminCompletDecoupe[cheminCompletDecoupe.length-1] == "") {
			chemin = cheminComplet;
			cheminComplet += "index.php";
		} else {
			chemin = cheminCompletDecoupe.splice(0,cheminCompletDecoupe.length-1) 
			chemin = chemin.join("/");
			chemin += "/";
		}
		
		// on boucle sur les balises <a> pour récupérer leur href
		listeDesLiens = document.getElementById("nav").getElementsByTagName("a");
		for (var i=0; i<listeDesLiens.length; i++) {
			// on compare le href avec le chemin de la page en cours
			if(listeDesLiens[i].getAttribute("href") == cheminComplet || (chemin + listeDesLiens[i].getAttribute("href")) == cheminComplet) {
				// on modifie le style du lien actif
				listeDesLiens[i].style.color = "#cc0000";

				// on sort de la boucle
				break;
			}
		}
	}
}

Les beaux chemins ne mènent pas loin (proverbe chinois)

Parmi les problèmes à gérer, il faut noter que Firefox diffère d'Opera ou d'Internet Explorer sur un point important de notre script. Au moment de demander le contenu de l'attribut href des balises <a>, Firefox nous retourne le contenu exact, à savoir "produits.php" par exemple, tandis que les 2 autres nous retournent "http://www.monserveur.com/monRepertoire/produits.php". Au moment de comparer le lien avec le nom de la page en cours, il faut donc faire les deux tests, ce qui implique d'avoir retenu au préalable deux variables : le chemin (http://www.monserveur.com/monRepertoire/) et le chemin complet (http://www.monserveur.com/monRepertoire/produits.php).

Un beau livre, c'est celui qui sème à foison les points d'interrogation (Cocteau)

Par ailleurs, il faut s'assurer lorsque nous manipulons l'URL de la page que celle-ci ne comprenne page un paramètre qui nous compliquerait la vie (mapage.php?monparametre=mavaleur). Ce qui nous intéresse c'est le chemin du fichier, pas le paramètre. On teste donc si l'URL comprend une query string et on la supprime.


if(document.location.search) {
	cheminComplet = document.location.href;
	cheminCompletSansQueryString = cheminComplet.split(document.location.search);
	cheminComplet = cheminCompletSansQueryString[0];
}

L'arbre suit sa racine (proverbe berbère)

Autre souci, si on se trouve à la racine d'un répertoire (http://www.monserveur.com/monRepertoire/), c'est la page par défaut qui sera appelée, index.htm, index.html, index.php, index.asp, etc. Pour autant, document.location.href ne nous retournera toujours que http://www.monserveur.com/monRepertoire/, sans plus de précision. Empiriquement, on déterminera donc dans notre cas précis qu'utilisant PHP, c'est la page index.php qui sera appelée si on se trouve dans ce cas de figure.


cheminCompletDecoupe = cheminComplet.split("/");
if (cheminCompletDecoupe[cheminCompletDecoupe.length-1] == "") {
	chemin = cheminComplet;
	cheminComplet += "index.php";
} else {
	chemin = cheminCompletDecoupe.splice(0,cheminCompletDecoupe.length-1) 
	chemin = chemin.join("/");
	chemin += "/";
}

Comme d'habitude ce code est fait rapidement et sans doute sujet à discussion. Les commentaires sont donc les bienvenus !

#javascript