本地化(Localization)也就是多語言功能,藉此用戶可以選擇他的母語或熟悉的語言來使用系統,這顯然很是有利於軟件系統推向國際化。一個應用程序的UI界面至少有一種語言,DDD開發框架ABP就提供了一個彈性的多語言框架,能夠簡化咱們在多語言方面的開發時間。利用ABP完整實現多語言只須要簡單地完成三個步驟:創建資源、配置資源以及使用資源。javascript
本地化的內容主要是文本字符串,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類繼承會更加容易些。下一篇將會講述如何存儲資源文件於數據庫中。
首先,咱們須要聲明系統支持哪幾種語言。這能夠在模塊的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是引用資源文件的命名空間。
服務器端使用
在服務器端使用多語言,咱們只須要注入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框架可否支持,該如何實現呢?