天天看點

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

 前言:最近,新的平台還沒有開發完成,原來的老項目又提出了新的需求:系統國際化。如果是前後端完全分離的開發模式,要做國際化,真的太簡單了,有現成的解決方案,基于Node建構的時下熱門的任何一種技術選型都有成熟的方案,比如:

<code>vue</code> + <code>vue-i18n</code>

<code>angular</code> + <code>angular-translate</code>

<code>react</code> + <code>react-intl</code>

但現在的情況是老的項目并沒有使用這類架構。說起國際化,部落客幾年前就做過,在MVC裡面實作國際化有通用的解決方案,主要就是通過資源檔案的方式定義多語言。最初接到這個任務,并沒有太多顧慮,畢竟這種東西有很成熟的解決方案,實作起來難點不會很大。可當真正動起來手來去實作的時候發現一些問題,這裡先介紹下我們老平台的架構:MVC+WebApi,MVC項目負責頁面渲染,webapi負責資料接口,是一種很傳統的架構方式。國際化主要在MVC端去做就好了,可是由于MVC項目裡面使用了大量第三方bootstrap元件,幾乎95%的元件都是通過js去實作的,比如bootstrapTable,比如bootstrap-select,比如bootstrap-fileinput。如果按照傳統的方式,僅僅在MVC裡面去實作國際化,那麼大量的js代碼裡面的中文沒法統一處理,并且很多第三方元件有自己的本地化local檔案,和後端的國際化很難統一處理;可能有人又說,那就前後端分開國際化呗,這種方案部落客真的想過,但是想到要維護兩套資源檔案,果斷放棄。最後還是決定直接維護一套,做前端國際化好了。于是在網上搜尋基于jquery的國際化,千篇一律,幾乎都說的是jquery + jquery.i18n.properties這種方案,既然大家都這麼選型,那部落客也按照這種思路去做好了。

在實作的過程中,有很多值得注意和分享的東西,在此寫一個填坑筆記,希望對大家有幫助!接下來,部落客就一步一步帶領大家解決這個過程中遇到的一些坑,如果有這個需求的童鞋可以關注下,可能這些問題你也會遇到。

本文原創位址:http://www.cnblogs.com/landeanfen/p/7581609.html

關于jquery.i18n.properties的使用,網上資料很多,比較完整的使用可以參考 這篇 ,有比較詳細的使用說明。這裡部落客簡單概述下過程。

先在你的項目檔案裡面添加如下目錄結構

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

首先頁面引用的js檔案如下

其中jquery-1.9.1.min.js和jquery.i18n.properties.js檔案是開源元件,直接去網上找到即可

jquery.i18n.properties.js 

jquery.js

第三個檔案language.extensions.js是我們自定義的js檔案,如果你将國際化的代碼直接寫在html頁面裡面,這個檔案就是不用的。

這裡直接引用上面示例文章裡面的代碼,首先需要一個切換中英文的标簽,比如是一個select

然後是一些檢視效果的html标簽

最後就是我們需要封裝的language.extensions.js檔案的内容了,裡面做了以下幾件事:

初始化頁面的時候去目前域的cookie裡面取目前浏覽器儲存語言的cookie,根據取到的目前語言版本去初始化國際化元件,然後初始化select元件的選中值

注冊select元件的change事件,根據目前選中的語言,更新cookie裡面的語言資訊,然後重新整理頁面。

這個檔案的内容這裡就不展示了,可以參考上面的使用示例文章

根據上面的目錄可以看出,我們打算将不同的語言的資源檔案放到不同語言的檔案夾裡面,這裡暫時不分檔案,所有的語言資源放到一個檔案common.properties裡面,比如内容如下:

en/common.properties

zh-CN/common.properties

貌似大功告成!當你down源碼直接在google浏覽器裡面運作的時候你會發現一個跨域的問題。

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

要求你在一種webServer裡面去通路.properties檔案,這個問題你隻需要使用任何一種webserver運作即可,比如IIS、Apache、Node的web伺服器等。部落客的代碼是在Visual Studio裡面跑的,是以是基于IIS的,當你把代碼搬到VS裡面跑的時候,第一個問題來了。

如果本文僅僅是上面的内容,是沒啥意義的。接下來才是本文要介紹的重點!

将上述代碼直接搬到VS裡面,運作的時候你會發現第一個問題:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

為什麼這裡會請求三個properties檔案?因為jquery.i18n.properties.js元件支援三種類型的命名方式,這點很多文章都有介紹,元件代碼運作的時候會去請求三種規則的properties檔案,隻要找到任何一種規則的檔案都可以讀取到裡面的内容。按照部落客上文給出的檔案目錄

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

根據這個目錄,那我們通過 http://localhost:12770/Content/i18n/zh-CN/common.properties 這個url應該能通路到zh-CN/common.properties這個檔案,可實際情況确實這樣:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

對于這種IIS報錯404的問題,C#程式員肯定是不陌生的,無非就兩個原因:

url不正确,這個目錄下面确實沒有找到這個資源檔案

檔案的類型iis預設不支援,直接拒絕請求

排除了第一個原因,那麼隻可能是第二個原因引起的了。那麼我們如何處理呢,在網上搜尋半天資料,找到一種解決方案:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

這樣确實能繞過IIS的檔案名驗證,但是改源碼不是一個好的解決方案,部落客有一千個理由來說明改源碼的弊端。這種方式肯定不是一個最好的解決方案,于是部落客決定另辟蹊徑。

還記得當初部落客學習less的時候,iis預設也是不支援.less檔案的,于是我們在web.config裡面加了如下一些配置:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

這絕對屬于同類型的問題,加這個配置是顯式告訴IIS,我們系統裡面某種字尾的檔案需要哪種Processer(處理器或處理元件)去處理,受此啟發,那麼我們這裡的.properties檔案的404問題是不是也可以通過此種方式解決?如果需要通過這種思路去解決,首要問題是需要找到.properties檔案的mimeType,部落客思考,既然是在js裡面調用這個.properties檔案,那麼我們是否可以使用JavaScript的處理機制來處理.properties檔案呢,考慮到上面那種将所有.properties替換成.js的處理方式,似乎.properties和.js有很多相似之處,于是我們加上如下一條配置:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

得到結果:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

試驗成功,就是這麼簡單。當然如果釋出到IIS,可能需要在IIS的MIME類型裡面添加.properties這種類型的映射。

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

好了,這個問題就這麼愉快的解決了。如果你的WebServer不是基于IIS的,可能沒有這個問題,但我想思路或許相通,供參考!

一般情況下,我們标簽裡面的内容如果要做國際化,需要使用 $('#id').text($.i18n.prop('proName')); 來給标簽指派,現在問題來了,我們開發一個界面,有很多地方都需要去做國際化,我們總不能這樣每一個頁面每一個标簽通過這種方式去指派吧,這樣工作量不是一點大,于是乎部落客想,有沒有一種比較好的通用的解決方案去給這些需要做國際化的标簽統一指派呢。html的data屬性似乎是一個不錯的選擇!它具有可讀性強、可維護性強、相容jquery的data()方法等優點。比如我們修改國際化元件的方法如下:

 通過data屬性擷取标簽,然後對每個标簽通過對應的data-i18n-屬性進行國際化指派即可,這裡暫時定義了三種類型data-i18n-placeholder、data-i18n-text、data-i18n-value的屬性,如果有其他需求,可以增加其他類型。

然後看下我們html頁面的使用

這樣不用寫一句标簽的指派代碼,即可對标簽進行國際化。

對于第三方元件,我們自定義的代碼裡面的中文要做國際化,我隻需要使用$.i18n.prop('key')即可,比如bootstrapTable:

直接使用

即可。這個解決思路很簡單,沒啥好說的,可是有一些第三方元件,自己有國際化的功能,初始化的時候需要指定國際化的類型,形如:

目前想到的解決方案,就是根據cookie裡面存儲的目前語言來顯式指派

如果是多種語言,這裡可以在前端自己去處理。

 上面介紹了第三方元件初始化時候指定國際化,除此之外,還有另外一種情況,就是很多元件有自己的本地化(關于國際化和本地化的差別,請自行谷歌)檔案,它的國際化是通過引用不同的本地化js檔案來實作的,比如部落客常用的bootstrapTable元件,它的目錄:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

還有其他元件也是這樣,比如:

前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”
前端系列——jquery.i18n.properties前端國際化解決方案“填坑日記”

那麼針對這種情況,我們的國際化該如何實作了,這裡部落客提供的思路是動态引用js,通過目前cookie裡面儲存的語言的類型來引用對應語言的js檔案,比如針對bootstrapTable,我們這樣去動态引用js

如果要想代碼寫得更加優雅,可以自己去實作前端的抽象工廠,這裡隻是提供一種實作思路。

排除了以上幾步的困難,我們的國際化在項目裡面基本就能正常運作起來了,至于WebApi裡面傳回消息的中文,如果你也想做國際化,我們可以通過将傳回消息封裝,統一傳回前端處理。本篇文章的“填坑方式”或許不是最好的,但至少給大家提供了一種實作思路,如果大家有更好的實作方式,歡迎留言交流。如果你覺得本文能夠幫助你,可以右邊随意 打賞 部落客。

本文原創出處:http://www.cnblogs.com/landeanfen/

歡迎各位轉載,但是未經作者本人同意,轉載文章之後必須在文章頁面明顯位置給出作者和原文連接配接,否則保留追究法律責任的權利