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,建议不要按名称排序文本。按建立时间排序。这样,当其余人把它翻译为其余语言时,他能够轻松的看到哪些文本是新增长的。

 

返回主目录

相关文章
相关标签/搜索