Module Zero之语言管理
概览介绍##
ABP定义了一个健壮的UI本地化系统,它可用于服务端和客户端。它允许在不同的资源中(Resource文件和XML文件是两种预定义的资源)轻松地配置应用语言以及定义本地化文本(字符串)。
虽然这对于大多数情况是没问题的,但是我们可能想要将语言和文本动态地定义到数据库中。Module-zero允许我们动态地管理每个租户的应用语言和文本。
如何开启##
启动模板
如果你是从ABP官网的启动模板创建的项目,那么你可以跳过本节。因为该模板自带的基于数据库的本地化默认是开启的。如果你在这个特征之前创建了项目,那么请通过阅读本节来为你的应用开启此功能。
基于数据库的本地化是为了向后兼容ABP中已存在的本地化系统而设计的。它实际上取代了所有基于MultiTenantLocalizationSource本地化资源的字典。
MultiTenantLocalizationSource包装了基于资源的DictionaryBasedLocalizationSource。因此,我们一般包装基于XML的本地化资源。它可能不会包装Resource文件资源,因为resource文件是为硬编码设计的,而且静态文件也不适合动态本地化。
因为它是一个包装器,所以如果一个文本没有在数据库中本地化,那么潜在的XML文件就会用作回退资源(我理解为xml文件就是退而求其次的资源,也就是优先级小于数据库资源)。可能看着很复杂,但是对于你的应用实现起来很简单。下面让我们看一下如何开启基于数据库的本地化。
开启数据库本地化(EnableDbLocalization)####
首先要开启它:
Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();
这一步应该在高级别的模块中的PreInitialize方法中完成(对于Web应用,它是web module。导入Abp.Zero.Configuration命名空间查看Zero()扩展方法)。
实际上,该配置使得一切变得富有魔力。但是,我们应该多做一点来使它更合适地工作。
种子数据库语言####
因为ABP会从数据库中获得所有的语言列表,因此我们应该将默认的语言插入数据库。如果你正在使用的是EF,那么你可以像这里一样使用种子代码。
移除静态的语言配置####
如果你使用了像下面一样的静态语言配置,那么你可以删除它们,因为以后会从数据库中获得它们。
Configuration.Localization.Languages.Add(new LanguageInfo("en", "English", "famfamfam-flag-england", true));
注意已存在的XML本地化资源####
不要删除XML本地化资源和资源配置代码。因为如果数据库中没有相应的资源的话,这些文件会用作回退资源,并且所有的本地化键值会从这些资源中获得。
这样,当你需要一个新的本地化文本时,你可以像往常一样将它定义到XML文件中。你至少应该将它定义到默认语言的XML文件中。也只有这样,你才不用将默认的本地化文本的值添加到数据库迁移代码中。
管理语言##
可以将接口IApplicationLanguageManager进行注入,然后使用它管理语言。该接口有诸如GetLanguagesAsync ,AddAsync,RemoveAsync,UpdateAsync...的方法,可以用来管理租主和租户的语言。
语言列表逻辑####
语言列表为每个租户和租主单独存储和计算,如下:
- 存在一个为租主定义的语言列表。该列表对所有租户都是默认的。
- 存在为每个租户独立的语言列表。该列表继承了租主的语言列表,并加入了租户特定的语言。租户可以不删除或更新租主定义(默认)的语言(但是可以重写本地化文本,后面会看到)。
应用语言实体(ApplicationLanguage Entity)####
应用语言实体表示了一个租户或租主的语言。
[Serializable]
[Table("AbpLanguages")]
public class ApplicationLanguage : FullAuditedEntity, IMayHaveTenant
{
//...
}
基本属性有:
- TenantId(nullable):如果该语言是特定租户的,那么该属性就包含相关的租户Id。如果该语言是租主的,那么就是null。
- Name:语言的名字。该属性必须是来自这里的列表里的文化代码。
- DisplayName:该语言的展示名称。可以是任意的名字,一般是CultureInfo.DisplayName
- Icon:该语言的一个任意图标或旗帜。这个可用于在UI上展示该语言的旗帜。
而且,应用语言实体继承了FullAuditedEntity。这意味着,它是一个软删除且自动 审计的实体。
应用语言实体存储在数据库中的AbpLanguages表中。
管理本地化文本##
可以通过注入IApplicationLanguageTextManager接口来管理本地化文本。该接口拥有为一个租户或租主获取或设置本地化文本需要的方法。
使文本本地化####
当你想要本地化一个文本时,让我们看一下发生了什么:
- 尝试获取当前文化(使用CurrentThread.CurrentUICulture获得)。
- 检查给定的文本在数据库中是否以当前的文化为当前的租户(使用IAbpSession.TenantId获得)已经定义(或重写)。如果定义了就返回该值。
- 然后检查给定的文本在数据库中是否以当前的文化为该租主已定义(或重写)。如果定义了就返回该值。
- 然后检查给定的文本是否以当前的文化在潜在的XML文件中已经定义。若定义则返回该值。
- 尝试找出该回退文化。它是这样计算的:如果当前文化是“en-GB”,那么回退文化就是“en”。
- 检查给定的文本在数据库中是否以回退文化为当前的租户(使用IAbpSession.TenantId获得)已经定义(或重写)。如果定义了就返回该值。
- 然后检查给定的文本在数据库中是否以回退文化为该租主已定义(或重写)。如果定义了就返回该值。
- 然后检查给定的文本是否以回退文化在潜在的XML文件中已经定义。若定义则返回该值。
- 尝试找出默认的文化。
- 检查给定的文本在数据库中是否以默认的文化为当前的租户(使用IAbpSession.TenantId获得)已经定义(或重写)。如果定义了就返回该值。
- 然后检查给定的文本在数据库中是否以默认的文化为该租主已定义(或重写)。如果定义了就返回该值。
- 然后检查给定的文本是否以默认的文化在潜在的XML文件中已经定义。若定义则返回该值。
- 获得相同的文本或者抛出异常
- 如果给定的文本(或键值)压根没有找到,那么ABP会抛出异常或者返回相同的使用[and]包装的文本(或键值)。(可以在启动时配置,详情查看)
因此,获得一个本地化的文本有点复杂。但是它运行起来很快,因为它使用了缓存(cache)。
应用语言文本实体(ApplicationLanguageText Entity)####
在数据库中,应用语言文本实体存储了本地化的值。
[Serializable]
[Table("AbpLanguageTexts")]
public class ApplicationLanguageText : AuditedEntity<long>, IMayHaveTenant
{
//...
}
它的基本的属性是:
- TenantId(nullable):若该本地化的文本是特定租户的,那么它包含了与之相关的租户的Id。如果这是租主本地化的文本,那么该值为null。
- LanguageName:语言的名称。该属性必须是来自这里的列表里的文化代码。这个和ApplicationLanguage.Name是匹配的,但是没有强制的外键从而使它独立于语言实体。IApplicationLanguageTextManager会合适地对它处理。
- Source:本地化资源名称。
- Key:本地化文本的Key或者名称。
- Value:本地化的值。
ApplicationLanguageText实体存储在数据库中的“AbpLanguageTexts ”表。
Module Zero之语言管理的更多相关文章
- Module Zero之角色管理
返回<Module Zero学习目录> 角色实体 角色管理者 多租户 角色实体 角色实体代表了该应用的一个角色.它应该派生自AbpRole类,如下所示: public class Role ...
- Module Zero之权限管理
返回<Module Zero学习目录> 概览介绍 角色权限 用户权限 概览介绍 Module-Zero实现了ABP授权系统的IPermissionChecker接口.这篇文章中,我们将会看 ...
- 使用Jena RDF API 开发脚本语言管理资源描述框架模型
摘要 资源描述框架(Resource Description Framework RDF)是一种以XML格式描述元数据的标准格式.Jena是一种用于将关系数据库或是文本文件中所表示的数据建立为元数据模 ...
- Module Zero之用户管理
返回<Module Zero学习目录> 用户实体 用户管理者 用户认证 用户实体 用户实体代表应用的一个用户,它派生自AbpUser类,如下所示: public class User : ...
- ABP+AdminLTE+Bootstrap Table权限管理系统第十一节--Bootstrap Table用户管理列表以及Module Zero之用户管理
返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 用户实体 用户实体代表应用的一个用户,它派生自AbpUser类,如下所示: public class User : ...
- 一步一步使用ABP框架搭建正式项目系列教程之本地化详解
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 本篇目录 扯扯本地化 ABP中的本地化 小结 扯扯本地化 本节来说说本地化,也有叫国际化.全球化的,不管怎么个叫法,反正道理都是一 ...
- (新年快乐)ABP理论学习之本地化(2016第一篇)
返回总目录 本篇目录 应用语言 本地化资源 获取本地化文本 扩展本地化资源 最佳实践 应用语言 一个应用至少有一种UI语言,许多应用不止有一种语言.ABP为应用提供了一个灵活的本地化系统. 第一件事情 ...
- 在IDEA中通过Module管理多个项目
你身边有没有这种顽固的Eclipse忠实用户:IDEA不能一个窗口管理多个项目!太不方便了! 对于一个窗口同时管理多个项目的需求,在我们日常开发时候是经常需要的.尤其当我们在分布式环境下,在一个窗口中 ...
- Module Zero概览
返回<Module Zero学习目录> 介绍 ABP框架的设计是独立于任何数据库模式的且尽可能地使用泛型.因此,它避开了一些要求数据存储的抽象和可选的概念(如审计日志,session管理和 ...
随机推荐
- BeautifulSoup研究一
BeautifulSoup的文档见 https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ 其中.contents 会将换行也记录为一个子节 ...
- 基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就 ...
- vuejs的使用方法
1.安装webpack打包工具 npm install -g webpack 2.安装vue客户端 npm install -g vue-cli 3.初始化项目 vue init webpack de ...
- c#接口与抽象类的区别
abstract 修饰符用于表示所修饰的类是不完整的,并且它只能用作基类.抽象类与非抽象类在以下方面是不同的: 抽象类不能直接实例化,并且对抽象类使用 new 运算符是编译时错误.虽然一些变量和值在编 ...
- bzoj 4327: JSOI2012 玄武密码
听说这题不公开.. 那就不贴题意了 一眼看上去还以为是exkmp的裸题.. 看了数据范围,呵呵.. 多串匹配嘛.. 就用AC自动机咯,而且每个点最多也就只有$4$个孩子 用原串在AC自动机上走,碰到的 ...
- C# asp.net 搭建微信公众平台(可实现关注消息与消息自动回复)的代码以及我所遇到的问题
[引言] 利用asp.net搭建微信公众平台的案例并不多,微信官方给的案例是用PHP的,网上能找到的代码很多也是存在着这样那样的问题或者缺少部分方法,无法使用,下面是我依照官方文档写的基于.net 搭 ...
- phpstorm 10注释的双斜线位置不在缩进的位置:
22:07 2016/4/4phpstorm 10注释的双斜线位置不在缩进的位置:终于找到了(但是没有实现效果,不知道是什么原因 win10系统):File | Settings | Editor | ...
- tornado 学习笔记16 HTTP1Connection
HTTP/1.x协议的具体实现.实现HTTPConnection接口. 16.1 构造函数 定义: def __init__(self, stream, is_client, params=None, ...
- [RxJava^Android]项目经验分享 --- 递归实现
介绍一下业务逻辑:获取接口数据,根据接口内容判断是否需要继续获取数据. 本文使用递归思路,通过RxJava来实现此功能,获取数据的Observable直接用模拟的Observable.just()替代 ...
- Excel转Html
项目结构: 这是一个maven项目,主函数在Client类里面 当运行程序的后,控制台情况: 当我们刷新了test.html文件后,用浏览器打开效果: 说一下这个过程的设计思路: 1.读取excel文 ...