上文介绍了多语言产品设计的相关背景和注意事项。产品支持多语言,包括了国际化和本地化,整体来说,这是一个相当复杂的工程。
接下来,聚焦于国内产品在已有产品服务的基础上新增其他语种,对多语言产品的实现予以介绍。
1、多语言文案翻译
1) 梳理确定范围
构建产品多语言能力的第一步就是需要确定需要支持多语言的文案范围。如果从 0 开始设计产品,在确定需要支持多语言能力之后,在每一次迭代中,需要基于产品设计文档,将涉及到支持多语言的文案内容梳理出来,用于后续翻译。如果从现有产品开始规划多语言能力,这个过程的文案梳理会相对复杂。
存量文案: 存量文案,是之前产品中已有的功能中需要翻译的文案内容。盘点存量文案范围,需要产品和研发共同协作。
增量文案: 增量文案,是未来进行产品迭代所涉及到的功能中所包含的文案内容。
在梳理前,先创建一个文案表格,建议包含以下几列:
- Key:默认为空,后期赋值并绑定
- 中文:文案本身的内容,对于我们来说就是中文要翻译的内容
- 文案目标语言:即需要翻译成的目标语言,比如 English,如果要支持多种语言,则需要多列。这一列内容,需要翻译人员输入
- 文案路径:文案所在的页面路径,同时可存储于多语言文案管理平台中 (后文详细介绍),该列是非必要的,只是为了便于文案管理
- 文案环境:建议贴上文案所在页面的截图,以便了解该文案的语境,帮助更好的翻译,该列同样是非必要的,目的是帮助翻译人员更好的理解和翻译文案
文案表格主要用于前期文案管理和翻译项目的协作,在这个基础上,我们可以开始梳理范围。考虑到不是从 0 开始设计产品,建议直接由产品研发共同参与,完成文案的收集工作。
产品经理梳理: 产品同学先将各页面可见的文案梳理出来。
研发梳理: 技术人员是通过代码检查的方式,找出那些直接硬编码在代码中的文本。这些文本可能在页面中不可见或者是被忽略的文案,但在产品实际使用时却会被用户看到,因此也是需要梳理的对象。关于文案收集,市面上有一些相对成熟的检查工具,可以批量检查并导出代码中的硬编码字符串,比如 IDE (如Android Studio或Xcode)的检查工具,或者使用正则表达式遍历搜索。
梳理出来的文案,录入文案表中。上述产品研发配合梳理,可以覆盖绝大部分的文案内容,对于极少数文案内容,可以通过后期的测试环境或者线上使用反馈予以覆盖。
2) 文案翻译
文案翻译,常见的方式有 3 种:
- 翻译平台服务:使用专业的翻译管理平台,比如Transifex、Crowdin、OneSky等
- 翻译机构合作:与翻译公司或者机构开展翻译项目合作,当然如果公司有足够的资源,可以构建自己的翻译服务团队
- 机器翻译:使用 Google、百度、ChatGPT 等方式实现翻译。对于前期的大量存量文案翻译工作,不建议这种方式,后期产品的迭代可以结合已翻译的文本风格和机器翻译的方式进行翻译,有利于节省成本。
将翻译完的多语言文本内容同样录入文案表对应的列中。
3) 文案审查
这部分主要是将翻译完成的文案内容,基于产品的风格和文化,做一些微调,主要包括长度、用词方式等方面,以更好更恰当的适配产品表达。这部分工作主要有公司的产品和设计团队完成。
2、 多语言文本 Key 的设置
将文案翻译完成之后,需要为每一段文案分配一个唯一的Key(键值),用于在代码中引用这段文案。需要注意的是,同一段文案对应的多个语种内容,共用同一个 Key,其主要作用是标记文案的唯一性,且不建议修改。
设置 Key 的时候,需要遵守一定的规范:
- 唯一性:每一个Key都应该是唯一的,不能重复。这是最基本的要求。一段文案对应一个唯一的Key,用户在应用内切换语种时,通过 Key 可以找到对应的文案。
- 描述性:好的 Key 应该能够描述这段文案的含义或者用途,尽量避免使用过于抽象或者无意义的Key。这样不仅可以帮助产品和研发更好地理解这段文案的用途,也可以在某种程度上方便翻译人员理解文案的含义。比如一个按钮的文案是“提交”,那么这个文案的 Key 可以是 "submit_button"。
- 结构性:如果一个界面或者功能有很多相关的文案,那么可以考虑为这些文案的Key设置一个共同的前缀,表示它们的归属或者关系。例如,如果一个登录界面有用户名、密码、登录按钮等文案,那么这些文案的Key可以分 是"login_username"、"login_password"、"login_button"等。
- 语言和字符限制:通常,Key 的字符集限制为ASCII字符,且不含特殊字符。至于长度,一般没有硬性规定,但出于易读性和管理的考虑,不建议设置过长的Key。
- 避免使用文案内容作为Key:据调研,一些早期的多语言实践中,直接使用英文文案作为Key,如 “submit”:“提交”。这种做法在文案需要修改时会带来问题,因为一旦英文文案改变,Key也需要改变,这将导致代码中所有引用这个Key的地方都需要修改。所以,现代的多语言项目中,通常不推荐使用文案内容作为Key,而单独设置 Key 值,即便这个 Key 值恰好和文案的英文译文一致。
注意,如果不同的页面有相同的文案内容,在设置 Key 的时候,可以使用同一个 Key,也可以为每个文案单独设置一个 Key,比如登录页和修改密码页都有“密码”,两者可以都使用“password”,也可以前者使用“login_password”而后者使用“change_password”。这种方式可以减少代码冗余,但是如果使用同一个 Key,那么未来这两个文案如果仅其中一个发生了调整,那么对应的 Key 和调整后的文案可能就失去“描述性”关系了。如果使用两个独立的 Key,可以通过加前缀的方式实现,带来弹性灵活好处的同时却也有不够精简的问题。面对这种情况,Key 值的选择策略仁者见仁智者见智。
3、多语言管理平台工具
多语言管理中台工具,是一个管理多语言文案的中心,可以借助开源工具或者自研。其主要作用有:
1)管理多语种、多语言文案以及对应的 Key 值
允许将完成翻译的文案内容批量导入管理系统中,并支持编辑、添加、删除多语言键值对等操作。
2)翻译工具
可以引入机器翻译的能力,比如 Google、百度、ChatGPT 等能力。这样,后续迭代过程中的新增文案,可以结合机器翻译和存量文案的翻译方式及风格,实现翻译工作在产研内部的自闭环。当然,更严谨的方式,依然是借助专业的平台或者机构服务。
3)生成各类语种的多语言文件
基于管理的多语言内容资源,生成团队所需要的多语言文件(通常是 JSON 或 XML 格式),并由研发导入到代码工程中,以便发布后,实现多语言调用。 多语言 JSON 文件是一个包含 Key 和对应语种文案的键对值组合,下面是一个简单的 English 示例。
{
"en":{
"welcome_message": "Welcome to our app!",
"login_button": "Login",
"signup_button": "Sign up"
}
}
4)提供调用服务
对于多业务多应用的团队和组织,该平台可以提供相关的 API,以允许多个应用直接调用平台内的多语言资源,这样无需每个应用团队都单独维护一套多语言资源,从而提效的同时实现了大幅降本。
5)版本管理
可以管理多语言文件的历史版本,这样可以方便查看以前版本的翻译,并可以回滚到以前的翻译版本。
4、多语言产品实现原理
多语言切换的实现路径:切换语言 → 确定 Key → 判断语种 → 请求并显示译文。
1)Key 的导入
代码通过调用 Key 值来访问多语言文案资源的前提是在代码对应的模块得知道调用哪个 Key,即调用之前,需要将对应的 Key 传入正确的代码位置,这个工作由研发主导,往往需要手动地在代码中一个个地替换硬编码的字符串为对应的多语言 Key 引用。考虑到需要在大量的代码位置插入对应的多语言 Key,为了提高效率和准确性,下方是一些建议:
使用自动化工具
有些IDE(如Android Studio、Visual Studio Code等)提供了一些自动化工具,通过使用这些专门的工具来扫描并查找代码中硬编码的字符串,并将其替换为本地化Key的引用,这个是较为常用的方式。在实践中,开发者在需要显示这段文本的地方,使用本地化库提供的函数或者方法,传入这个Key。例如,在Android中,可以使用 “getString(key)” 方法。
模块化和复用
如果应用有一些通用的文案,如"确定"、"取消"等,则可以为这些文案定义一些通用的Key,然后在多个地方复用。这样,就可以减少在代码中插入Key的次数。当然,诚如上文所说,这样做的前提是这部分文案内容基本不调整。
设计好的代码结构
一个设计好的代码结构可以更容易地进行本地化。例如,可以将所有的文案都放在一些集中的位置,如专门的文案管理类中,而不是分散在各处的逻辑代码中。
逐步替换
如果应用文案内容非常庞大,一次性进行全面的替换可能会很困难,则可以考虑逐步替换,按照优先级,先替换最重要或者最常见的部分,然后逐步扩大范围。
2)多语言文案的显示原理
多语言文案的显示原理是当用户切换语言时,程序代码开始运行,系统会根据当前的语言设置,从多语言文件中查找这个 Key 对应的文本。如果找到了,就显示这个文本;如果没有找到,通常会显示原语言内容,比如中文对应的文案。
在多语言实践过程中,有两种方式实现对多语言文案内容的调用,分别是非热更新方式和热更新方式。
非热更新方式
非热更新的方式,其实是文件传入的方式,这需要将多语言文件导入对应的代码模块,这样便可以基于 Key 去调用对应的多语言资源。如果多语言内容有更新,这种方式往往需要通过应用发版的方式,对多语言能力进行迭代。
热更新方式
多语言文件的热更新一般需要远程服务器和本地的配合,下面是一般的实现原理和逻辑:
- 远程服务器:首先,需要一个远程服务器来存储所有的本地化资源文件。当有新的语言版本发布时,可以上传新的本地化资源文件到服务器。服务器需要能够处理这些上传的文件,并能根据客户端的请求返回相应的文件。
- 本地缓存:在应用程序中,需要一个地方来存储从服务器下载的本地化资源文件。这个地方可以是文件系统,也可以是数据库。在加载本地化资源时,应用程序应该优先使用缓存中的文件,如果缓存中没有找到,再使用默认的本地化资源文件。
- 文件下载:应用程序需要在合适的时机(例如启动时,或者用户手动刷新时)从服务器下载本地化资源文件。下载的文件应该被保存到本地缓存中。
- 文件解析:应用程序需要能够解析从服务器下载的这些文件,并将解析后的数据用于本地化。
- 错误处理:在热更新过程中,可能会遇到各种问题,例如网络错误,文件解析错误等。应用程序需要能够处理这些错误,并在必要时恢复到默认的本地化资源。
- 数据同步:为了避免每次启动应用程序都需要下载所有的本地化资源文件,可能需要一个数据同步机制。只有在服务器上的数据有变化时,才需要下载新的数据。
- 应用热重启:当应用程序从服务器获取到新的多语言文件并存储在本地后,需要在不关闭应用的情况下将新的本地化资源文件加载到内存中,并应用到当前的用户界面上。这可能需要一种特殊的机制来实现 (例如React的Context或者Flutter的InheritedWidget),因为大多数的UI框架在初始化时只加载一次本地化资源。
— END —
你好,我是江同学,5年以上产品经理
职场过来人,有过创业经历,深谙产品逻辑和商业逻辑
专注分享产品知识技能