程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 基於Gettext的asp.net網站多語言解決方案

基於Gettext的asp.net網站多語言解決方案

編輯:.NET實例教程

很久以前就想寫這篇blog,系統的介紹一下偶是如何使用Gettext給blogwind做多語言界面的……

很不喜歡.Net內置的多語言解決方案……因為,它使用xml……編輯XML是一件很痛苦的事情……我也不想給每個頁面弄一堆resouce文件……光看著這些資源文件我就很暈……

偶是從Django裡面知道有Gettext這套在開源軟件中廣為使用的程序多語言解決方案的……

最喜歡它的地方是它默認直接使用英文原文作為字符串的鍵值……而不是像.net默認的那樣,給所有的字符串加上一個編號……而當翻譯不存在的時候,.Net是會拋出異常,而Gettext是會返回原文……這樣子,我可以部分給網站制作一個語言版本……而不需要一步到位……

--------------------------------------------

Gettext的翻譯文件為.po文件……其實就是純文本文件……其內容類似:

#: D:/web/blogwind/default.ASPx:87
msgid "Loading..."
msgstr "讀取中..."

第一行代表偶需要翻譯的字符串在程序中的位置……msgid則是需要翻譯的字符……msgstr則是翻譯的結果……很簡單……

偶在做網站的時候,把所有需要翻譯的字符串都使用一個函數包涵起來……比方說:
    ph.g("編寫網志")

然後,自己寫了個小Python程序去搜索偶網頁程序中所有的 ph.g("XXXXX"),並生成/更新現有的po文件……

可以用的PoEdit來編輯po文件……非常方便……因為注釋中可以放待翻譯的字符串在源程序中的位置,偶翻譯的時候還隨時可以查閱源程序,看看究竟是在什麼地方用到這個詞句……以保證遇到一詞多譯時能夠選擇正確的一個翻譯……

編輯完po文件之後,便需要使用Gettext包中msgfmt這個小程序把po文件直接編譯為.Net使用的資源dll……命令類似:

msgfmt --csharp -r blogwind -l zh-CHS -d . blogwind.po

--csharp 是指定輸出為.net的dll……呃……需要指定這點,是因為它還可以輸出為Java / tcl /qt有幾個.net resource文件等格式……對於.Net的支持是後來新加的……如果報錯,確定你使用的是0.13.1版或者更新的Gettext庫……

-r blogwind 是指dll的資源名稱為blogwind

-l zh-CHS 則是語系

最後的則是待編譯的po文件名了……


----------------------------------------

Gettext有C#的"wrapper"……源碼在GnuWin32裡面就有……它這個wrapper……wrap的是.Net的System.Resources類……使它符合Gettext找不到翻譯便返回原文的做法而已……順便再搞定一下資源緩存之類的……一共也就幾百行代碼……

不過,它這個版本似乎是為桌面程序設計的……要在網頁中使用,還需要做點小修改……它讀取那些msgfmt生成的dll時,使用的是:Assembly.LoadFrom(.....)

這意味著它每次只是讀一個dll……對於單一用戶的桌面程序來說,每次使用一種語言是正常……可是,對於網站來說,偶需要同時提供不用的語言界面給不同的用戶……所以……需要改成Assembly.LoadAssembly(.....)


------------------------------------------

嗯,到了最後,便是調用了……注意,下面出現的代碼都是偶自己寫的……大家完全沒有必要照偶的方式做……

Imports GNU.Gettext

Public Class lh
  'lh = language Helper
  Public Shared catalog As GettextResourceManager

  Public Shared Sub init(ByVal name As String, ByVal dictpath As String)
    catalog = New GettextResourceManager(name, dictpath)
  End Sub
End Class

在Global.asax的Application Start中調用一下:
        lh.initcate("blogwind", Server.MapPath("langs"))

恩,這樣子,它便會去網站根目錄下langs目錄尋找它需要的各種語言dll了……當然,blogwind這個類名以及langs這個目錄可以隨意改成別的……

最先偶寫到的那個ph.g(..)函數其實是:
  Public Function g(ByVal Word As String) As String
    Dim cu As New System.Globalization.CultureInfo(langs.getLangString(Me.lang))
    Return lh.catalog.GetString(Word, cu)
  End Function

ph是pagehelper……呃……我知道,我起類名很規范……總之,我在pagehelper裡面還自己保存了當前浏覽者的語言信息放在langs / pagehelper裡面……通過:
    Dim cu As New System.Globalization.CultureInfo(langs.getLangString(Me.lang))
來獲得相應的CultureInfo,再傳給Gettext……

比方說,語系是zh-CHS,待尋找翻譯的Word是“編寫網志”,Gettext便會去webroot/langs/zh-CHS目錄中尋找blogwind.resources.dll這文件……找到了,便Load它,再尋找"編寫網志"等等……

因為這些翻譯的dll是動態讀取的……

其實完全可以做到讓程序在app_start中自動去遍歷langs中的子目錄,看看都有哪些語系……然後自動生成一個菜單在網頁中供用戶選擇……以後添加語言,其實就簡單到往這個目錄中建立目錄扔dll了……程序本身,絲毫不需要做任何修改……


-----------------

當然,上面說的,僅僅是最簡單的字符串翻譯……網頁中還有圖片……語言相關的CSS等等細節……而且,實際上,我在使用Gettext的時候還自己寫了個小Python程序(幾十行的樣子)去生成/維護po文件……若po文件不能自動生成、維護更新的話,管理起來是很麻煩的……

上面的說明也是非常簡略的……僅僅只是說明要給ASP.Net網站提供多語言界面……除了使用官方鼓吹的資源文件方式外,還可以有別的選擇……而對於Gettext這個選擇,偶覺得更加優雅些而已…… www.blogwind.com 的多語言界面,便是使用上述的方式實現的……

至於哪裡下載Gettext以及msgfmt等工具,wrapper中的那行修改具體是在哪裡等問題,就請不要來問偶了……

這裡,有偶修改重新編譯過後的版本:
http://www.cnblogs.com/Files/wuvist/GetText.zip

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved