使用 Trac 和 WSGI 时如何在 Genshi 模板中获取远程用户代理?

发布于 2024-08-13 09:34:59 字数 446 浏览 5 评论 0原文

我正在尝试对 Trac 项目管理网站进行一些定制,但遇到了一个有趣的问题。该项目有一组 SVG 和 PNG 图像。 SVG 图像具有许多优点,包括多个超链接和较小的传输尺寸,而 PNG 较大且只能链接到单个文档。

我意识到可以在页面加载后使用 jQuery 嗅探出用户代理,并将 PNG 替换为图像的 SVG 版本,但这会导致 PNG 被发送到所有客户端。我还可以让 Genshi 将所有客户端的 PNG 替换为 SVG,然后使用 jQuery 将 PNG 放回去,但会出现同样的问题。我可以使用 jQuery 为所有客户端插入适当的图像,但是要求客户端执行服务器应该执行的操作似乎很愚蠢。

有没有办法可以获取 Genshi 模板内的浏览器信息?这比仅仅调用环境变量要困难一些,因为我正在使用 WSGI 运行 Trac。我查看了 repr(locals()) 的输出,但没有看到任何看起来可以解决我的问题的内容。我还想避免修改 Trac 源代码。

I'm trying to do some customization of a Trac project management website and have run into an interesting problem. The project has a set of images that are both SVG and PNG. The SVG images have numerous advantages including multiple hyperlinks and a smaller transmitted size against PNG which is bigger and can only link to a single document.

I realize that it is possible to use jQuery to sniff out the user agent after the page has been loaded and replace the PNG with the SVG version of the image, but this results in the PNG being sent to all clients. I also can have Genshi replace the PNG with SVG for all clients and then use jQuery to put the PNG back, but the same problem results. I could use jQuery to insert the appropriate images for all clients, but that just seems silly to require the client to do what the server should.

Is there a way I can get browser information inside of a Genshi template? It's a little more difficult than just calling for environment variables because of the fact that I'm running Trac using WSGI. I've looked through the output of repr(locals()) and didn't see anything that looked like it solved my problem. I'd also like to avoid modifying the Trac source code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你丑哭了我 2024-08-20 09:34:59
user_agent = environ.get('HTTP_USER_AGENT', None)

或者,如果 environ 包含在某种 Request 对象中:

user_agent = request.user_agent

顺便说一句,您可能应该查看 HTTP_ACCEPT 标头,而不是 HTTP_USER_AGENT code> 找出应该发送什么表示。

user_agent = environ.get('HTTP_USER_AGENT', None)

Or if environ is wrapped in some sort of Request object:

user_agent = request.user_agent

btw, You should probably look at HTTP_ACCEPT header instead of HTTP_USER_AGENT to find out what representation should be sent.

猫九 2024-08-20 09:34:59

好的,所以我对这个问题做了一些挖掘,不是通过 grep 源代码,而是通过编写一个自定义 Genshi 处理程序来吐出局部变量中每个元素的递归 repr() (在提供的帮助下)通过上一个问题解决了如何打印范围内的所有变量)。我最初错过了 req 对象。看起来就像使用 req.environ['HTTP_USER_AGENT'] 一样简单。问题首先在于找到 req 对象。通过查找源代码,我仍然无法准确找到模板实例化的位置,因此事实证明这比补丁更容易、更好。

为了完整起见,下面是我用来替换仅适用于较新版本的基于 Gecko 的浏览器的徽标的 Genshi 模板。它有点老套,可能不是最理想的,但它可以工作,并且不会将 SVG 发送到撒谎并说它们“像 Gecko”但无法正确渲染 SVG 的浏览器 - 是的,我正在看你的 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] > 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>

Okay, so I did some digging on the issue, not by grepping through the source code, but by writing a custom Genshi handler that spit out the recursive repr() of every element in locals (with help provided by a previous question that addressed how to print out all variables in scope). I had originally missed the req object. It looks like it's as simple as using req.environ['HTTP_USER_AGENT']. The problem was in finding the req object in the first place. Grepping through the source code I still can't find exactly where the templates are instantiated, so this proves to be much easier and better than a patch.

For completeness, here's the bit of Genshi template I used to replace the logo only for newer versions of Gecko based browsers. It's a little hacky and probably suboptimal, but it works and it doesn't send SVG to browsers that lie and say they're "like Gecko" but can't render SVG properly -- yes, I'm looking at you 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] > 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文