The 2008-05-08 at 19:08 by Loïc d'Anterroches filed under Pluf - Framework en PHP5.
Mes expériences avec le système de traduction de Pluf m’ont fait toucher à une en-tête (header) renvoyée par le serveur. Cet en-tête est Vary. Cet en-tête permet d’informer les navigateurs/agents ainsi que les proxy/caches que le contenu d’une page varie en fonction des en-têtes émis par l’agent faisant la requête.
Par exemple, mon navigateur, Firefox, envoie cela comme information quand il faut une requête :
Accept: text/xml,application/xml,application/xhtml+xml,
text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en,fr;q=0.7,en-us;q=0.3
Cela veut dire, j’accepte du contenu dans différents formats, avec la priorité au format text/xml, puis application/xml, … et à la find image/png et enfin */* tout ce qui reste. Le navigateur accepte aussi le contenu en Anglais, puis Français et Anglais américain. Vous noterez pour certains cas la présence d’un paramêtre q avec une valeur. Ce paramêtre q, comme qualité, avec les langues s’explique de la façon suivante :
en,fr;q=0.7,en-us;q=0.3 correspond en étendu à en;q=1,fr;q=0.7,en-us;q=0.3
Maintenant supposons que vous puissiez accéder au site http://example.com/mon_sujet/ et que ce dernier dispose de 3 versions, une en anglais, une en français et une en américain. Le serveur va maintenant devoir choisir quelle page retourner. Comment choisir ?
Il faut d’abord attribuer une valeur aux trois versions. La valeur correspondera par exemple à la quantité d’information disponible. On va dire que par exemple, la page en Anglais à une qualité de 0.5, la page française de 0.9 et la page américaine de 1.0.
Le résultat du calcul pour chaque langue est le suivant :
C’est donc la page française avec le score le plus haut qui sera retournée. Maintenant, c’est à vous de donner en interne un score pour chaque version de vos pages… en pratique les personnes donnent un score de 1 pour chaque version et donc retourne dans notre cas la version anglaise.
Vous pouvez lire un peu plus sur ces en-tête ici : RFC 2616, Header Field Definitions.
Donc maintenant, vous comprenez que la page http://example.com/mon_sujet/ ne va pas toujours être la même et que le contenu varie en fait par rapport à l’en-tête Accept-Language. Si vous avez maintenant un système de cache naïf, qui stocke une version par URL, cela ne marche pas, car finalement une seule des 3 versions va être mise en cache… problème !
C’est là que l’en-tête Vary du serveur intervient. Cet en-tête dit au système de mise en cache, attention, le contenu de cette page varie en fonction de certaines caractéristiques de la requête. C’est pourquoi on renvoie l’en-tête suivant :
Vary: accept-language
Si vous renvoyez une page qui est en xml ou html en fonction de la requête, vous pourriez mettre :
Vary: accept-language, accept
Il faut donc dans Pluf un moyen élégant de mettre à jour cet en-tête. Je n’ai trouvé qu’une solution pour le moment, mettre dans l’objet requête l’information de la manière suivante :
$request->response_vary_on = 'accept';
Pourquoi sur la requête et pas ajouter manuellement dans la réponse ? Vous pouvez le faire, mais souvent, on n’a pas accès à l’objet réponse. En effet, une vue typiquement ce termine par l’appel suivant :
function mavue($request, $match)
{
.....
return Pluf_Shortcuts_RenderToResponse('mongabarit.html',
array('param1' => $toto, ...));
}
Comme vous ne touchez pas à l’objet réponse, il faut trouver une autre solution élégante. Et comme l’objet $request est disponible à tous les niveaux du dispatcher, j’ai donc choisi cette option :
function mavue($request, $match)
{
.....
$request->response_vary_on = 'accept';
return Pluf_Shortcuts_RenderToResponse('mongabarit.html',
array('param1' => $toto, ...));
}
Le problème est que cela fait une condition if supplémentaire pour toutes les vues, que l’en-tête Vary soit utilisé ou non. Cela pose donc une question de performance. Je vais voir si je trouver une méthode plus élégante.
Comments from readers