本地化(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框架可否支持,该如何实现呢?