本地化javascript
任何應用程序都會包含至少一種語言。許多的應用程序都包含多種語言。ABP提供了靈活的本地化系統。java
首要的事情是聲明支持哪一種語言。在模塊的PreInitialize方法中設置,以下所示:數據庫
Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flag-england", true)); Configuration.Localization.Languages.Add(new LanguageInfo("tr", "Türkçe", "famfamfam-flag-tr"));
在服務端,你能夠注入並使用ILocalizationManager。在客戶端,你可使用abp.Localization javascript API來獲取全部可用語言的列表及當前語言。famfamfam-flag-england(and tr)僅僅是一個CSS類,你能夠根據須要更改。而後你能夠在UI使用它時顯示相關的標誌。json
ABP模板使用這個系統給用戶展現一個能夠語言切換的組合框。能夠嘗試建立一個模板並參考源碼瞭解更多。瀏覽器
本地化文本能夠存儲在不一樣的源中。甚至,你能夠一個應用中使用多種源(若是你有多個模塊,每一個模塊能夠定義分離的本地化源,或者一個模塊定義多種源)。ILocalizationSource接口須要使用一個本地化源實現。而後,它就會自動註冊到ABP的本地化配置中。網絡
每個本地化源必須有一個惟一的源名稱。有以下預先定義的本地源類型。app
本地化文本能夠存儲在XML文件裏。XML文件的內如大體以下所示:
<?xml version="1.0" encoding="utf-8" ?> <localizationDictionary culture="en"> <texts> <text name="TaskSystem" value="Task System" /> <text name="TaskList" value="Task List" /> <text name="NewTask" value="New Task" /> <text name="Xtasks" value="{0} tasks" /> <text name="CompletedTasks" value="Completed tasks" /> <text name="EmailWelcomeMessage">Hi, Welcome to Simple Task System! This is a sample email content.</text> </texts> </localizationDictionary>
XML文件必須是unicode(utf-8)編碼。culture="en"聲明標示這個XML文件包含英文文本。對於文本節點,name屬性用來定義文本。你可使用value屬性或inner text(如最後一個)來設置本地化文本的值。咱們爲每個種語言建立一個單獨的XML文件,以下所示:
SimpleTaskSystem爲源名稱,SimpleTaskSystem.xml定義了默認的語言。當文本請求的時候,ABP從當前語言的XML文件中(使用Thread.CurrentThread.CurrentUICulture)獲取文本。若是它在當前語言中不存在,則從默認語言的XML文件中獲取。
XML文件能夠存儲在文件系統或嵌入到程序集中。
對於文件系統存儲的XMLs,咱們能夠按以下所示註冊一個XML本地化源:
Configuration.Localization.Sources.Add( new DictionaryBasedLocalizationSource( "SimpleTaskSystem", new XmlFileLocalizationDictionaryProvider( HttpContext.Current.Server.MapPath("~/Localization/SimpleTaskSystem") ) ) );
這在模塊的PreInitialize事件中完成(參見模塊系統瞭解更多)。ABP在指定目錄查找全部的XML文件並註冊爲本地化源。
對於嵌入XML文件,咱們須要標記本地的全部的XML文件爲嵌入的資源(選擇XML文件,打開屬性窗口(F4),改變生成操做爲內嵌資源)。而後咱們能夠按以下所示註冊本地化源:
Configuration.Localization.Sources.Add( new DictionaryBasedLocalizationSource( "SimpleTaskSystem", new XmlEmbeddedFileLocalizationDictionaryProvider( Assembly.GetExecutingAssembly(), "MyCompany.MyProject.Localization.Sources" ) ) );
XmlEmbedddFileLocalizationDictionaryProvider獲取包含XML文件(GetExecutingAssembly獲取當前程序集)和XML文件命名空間(命名空間由程序集名稱+XML文件的目錄層級組成)的程序集。
注意:當給嵌入的XML文件添加語言前綴時,不要使用點符號如'MySource.tr.mxl',應該使用破折號如'MySource-tr.xml',由於點符號會在查找資源時形成命名空間問題。
本地化源可使用JSON文件來存儲文本。一個JSON本地化文件的實例以下:
{ "culture": "en", "texts": { "TaskSystem": "Task system", "Xtasks": "{0} tasks" } }
JSON文件編碼應爲unicode(utf-8)。culture:"en"聲明標示這個JSON文件包含英文文本。咱們我每種語言建立一個單獨的JSON文件,以下所示:
這裏,MySourceName爲資源名稱,MySourceName.json文件定義了默認的語言。它和XML文件類似。
JOSN文件能夠存儲在文件系統或嵌入到程序集中。
若是文件系統存儲JSONs,我麼能夠按以下方式註冊JOSN本地化源:
Configuration.Localization.Sources.Add( new DictionaryBasedLocalizationSource( "MySourceName", new JsonFileLocalizationDictionaryProvider( HttpContext.Current.Server.MapPath("~/Localization/MySourceName") ) ) );
這些都是在模塊的PreInitialize事件中完成(參見模塊系統瞭解更多信息)。ABP在指定目錄查找JSON文件並註冊爲本地化源。
對於嵌入JSON文件,咱們須要標記本地的全部的XML文件爲嵌入的資源(選擇JSON文件,打開屬性窗口(F4),改變生成操做爲內嵌資源)。而後咱們能夠按以下所示註冊本地化資源:
Configuration.Localization.Sources.Add( new DictionaryBasedLocalizationSource( "MySourceName", new JsonEmbeddedFileLocalizationDictionaryProvider( Assembly.GetExecutingAssembly(), "MyCompany.MyProject.Localization.Sources" ) ) );
JsonEmbedddFileLocalizationDictionaryProvider獲取包含XML文件(GetExecutingAssembly獲取當前程序集)和XML文件命名空間(命名空間由程序集名稱+XML文件的目錄層級組成)的程序集。
注意:當給嵌入的JOSN文件添加語言前綴時,不要使用點符號如'MySource.tr.mxl',應該使用破折號如'MySource-tr.xml',由於點符號會在查找資源時形成命名空間問題。
本地化文本也能夠存儲在.NET的資源文件中。咱們能夠爲每種語言建立一個資源文件,以下所示(右鍵單擊工程,選擇添加新項而後找到資源文件):
MyTexts.resx包含默認語言文本,MyTexts.tr.resx包含Turkish語言的文本。當咱們打開MyTexts.resx時,咱們能夠看到全部的文本:
在這種狀況下,ABP使用.NET內建的資源管理器。你應該爲資源配置一個本地化源:
Configuration.Localization.Sources.Add( new ResourceFileLocalizationSource( "MySource", MyTexts.ResourceManager ));
這裏源的惟一名稱爲MySource。MyTexts.ResourceManager爲資源管理器的一個引用用來獲取本地化文本。這在模塊的PreInitialize事件中完成(參見模塊系統瞭解更多信息)。
能夠實現自定義源來實如今不一樣的源中存儲文本,如在數據庫中。你能夠直接實現ILocalizationSource接口或者你可使用DictionaryBasedLocalizationSource類來簡化實現(json和xml本地化源也使用它)。例如,Module zero在數據庫中實現資源。
ASP.NET Core有本身的機制來決定當前語言。Abp.AspNetCore包自動添加ASP.NET Core的UseRequestLocalization中間件來請求管道。它也添加一些特殊的提供者。這裏是全部提供者的默認順序列表,他們決定HTTP請求的當前語言:
當使用app.UseAbp()方法時,會自動添加UseRequestLocalization中間件。可是建議在認證中間件以後手動添加它(在Startup類的配置方法中),若是你的應用程序使用認證校驗的話。不然,本地化中間件能夠知道當前用戶來決定最佳的語言。示例用法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseAbp(options => { options.UseAbpRequestLocalization = false; //disable automatic adding of request localization }); //...authentication middleware(s) app.UseAbpRequestLocalization(); //manually add request localization //...other middlewares app.UseMvc(routes => { //... }); }
大多數時候,若是你恰當的使用了ABP的本地化系統,那麼你沒必要關心它。參見ASP.NET Core本地戶文檔來更好的瞭解它。
在每一次網絡請求時ABP自動決定當前語言,並設置當前線程的culture(和UI culture)。如下是ABP默認如何決定語言的方式:
若是須要,你能夠在模塊的PreInitialize方法中改變特定的cookie名稱(也是header名稱)。示例:
Configuration.Modules.AbpWeb().Localization.CookieName = "YourCustomName";
建立一個 資源並註冊到ABP本地化系統以後,文本就能夠很容易的本地化。
在服務端,咱們注入ILocalizationManager並使用GetString方法。
var s1 = _localizationManager.GetString("SimpleTaskSystem", "NewTask");
GetString方法基於當前線程UI culture從本地化源中獲取字符串。若是沒找到,它便使用默認語言。
若是指定的字符串沒有定義,那麼它人性化的返回指定的字符串並默認使用'['和']'包裝(取代拋出異常)。示例:若是給定的文本爲"ThisIsMyText",那麼結果將爲「[This is my text]」。這個功能是能夠配置的(你能夠在模塊的PreInitialize方法中使用Configuration.Localization改變它)。
爲了避免要重複使用資源名稱,你能夠先得到資源,而後從資源中獲取字符串:
var source = _localizationManager.GetSource("SimpleTaskSystem"); var s1 = source.GetString("NewTask");
這個返回當前語言的文本。GetString有重寫版本用來在不用的語言中獲取文本或經過參數格式化文本。
若是咱們不能注入ILocalizationManager(例如在靜態context中,不能使用依賴注入系統),咱們能夠簡單的使用LocalizationHelper靜態類。可是儘量的狀況下注入並使用ILocalizationManager,由於LocalizationHelper是靜態的,靜態類是測試不友好的(誰編寫單元測試)。
若是你須要在應用服務、MVC控制器、Razor視圖或其餘從AbpServiceBase繼承的類中本地化,能夠簡單的使用L方法。
本地化文本一般在MVC控制器和視圖中都是須要的。這有一個簡便方法。參見下面控制器示例:
public class HomeController : SimpleTaskSystemControllerBase { public ActionResult Index() { var helloWorldText = L("HelloWorld"); return View(); } }
L方法用來本地化字符串。固然,你必須提供一個資源名稱。這個操做在SimpleTaskSystemControllerBase中完成,以下所示:
public abstract class SimpleTaskSystemControllerBase : AbpController { protected SimpleTaskSystemControllerBase() { LocalizationSourceName = "SimpleTaskSystem"; } }
注意,它繼承自AbpController。所以,你能夠輕鬆的使用L方法本地化文本。
在視圖中也存在一樣的L方法:
<div> <form id="NewTaskForm" role="form"> <div class="form-group"> <label for="TaskDescription">@L("TaskDescription")</label> <textarea id="TaskDescription" data-bind="value: task.description" class="form-control" rows="3" placeholder="@L("EnterDescriptionHere")" required></textarea> </div> <div class="form-group"> <label for="TaskAssignedPerson">@L("AssignTo")</label> <select id="TaskAssignedPerson" data-bind="options: people, optionsText: 'name', optionsValue: 'id', value: task.assignedPersonId, optionsCaption: '@L("SelectPerson")'" class="form-control"></select> </div> <button data-bind="click: saveTask" type="submit" class="btn btn-primary">@L("CreateTheTask")</button> </form> </div>
爲了使用這個方法,須要視圖繼承自一個基類,這個基類設置了源名稱:
public abstract class SimpleTaskSystemWebViewPageBase : SimpleTaskSystemWebViewPageBase<dynamic> { } public abstract class SimpleTaskSystemWebViewPageBase<TModel> : AbpWebViewPage<TModel> { protected SimpleTaskSystemWebViewPageBase() { LocalizationSourceName = "SimpleTaskSystem"; } }
在web.config文件中設置這個基類:
<pages pageBaseType="SimpleTaskSystem.Web.Views.SimpleTaskSystemWebViewPageBase">
當你從ABP模板中建立解決方案時,控制器和視圖的全部設置都已經準備就緒了。
在javascript代碼中,ABP也可使用一樣的本地化文本。首先,你要在page中添加動態的ABP腳本:
<script src="/AbpScripts/GetScripts" type="text/javascript"></script>
ABP自動生成須要的javascript代碼來在客戶端獲取本地化文本。而後你能夠在javascript中得到一個本地化文本,以下所示:
var s1 = abp.localization.localize('NewTask', 'SimpleTaskSystem');
NewTask爲文本名稱,SimpleTaskSystem爲資源名稱。爲了避免重複使用資源名稱,你能夠首先得到資源再獲取文本:
var source = abp.localization.getSource('SimpleTaskSystem'); var s1 = source('NewTask');
本地化方法能夠接收其餘的格式化參數。示例:
abp.localization.localize('RoleDeleteWarningMessage', 'MySource', 'Admin'); //shortcut if source is got using getSource as shown above source('RoleDeleteWarningMessage', 'Admin');
若是RoleDeleteWarningMessage='Role {0} will be deleted',那麼本地化文本將爲'Role Admin will be deleted'。
你能夠設置一個默認的本地化源,而後使用abp.localization.localize方法時就能夠不帶資源名稱:
abp.localization.defaultSourceName = 'SimpleTaskSystem'; var s1 = abp.localization.localize('NewTask');
defaultSourceName是全局的,一次只能有一個資源。
假定咱們使用一個定義了本身本地化源的模塊。咱們要改變他的本地化文本,添加新文本或轉換爲其餘語言。ABP容許擴展一個本地化源。如今支持XML和JSON文件(實際上爲任何實現了IDictionaryBasedLocalizationSource接口的本地化源)。
ABP也定義類一些本地化源。例如,Abp.Web nuget包定義了一個名爲"AbpWeb"本地化源,爲嵌入的XML文件:
默認(英文)XML文件以下所示(僅第一次時顯示兩個文本):
<?xml version="1.0" encoding="utf-8" ?> <localizationDictionary culture="en"> <texts> <text name="InternalServerError" value="An internal error occurred during your request!" /> <text name="ValidationError" value="Your request is not valid!" /> ... </texts> </localizationDictionary>
而後咱們能夠在模塊的PreInitialize方法中註冊它:
Configuration.Localization.Sources.Extensions.Add( new LocalizationSourceExtensionInfo("AbpWeb", new XmlFileLocalizationDictionaryProvider( HttpContext.Current.Server.MapPath("~/Localization/AbpWebExtensions") ) ) );
若是想建立嵌入的資源XML文件(參見本地化源部分),咱們可使用XmlEmbeddedFileLocalizationDictionaryProvider。ABP使用咱們的XML文件重寫(合併)基本的本地化源。咱們也能夠添加新的語言文件。
注意:咱們可使用JSON文件擴展XML文件,反之亦然。
ILanguageManager能夠用來可用語言的列表和當前語言。
XML文件、JSON文件和資源文件有本身的長處和弱點。咱們建議使用XML或JOSN文件而不是資源文件,由於:
若是你使用XML或JSON,建議不要按名稱排序文本。按建立時間排序。這樣,當其餘人把它翻譯爲其餘語言時,他能夠輕鬆的看到哪些文本是新增長的。