2009-12-06 17 views
1

J'essaye de faire une certaine personnalisation d'un site Web de gestion de projet de Trac et ai rencontré un problème intéressant. Le projet a un ensemble d'images qui sont à la fois SVG et PNG. Les images SVG ont de nombreux avantages, y compris de multiples liens hypertexte et une plus petite taille transmise par rapport à PNG qui est plus grande et ne peut que lier à un seul document.Comment obtenir l'agent utilisateur distant dans un modèle Genshi lors de l'utilisation de Trac et de WSGI?

Je me rends compte qu'il est possible d'utiliser jQuery pour détecter l'agent utilisateur après le chargement de la page et remplacer le fichier PNG par la version SVG de l'image, mais le PNG est envoyé à tous les clients. Je peux aussi avoir Genshi remplacer le PNG avec SVG pour tous les clients, puis utiliser jQuery pour remettre le PNG, mais le même problème se produit. Je pourrais utiliser jQuery pour insérer les images appropriées pour tous les clients, mais cela semble stupide d'exiger que le client fasse ce que le serveur devrait faire.

Y a-t-il un moyen d'obtenir des informations de navigateur à l'intérieur d'un modèle Genshi? C'est un peu plus difficile que de simplement appeler des variables d'environnement parce que j'utilise Trac avec WSGI. J'ai regardé à travers la sortie de repr(locals()) et n'a pas vu quelque chose qui semblait avoir résolu mon problème. Je voudrais également éviter de modifier le code source Trac.

Répondre

0

Ok, donc je fait quelques recherches sur la question, et non par grep à travers le code source, mais en écrivant un gestionnaire Genshi personnalisé qui crachent le repr() récursive de chaque élément dans la population locale (avec l'aide fournie par un previous question qui abordait comment imprimer toutes les variables dans la portée). J'avais initialement manqué l'objet req. Il semble que c'est aussi simple que d'utiliser req.environ['HTTP_USER_AGENT']. Le problème était de trouver l'objet req en premier lieu. En parcourant le code source, je n'arrive toujours pas à trouver exactement où les templates sont instanciés, donc cela s'avère beaucoup plus facile et meilleur qu'un patch.

Pour être complet, voici le modèle de Genshi que j'ai utilisé pour remplacer le logo uniquement pour les nouvelles versions de navigateurs basés sur Gecko. C'est un peu hacky et probablement sous-optimal, mais cela fonctionne et il n'envoie pas SVG aux navigateurs qui mentent et disent qu'ils sont "comme Gecko" mais ne peuvent pas rendre SVG correctement - oui, je regarde Webkit.

<py:if test="'Gecko/' in req.environ['HTTP_USER_AGENT'] and [int(x.split('/')[1]) for x in req.environ['HTTP_USER_AGENT'].split() if x.startswith('Gecko')][0] &gt; 20080101"> 
    <div py:match="div[@id='header']"> 
    <object type="image/svg+xml" id="svgLogo" data="${href.chrome('site/logo.svg')}" style="width=${chrome['logo']['width']}px; height=${chrome['logo']['height']}px;"></object> 
    </div> 
</py:if> 
0
user_agent = environ.get('HTTP_USER_AGENT', None) 

Ou si environ est enveloppé dans une sorte de Request objet:

user_agent = request.user_agent 

BTW, vous devriez probablement à en-tête HTTP_ACCEPT au lieu de HTTP_USER_AGENT pour savoir quelle représentation doit être envoyé.

+0

Eh oui, dans un environnement de CGI ou à l'intérieur d'une application WSGI que je pouvais faire ceux-ci, mais 'environ' est vide à l'intérieur Genshi et je ne peux pas savoir où/si l'objet de la demande est transmise à Genshi de Trac/WSGI. En outre, HTTP_ACCEPT est probablement un non aller parce que certains navigateurs mentent et disent qu'ils peuvent accepter SVG mais le font mal - je vous regarde Chrome! Ce qui donne avec les boîtes blanches géantes pour les arrière-plans‽ – Pridkett

+0

@Pridkett: grep votre source trac pour le nom du modèle et passez les variables requises dans le code de rendu. – jfs

+0

J'essaie d'éviter de changer le code source Trac. Je suis allé trop souvent dans ce sens et je ne veux pas vraiment m'inquiéter de la gestion d'une variété de patchs - même très simples. – Pridkett