ABP官方文檔翻譯 6.3 本地化

本地化javascript

介紹html

  任何應用程序都會包含至少一種語言。許多的應用程序都包含多種語言。ABP提供了靈活的本地化系統。java

應用程序語言web

  首要的事情是聲明支持哪一種語言。在模塊的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模板使用這個系統給用戶展現一個能夠語言切換的組合框。能夠嘗試建立一個模板並參考源碼瞭解更多。瀏覽器

本地化源cookie

  本地化文本能夠存儲在不一樣的源中。甚至,你能夠一個應用中使用多種源(若是你有多個模塊,每一個模塊能夠定義分離的本地化源,或者一個模塊定義多種源)。ILocalizationSource接口須要使用一個本地化源實現。而後,它就會自動註冊到ABP的本地化配置中。網絡

  每個本地化源必須有一個惟一的源名稱。有以下預先定義的本地源類型。app

XML文件

  本地化文本能夠存儲在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本地化源

  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文件來存儲文本。一個JSON本地化文件的實例以下:

{
  "culture": "en",
  "texts": {
    "TaskSystem": "Task system",
    "Xtasks": "{0} tasks"
  }
}

  JSON文件編碼應爲unicode(utf-8)。culture:"en"聲明標示這個JSON文件包含英文文本。咱們我每種語言建立一個單獨的JSON文件,以下所示:

  這裏,MySourceName資源名稱,MySourceName.json文件定義了默認的語言。它和XML文件類似。

註冊JSON本地化源

  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
        ));

  這裏的惟一名稱爲MySourceMyTexts.ResourceManager爲資源管理器的一個引用用來獲取本地化文本。這在模塊的PreInitialize事件中完成(參見模塊系統瞭解更多信息)。

自定義源

  能夠實現自定義源來實如今不一樣的源中存儲文本,如在數據庫中。你能夠直接實現ILocalizationSource接口或者你可使用DictionaryBasedLocalizationSource類來簡化實現(json和xml本地化源也使用它)。例如,Module zero在數據庫中實現資源。

當前語言是如何決定的

ASP.NET Core

  ASP.NET Core有本身的機制來決定當前語言。Abp.AspNetCore包自動添加ASP.NET Core的UseRequestLocalization中間件來請求管道。它也添加一些特殊的提供者。這裏是全部提供者的默認順序列表,他們決定HTTP請求的當前語言:

  • QueryStringRequestCultureProvider(ASP.NET Core`s默認提供者):使用culture&ui-culture URL查詢字符串值。示例值:「culturee=es-MX&ui-culture=es-MX」。
  • AbpUserRequestCultureProvider(ABP的提供者):若是用戶能夠經過IAbpSession得知而且以前顯示的選擇了一個語言(且保存到ISettingManager),那麼就使用用戶喜歡的語言。若是用戶能夠得知可是沒有選擇任何語言,且.AspNetCore.Culture cookie或header有值,使用這個信息設置用戶的語言設置並使用這個值做爲當前語言。若是用戶不可得知,這個提供者什麼都不作。
  • AbpLocalizationHeaderRequestCultureProvider(ABP的提供者):使用.AspNetCore.Culture header值。示例值:"c=en|uic=en-US"。
  • CookieRequestCultureProvider(ASP.NET Core的默認提供者):使用.AspNetCore.Culture cookie值。示例值:「c=en|uic=en-US」。
  • AbpDefaultRequestCultureProvider(ABP的提供者):若是語言(名爲"Abp.Localization.DefaultLanguageNmae")有一個默認/應用程序/租戶設置值,那麼使用這個設置值。
  • AcceptLanguageHeaderRequestCultureProvider(ASP.NET Core的默認提供者):使用Accept-Language header值。示例值:「tr-TR,tr;q=0.8,en-US;q=0.6,en;q=0.4」。

  當使用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本地戶文檔來更好的瞭解它。

ASP.NET MVC 5.x

  在每一次網絡請求時ABP自動決定當前語言,並設置當前線程的culture(和UI culture)。如下是ABP默認如何決定語言的方式:

  • 嘗試一個特定header值,默認名爲"Abp.Localization.CultureName"。
  • 若是沒找打,嘗試獲取一個特定的cookie值,默認名爲"Abp.Localization.CultureName"。
  • 若是沒找到,嘗試獲取默認的culture設置(設置名爲"Abp.Localization.DefaultLanguageName",是定義在Abp.Localization.LocalizationSettingNames.DefaultLanguage裏的一個常量,可使用設置管理器改變這個值)。
  • 若是沒找到,嘗試獲取瀏覽器默認的語言(HttpContext.Request.UserLanguages)。

  若是須要,你能夠在模塊的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控制器

   本地化文本一般在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方法本地化文本。

在MVC視圖

  在視圖中也存在一樣的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

  在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文件易於編輯、擴展或port。
  • 當獲取本地化文本時, XML/JSON文件須要字符串key而不是編譯時的屬性如資源文件。這能夠認爲是一個弱點。可是,之後容易改變源。甚至咱們能夠將本地化遷移到數據庫而不用改變代碼(Module-zero實現它建立一個基於數據庫和每一個租戶的本地化源。參見文檔)。

  若是你使用XML或JSON,建議不要按名稱排序文本。按建立時間排序。這樣,當其餘人把它翻譯爲其餘語言時,他能夠輕鬆的看到哪些文本是新增長的。

 

返回主目錄

相關文章
相關標籤/搜索