国际化
Steedos是支持多语言的低代码平台,我们可以在软件包中通过编写国际化资源文件来覆盖系统默认的相关翻译内容从而实现国际化。
我们鼓励大家在Steedos GitHub 开源代码中直接修改国际化资源文件并提交PR。
如果是要在Steedos项目中实现国际化,我们推荐大家把所有国际化的相关内容专门做成一个软件包,这样方便后续按模块进行维护、升级和部署,比如可以创建一个名为 locale 的软件包,以下国际化相关教程都在该软件包中开发。
资源文件
以下是Steedos源码中国际化资源文件对应的位置,其中文件或文件名中zh-CN表示中文资源文件,en表示英文资源文件。
对象
对象、对象字段、列表视图、操作按钮等对象元数据的国际化资源文件在以下源码中:
- Git仓库源码:standard-objects/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-objects/objectTranslations
最新版本的Steedos已经把上述内置 standard-objects 软件包中部分对象拆分到下面的软件包中了。
standard-cms
- Git仓库源码:standard-cms/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-cms/main/default/objectTranslations
standard-collaboration
- Git仓库源码:standard-collaboration/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-collaboration/main/default/objectTranslations
standard-object-database
- Git仓库源码:standard-object-database/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-object-database/main/default/objectTranslations
standard-permission
- Git仓库源码:standard-permission/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-permission/main/default/objectTranslations
standard-process-approval
- Git仓库源码:standard-process-approval/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-process-approval/main/default/objectTranslations
standard-ui
- Git仓库源码:standard-ui/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-ui/main/default/objectTranslations
设置应用菜单
后台设置应用是有左侧菜单的,这个菜单项的国际化资源文件在以下源码中:
- Git仓库源码:standard-objects/translations
- 本地NPM包源码:
node_modules/@steedos/standard-objects/translations
其他
其他国际化变量在以下源码中:
- Git仓库源码:i18n/translations
- 本地NPM包源码:
node_modules/@steedos/i18n/translations
元数据
Steedos是通过对各种类型的元数据添加翻译资源文件来实现国际化的,以下是各种元数据类型实现国际化的细节。
对象
对象和对象字段的元数据中是可以定义相关显示名称的,比如Steedos有一个名为 company 的对象,通过定义其 label 属性可以配置该对象的显示名称,这个对象在中文环境下显示的是“分部”,英文显示的是“Company”,以下操作过程可以把该对象对应的翻译改为“分公司”和”Sub Corporation“,同时把该对象上名为”分部代码“的字段改为”分公司代码“。
同步为代码
如果是为可视化界面上新建的对象添加国际化翻译内容,推荐先把该对象的元数据同步为代码以实现源代码版本管理,详情请参阅教程 同步元数据,不过这并不是必须的,因为未同步为代码的对象也支持按以下操作步骤实现对象国际化。
添加翻译文件
在软件包的default文件夹下新建一个objectTranslations文件夹,其下新建 company.en 和 company.zh-CN 两个同级文件夹对应的中英两种语言的翻译内容,最后各自新建中英文翻译的yml配置文件。
其目录结构如下:
locale
├── main / default
└───├── objectTranslations
└───├── company.en
| └── company.en.objectTranslation.yml
└── company.zh-CN
└── company.zh-CN.objectTranslation.yml
请注意添加国际化文件时,请按需添加,需要中文就加中文翻译文件,需要英文就加英文翻译文件,不可以加了文件后文件内容却是空的,这样会造成服务端程序抛出异常错误消息。
修改翻译内容
在刚新建的yml文件中添加翻译内容,以下两个文件内容实现了重写 company 对象及其字段的中文和英文显示名称
// locale/main/default/objectTranslations/company.zh-CN/company.zh-CN.objectTranslation.yml
name: company
label: 分公司
fields:
code:
label: '分公司代码'
// locale/main/default/objectTranslations/company.en/company.en.objectTranslation.yml
name: company
label: Sub Corporation
fields:
code:
label: 'Sub Corporation Code'
Base对象翻译
Steedos内置了Base对象,该对象用于配置所 有对象的通用属性,其中包括所有对象的通用国际化,它表示可以给所有对象上的通用字段,标准操作按钮等设置默认的国际化内容,而不用每个对象上都去设置一次。
内置的Base对象国际化内容请参考源码:
- Git仓库源码:base.zh-CN.objectTranslation.yml
- 本地NPM包源码:
node_modules/@steedos/standard-objects/objectTranslations/base.zh-CN/base.zh-CN.objectTranslation.yml
与给某个具体对象实现国际化操作方式一样,需要先为Base对象添加国际化翻译文件。
locale
├── main / default
└───├── objectTranslations
└───├── base.en
| └── base.en.objectTranslation.yml
└── base.zh-CN
└── base.zh-CN.objectTranslation.yml
然后再设置对应的翻译内容来实现对Base对象的国际化,我们只要把上面提到的Base对象国际化源码中的同名国际化变量添加进去,并定义其翻译内容即可修改默认的国际化内容。
以下翻译内容把中文环境下”分部“字段的显示名称改为了”单位“,并且修改了”新建“和”编辑“这两个标准操作按钮的显示名称,加上它们后,所有对象默认的相关国际化配置都会发生对应的变化,重启服务后就能看到效果。
// locale/main/default/objectTranslations/base.zh-CN/base.zh-CN.objectTranslation.yml
name: base
label: base
fields:
company_id:
label: '单位'
company_ids:
label: '所属单位'
actions:
standard_new:
label: 创建
standard_edit:
label: 修改
内置对象翻译
部分内置对象国际化翻译文件源码:
- Git仓库源码:standard-objects/objectTranslations
- 本地NPM包源码:
node_modules/@steedos/standard-objects/objectTranslations
要修改这些内置对象的国际化内容,按上面提到的操作步骤,先添加翻译文件,再修改翻译内容,只要为对象上同名国际化变量配置不同的翻译内容值,重启服务后即可看到修改后的效果。
字段
字段作为对象的一部分,其国际化翻译与对象是在一起的,请参考上述“对象国际化”的步骤来实现字段国际化,先添加翻译文件再修改翻译内容。
字段分组
不过字段上可以配置“分组”,我们如果需要对分组进行国际化翻译,也是修改对象翻译文件,以下翻译内容描述了如何修改Steedos内置对象“公司”下名为“华炎云”的字段分组的中文显示名称。
// locale/main/default/objectTranslations/spaces.zh-CN/spaces.zh-CN.objectTranslation.yml
name: spaces
label: 总公司
fields:
api_key:
label: '密钥'
groups:
Developer: Steedos
该翻译内容把“公司”对象的中文显示名称改为了“总公司”,把字段api_key的中文显示名称改为了“密钥”,并且该字段所属的分组显示名称从“华炎云”改为了“Steedos”。
可视化界面上新建的字段国际化方式与上面讲的内置对象是一样的,只要在对象翻译文件上加上相关字段或字段分组并设置其翻译文本即可。
下拉选项
选择框类型的下拉选项也是可以定制国际化翻译内容的,以下国际化翻译内容实现了给名为“项目任务”的对象下的“优先级”字段配置中文环境下的下拉选项显示名称。
// locale/main/default/objectTranslations/project_tasks__c.zh-CN/project_tasks__c.zh-CN.objectTranslation.yml
name: project_tasks__c
label: 项目任务
fields:
priority__c:
label: 优先级
options:
- label: 高
value: high
- label: 中
value: normal
- label: 低
value: low
其他
字段上的其他属性比如“提示文本”和“描述”也是可以配置国际化内 容的,以下示例描述了如何在国际化文件中配置它们。
// locale/main/default/objectTranslations/project_tasks__c.zh-CN/project_tasks__c.zh-CN.objectTranslation.yml
name: project_tasks__c
label: 项目任务
fields:
priority__c:
label: 优 先级
options: ...
help: 本周任务请选择“高”,下周任务请选择“中”,否则请选择“低”
description: 描述项目任务的紧急程度。
列表视图
与字段一样,列表视图也是对象的组成部分之一,其国际化翻译与对象是在一起的,请参考上述“对象国际化”的步骤来实现列表视图国际化,先添加翻译文件再修改翻译内容。
以下翻译内容描述了如何定制可视化界面上新建的名为“项目任务”的自定义对象的“所有”视图的中文和英文名称。
// locale/main/default/objectTranslations/project_tasks__c.zh-CN/project_tasks__c.zh-CN.objectTranslation.yml
name: project_tasks__c
label: 项目任务
listviews:
all:
label: 所有任务
// locale/main/default/objectTranslations/project_tasks__c.en/project_tasks__c.en.objectTranslation.yml
name: project_tasks__c
label: Project Tasks
listviews:
all:
label: All Tasks
请注意国际化列表视图时在翻译文件中使用的是listviews这个单词作为key,它与对象定义时使用的list_views相比要少写一个下划线。
操作按钮
与字段和列表视图一样,操作按钮也是对象的组成部分之一,其国际化翻译与对象是在一起的,请参考上述“对象国际化”的步骤来实现列表视图国际 化,先添加翻译文件再修改翻译内容。
以下翻译内容描述了如何定制可视化界面上新建的名为“项目任务”的自定义对象的“打印”按钮的中文和英文名称。
// locale/main/default/objectTranslations/project_tasks__c.zh-CN/project_tasks__c.zh-CN.objectTranslation.yml
name: project_tasks__c
label: 项目任务
actions:
print:
label: 打印当天任务
// locale/main/default/objectTranslations/project_tasks__c.en/project_tasks__c.en.objectTranslation.yml
name: project_tasks__c
label: Project Tasks
actions:
print:
label: Print Tasks for today
Steedos内置了很多标准操 作按钮,比如新建、编辑、删除等,这些标准按钮的国际化方法与自定义按钮是一样的,比如以下翻译内容可以修改上面的“项目任务”对象的“新建”按钮的中文名为“创建项目任务”。
// locale/main/default/objectTranslations/project_tasks__c.zh-CN/project_tasks__c.zh-CN.objectTranslation.yml
name: project_tasks__c
label: 项目任务
actions:
standard_new:
label: 创建项目任务
如果想修改所有对象的某个标准操作按钮的显示名称,请参阅上述Base对象翻译 小节。 内置标准操作按钮清单请参考源码:
- Git仓库源码:base.zh-CN.objectTranslation.yml#L137
- 本地NPM包源码:
node_modules/@steedos/standard-objects/objectTranslations/base.zh-CN/base.zh-CN.objectTranslation.yml
请注意国际化操作按钮时在翻译文件中使用的是actions这个单词作为key,而对象中定义按钮元数据时使用的是buttons。
自定义变量
自定义国际化变量指的是定义一个全局的国际化Key,并为该Key编写不同语言的国际化翻译内容。
上面讲到的对象层面的元数据,包括对象、字段、列表视图、操作按钮等,它们的翻译资源文件都是放在objectTranslations文件夹内,而其他元数据的翻译资源文件都是放到名为translations的文件夹内,用于存放自定义的国际化变量,比如我们后续会讲到的应用、设置菜单、系统消息还有审批王等,都是通过自定义变量来实现国际化的。
添加自定义变量
要添加自定义翻译变量,需要先在软件包中添加全局自定义翻译文件。
locale
├── main / default
└───├── translations
├── └── en.translation.yml
└── └── zh-CN.translation.yml
以下翻译内容为中文和英文资源分别添加了名为base_error_start_end_date的自定义翻译变量。
// locale/main/default/translations/zh-CN.translation.yml
CustomLabels:
base_error_start_end_date: '结束时间不能早于开始时间'
// locale/main/default/translations/en.translation.yml
CustomLabels:
base_error_start_end_date: 'The end time cannot be earlier than the start time'
添加自定义国际化变量前,应该先确认下变量名称是否已经被 内置自定义变量 或其他软件包占用,一般来说我们启动项目后在浏览器控制台中调用t函数即 可判断当前key是否已经被占用,只要返回的内容不是key本身就说明该变量已经被占用。
t('base_error_start_end_date') //返回“开始时间必须小于结束时间”
比如,在浏览器控制台输入以上代码并运行会发现输出的内容为“开始时间必须小于结束时间”,这说明该变量已经被占用了,所以上面不应该使用变量base_error_start_end_date,因为它已经被占用了。
我们尝试把该变量前面的base去掉,可以看到它并没有被占用。
t('error_start_end_date') //返回error_start_end_date
如果强行在软件包中添加已经被占用的自定义国际化变量的话,原来引用该变量的地方国际化内容就会被同时修改掉。
使用自定义变量
在添加好自定义翻译变量后,我们就可以在程序源码中使用它们了。
触发器中抛错信息
以下示例演示了如何在 触发器 中抛出错误消息时使用上面新添加的自定义翻译变量。
// locale/main/default/triggers/project_tasks__c.trigger.js
const validateStartEndDate = function (start, end) {
if(start && end){
const startTime = start.getTime ? start.getTime() : (new Date(start)).getTime();
const endTime = end.getTime ? end.getTime() : (new Date(end)).getTime();
if(endTime - startTime < 1000){
throw new Error("base_error_start_end_date");
}
}
}
module.exports = {
listenTo: 'project_tasks__c',
beforeInsert: async function () {
const { doc, object_name} = this;
validateStartEndDate(doc['start'], doc['end']);
},
beforeUpdate: async function () {
const { doc, object_name} = this;
validateStartEndDate(doc['start'], doc['end']);
}
}
从上述示例代码中可以看到,在触发器中只要在抛出错误信息时直接引用自定义翻译变量的key,就可以自动实现错误消息国际化了,系统会根据当前登录用户所设定的语言返回正确的国际化内容。
因为 触发器返回的错误消息会在前端组件中执行国际化转换再显示给最终用户看,所以并不需要在触发器中手动执行服务端国际化函数。
前端脚本中显示变量内容
我们在前端脚本中只要调用 t 函数即可得到当前登录用户所设定的语言对应的国际化内容,比如以下脚本会弹出错误消息,显示为前面我们定义的国际化内容。
toastr.error(t('base_error_start_end_date'));