DDD開發框架ABP之本地化/多語言支持

      本地化(Localization)也就是多語言功能,藉此用戶可以選擇他的母語或熟悉的語言來使用系統,這顯然很是有利於軟件系統推向國際化。一個應用程序的UI界面至少有一種語言,DDD開發框架ABP就提供了一個彈性的多語言框架,能夠簡化咱們在多語言方面的開發時間。利用ABP完整實現多語言只須要簡單地完成三個步驟:創建資源、配置資源以及使用資源。javascript

1、創建資源

      本地化的內容主要是文本字符串,ABP提供三種方式存儲本地化資源的方式,分別是ASP.NET自帶的資源文件、XML文件以及自定義的資源獲取方式。ABP是分模塊的,每一個模塊能夠定義獨立的本地化來源,每一個本地化資源必須有一個惟一的名稱。html

XML文件
      以XML文件存儲本地化資源時,XML文件必須是unicode(UTF-8),文件格式以下:前端

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <localizationDictionary culture="en">
 3     <texts>
 4        <text name="ZeroSystem" value="Zero System" />
 5        <text name="TaskList" value="Task List" />
 6        <text name="NewTask" value="New Task" />
 7        <text name="Xtasks" value="{0} tasks" />
 8        <text name="CompletedTasks" value="Completed tasks" />
 9        <text name="EmailWelcomeMessage">Hi,
10         Welcome to Simple Task System! This is a sample
11         email content.</text>
12     </texts>
13 </localizationDictionary>

      上面代碼中,文件開頭的culture="en"代表這個XML文件用於英語環境。text節點很簡單地使用了name/value,name是一個代碼,是惟一的,value是其在對應的語言下先是給用戶的信息,能夠是一個詞,也能夠是一段話。java

      咱們應該爲每種語言建立一個XML文件,好比:數據庫

ZeroSystem
    ZeroSystem-zh-CN.xml
    ZeroSytem-zh-TW.xml
    ZeroSytem.xml

      上面的文件列表中,Zero是資源的名稱,沒有帶語言代碼的XML文件用於默認語言。ABP會自動根據當前系統語言Thread.CurrentThread.CurrentUICulture從相應資源文件中獲取文本信息,若是該語言沒有,則自動從默認語言的XML文件中搜索。值得一提的是,在大系統中,咱們能夠考慮根據模塊分類創建多個資源文件以方便管理,只須要創建多個不一樣名稱的文件夾和一系列的資源文件便可。服務器

RESX 資源文件app

      本地化信息也能夠存儲在.NET資源文件中,咱們能夠爲每一種語言創建一個資源文件。.NET資源文件資源文件以.resx爲後綴,也是name/value鍵值對。框架

       

       .NET資源文件中不帶語言後綴的文件用於默認語言。其餘方面與XML資源文件方式大同小異,本文再也不作詳細說明。ide

自定義資源ui

      ABP的本地化框架除了支持XML外,也提供了自定義的資源,能夠用其餘方式來保存文本,好比數據庫。咱們能夠直接實現ILocalization接口,或者從DictionaryBasedLocalizationSource類繼承會更加容易些。下一篇將會講述如何存儲資源文件於數據庫中。

 

2、配置資源

 

      首先,咱們須要聲明系統支持哪幾種語言。這能夠在模塊的PreInitialize事件中完成配置:

 

1 public override void PreInitialize()
2 { 3 Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "us.png", true)); 4 Configuration.Localization.Languages.Add(new LanguageInfo("zh-TW", "繁體中文", "tw.png")); 5 Configuration.Localization.Languages.Add(new LanguageInfo("zh-CN", "簡體中文", "cn.png")); 6 }

 

      上面代碼中,配置了三種語言,英語爲默認語言。LanguageInfo參數包括代碼,名稱,圖標和是否默認語言。

註冊XML資源

      XML資源文件在系統發佈時,有兩種存儲方式,一種是文件系統,一種是嵌入到程序集。文件系統存儲更靈活,它能夠在系統運行中動態變動;嵌入到程序集的方式使用更方便,但編譯後就不能更改。不一樣方式都須要在初始化是註冊到配置中。
      文件系統方式註冊時指定文件的地址目錄:

1 Configuration.Localization.Sources.Add(
2     new DictionaryBasedLocalizationSource(
3         "ZeroSystem",
4         new XmlFileLocalizationDictionaryProvider(
5            HttpContext.Current.Server.MapPath("~/Localization/Zero")
6         )
7     )
8 );

      預編譯嵌入程序集的方式須要標記全部XML文件爲「嵌入資源」(選擇XML文件,打開屬性窗口,修改「Build Action」爲「Embedded Resource」)。註冊代碼以下:

1 Configuration.Localization.Sources.Add(
2      new DictionaryBasedLocalizationSource(
3          "ZeroSystem",
4          new XmlEmbeddedFileLocalizationDictionaryProvider(
5              Assembly.GetExecutingAssembly(),
6              "ZeroSystem.Web.Localization.Sources" )
7     )
8 );

      注意:預編譯嵌入程序集的方式時,XML文件不要使用「.」做爲分隔符,建議使用「-」,不然可能會出現找不到文件的問題。好比MySource.en.xml 改成 MySource-en.XML。

註冊RESX資源文件

      .NET資源文件在註冊到配置時略有差別:

1 Configuration.Localization.Sources.Add(
2     new ResourceFileLocalizationSource( "ZeroSystem",
3        MyTexts.ResourceManager ));

      其中ZeroSystem是資源文件的惟一名稱,MyTexts.ResourceManager是引用資源文件的命名空間。

3、使用資源

服務器端使用

      在服務器端使用多語言,咱們只須要注入ILocalizationManager接口,而後調用其GetString方法,第一個參數爲資源來源的名稱,第二個參數爲資源字符串的名稱。

var s1 = _localizationManager.GetString("ZeroSystem", "NewTask");

      GetString方法是基於當前線程的UI Culture設置從資源來源中取得字符串,若是沒有找到,則從默認語言中取得字符串。

      爲了不重複,能夠先創建對象存儲資源來源,後面調用GetString方法時只須要傳遞一個參數:

1 var source = _localizationManager.GetSource("ZeroSystem");
2 var s1 = source.GetString("NewTask");

      注意:若是咱們在特定狀況下(好比靜態的上下文中)沒法注入ILocalizationManager接口,咱們也能夠直接使用靜態類LocalizationHelper。

L方法

  在應用服務層(Application Service)、MVC Controller,或者Razor View中,ABP還定義了一個更簡單的方法L,來取得本地語言的字符串。

1 public class HomeController : SimpleTaskSystemControllerBase
2 {
3     public ActionResult Index()
4     {
5         var helloWorldText = L("HelloWorld");
6         return View();
7     }
8 }

Javascript端

      ABP一樣支持的Javascript裏面使用多語言。爲了實現這個能力,咱們首先須要引入Javascript文件:

<script src="/AbpScripts/GetScripts" type="text/javascript"></script>

      ABP自動生成了取得本地化資源的Javascript方法,因此咱們能夠簡單地取得本地化文本以下:

var s1 = abp.localization.localize('NewTask', 'ZeroSystem');

      本地化文本一樣能夠帶參數,好比「 Role {0} will be deleted」,經過下面的方法能夠獲得「Role Admin will be deleted」。

1 var source = abp.localization.getSource('ZeroSystem');
2 source('RoleDeleteWarningMessage', 'Admin');

多語言切換(基於AngularJS

      首先須要創建一個Angular控制器,好比在header.js文件中,註明語言變量:

1 angular.module('app').controller(controllerId, [
2         '$scope', '$state', function ($scope, $state) {
3             var vm = this;
4             vm.languages = abp.localization.languages;
5             vm.currentLanguage = abp.localization.currentLanguage;
6       }
7 ]);

      其中abp.localization.languages存儲了語言的清單,abp.localization.currentLanguage存儲了當前語言。
      而後在UI界面添加語言選項,以Razor+AngularJS爲例,在header.cshtml文件中添加以下代碼:

 1 <li class="dropdown dropdown-language">
 2        <a href="javascript:;" data-toggle="dropdown" class="dropdown-toggle" data-hover="dropdown" data-close-others="true">
 3              <img alt="" src="/assets/global/img/flags/{{vm.currentLanguage.icon}}.png" />
 4              <span>{{vm.currentLanguage.displayName}}</span>
 5               <i class="fa fa-angle-down"></i>
 6       </a>
 7       <ul class="dropdown-menu dropdown-menu-default">
 8              <li ng-repeat="language in vm.languages" ng-hide="vm.currentLanguage.name == language.name">
 9                    <a href="~/AbpLocalization/ChangeCulture?cultureName={{language.name}}">
10                           <img alt="" src="/assets/global/img/flags/{{language.icon}}.png" />
11                           <span> {{language.displayName}}</span>
12                    </a>
13                </li>
14         </ul>
15 </li>

      ABP定義的語言對象包含了三個屬性,分別是:
      name:語言名稱,好比en, cn等
      displayName:顯示的語言文本,好比:英語、日語、簡體中文、繁體中文等。
      icon:顯示的語言圖標名稱,ABP推薦的是國旗圖標
      語言切換時,鏈接至ABP內置的一個MVC控制器,控制器的名稱爲:AbpLocalizationController,控制器定義了一個Action方法ChangeCulture。該控制器完整代碼以下:

 1 namespace Abp.Web.Mvc.Controllers.Localization
 2 {
 3     public class AbpLocalizationController : AbpController
 4     {
 5         [DisableAuditing]
 6         public virtual ActionResult ChangeCulture(string cultureName, string returnUrl = "")
 7         {
 8             if (!GlobalizationHelper.IsValidCultureCode(cultureName))
 9             {
10                 throw new AbpException("Unknown language: " + cultureName + ". It must be a valid culture!");
11             }
12 
13             Response.Cookies.Add(new HttpCookie("Abp.Localization.CultureName", cultureName) { Expires = Clock.Now.AddYears(2) });
14 
15             if (Request.IsAjaxRequest())
16             {
17                 return Json(new MvcAjaxResponse(), JsonRequestBehavior.AllowGet);
18             }
19 
20             if (!string.IsNullOrWhiteSpace(returnUrl))
21             {
22                 return Redirect(returnUrl);
23             }
24 
25             return Redirect(Request.ApplicationPath);
26         }
27     }
28 }

總結

      DDD開發框架ABP就提供了一個彈性的多語言框架,能夠靈活的採用XML文件、.NET資源文件或數據庫的方式存儲多語言資源。ABP利用依賴注入提供了快捷的獲取資源的方法,在前端Javascript也封裝了支持多語言的方法。

      具體如何實如今數據庫中存儲多語言資源,在下一篇博客《DDD開發框架ABP之本地化資源的數據庫存儲擴展》中有詳細的實現過程和代碼。固然一般說的多語言指的是軟件系統的菜單、欄位、說明、幫助等開發階段預先定義的內容,這些內容是由開發人員設定,在不一樣語言環境下不會由於用戶的不一樣而存在差別。還有一種關鍵數據欄位的多語言,好比用戶姓名、角色名稱、供應商名稱等,或許用戶也但願系統可以具備多語言能力,ABP框架可否支持,該如何實現呢?

相關文章
相關標籤/搜索