2009-12-06 43 views
1

我試圖做一些Trac項目管理網站的自定義,並遇到了一個有趣的問題。該項目有一組SVG和PNG圖像。 SVG圖像具有許多優點,包括多個超鏈接和較小的傳輸大小,對PNG較大,只能鏈接到單個文檔。使用Trac和WSGI時,如何獲取Genshi模板中的遠程用戶代理?

我意識到,可以使用jQuery在頁面加載後嗅探用戶代理,並用圖像的SVG版本替換PNG,但這會導致PNG被髮送到所有客戶端。我也可以讓Genshi用所有客戶端的SVG替換PNG,然後使用jQuery將PNG放回,但同樣的問題會導致。我可以使用jQuery爲所有客戶端插入適當的圖像,但這只是要求客戶端執行服務器應該做的事情似乎很愚蠢。

有沒有一種方法可以在Genshi模板中獲取瀏覽器信息?這比調用環境變量更困難,因爲我正在使用WSGI運行Trac。我查看了repr(locals())的輸出,沒有看到任何看起來像解決了我的問題的東西。我也想避免修改Trac源代碼。

回答

0

好了,所以我沒有在這個問題上的一些挖,不通過源代碼grepping,而是通過編寫自定義元史處理程序,在當地人吐出的每一個元素的遞歸repr()(由一個previous question是解決提供幫助如何打印範圍內的所有變量)。我最初錯過了req這個對象。它看起來像使用req.environ['HTTP_USER_AGENT']一樣簡單。問題在於首先找到req對象。仔細查看源代碼我仍然無法準確找到模板實例化的位置,所以證明比補丁更容易和更好。

爲了完整起見,下面是Genshi模板的一小部分,我用它來代替僅適用於Gecko瀏覽器新版本的logo。這有點不好,可能不是最理想的,但它有效,它不會將SVG發送給說謊的瀏覽器,並說他們「像壁虎」,但無法正確渲染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] &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) 

或者,如果environ被包裹在某種Request對象:

user_agent = request.user_agent 

順便說一句,你或許應該看看HTTP_ACCEPT頭,而不是HTTP_USER_AGENT找出代表性應予以發送。

+0

是啊,在CGI環境或WSGI的應用程序,我可以做到這些的內部,但是'environ'是空的內部元史,我想不通,如果請求對象從Trac系統傳遞到元史其中//WSGI。此外,HTTP_ACCEPT可能是不行的,因爲一些瀏覽器撒謊,並說他們可以接受SVG,但做得不好 - 我看着你鉻!什麼使用巨大的背景白盒子 – Pridkett 2009-12-06 15:24:38

+0

@Pridkett:grep你的模板名稱的trac源代碼,並在渲染代碼中傳遞必要的變量。 – jfs 2009-12-06 16:08:01

+0

我試圖避免更改Trac源代碼。我已經走了這條路,太多次了,並不想擔心管理各種各樣的修補程序 - 即使是非常簡單的修補程序。 – Pridkett 2009-12-07 14:11:12

相關問題