技术应用 | 如何实现网站国际化 (i18n)? 超详细攻略来了
The following article is from 舜禹环球通Transphere Author John Curtis
要拓展海外市场,有一个符合当地市场语言和文化的官方网站至关重要;而要实现这个目标,首先要确保网站符合国际化的要求。那么,什么是国际化?为什么要先符合国际化要求?又要如何判断呢?我们在这里编写了一份超详细攻略,搭配可以实操的源代码,大家亲自动手试一试吧。
在讨论了网站国际化后,我们又补充了一些本地化的内容,以期展现更为清晰的全局图景。
1 什么是国际化 (i18n)?
网站国际化指的是对网站代码进行开发或修改,以支持目标地的语言及书写习惯(如单复数、日期等),让针对目标市场的本地化工作得以顺利开展。如果不先完成网站国际化,网站的底层结构会对本地化造成阻碍,甚至需要重写代码,徒增工作量。换言之,国际化是本地化的基础,做好国际化,才能更为高效地进行本地化。
2 您的网站为什么需要本地化?
网站经过本地化后,能够贴合新客户的文化和语言偏好。一个针对中国客户设计的网站可能并非适用于美国客户。这两个客户群体不仅语言不同,浏览习惯也有很大差异,因此必须区别对待。这并非仅仅是经验之谈,还有以下统计数据作为事实依据:
●87% 的消费者从不在外文网站上购物。
●65% 的消费者更喜欢浏览使用其母语的网站。
●64% 的买家认为,经本地化的内容更可信。
在所有投资中,用于改善客户用户体验的投资能带来最高回报比。WebFX 调查显示,每向用户体验投资一美元,就会收获 100 美元的回报——这意味着投资回报率高达 9900%!
但在启动网站本地化这项工作之前,网站必须符合国际化的要求。
3 查看网站是否已经国际化
没有国际化的网站通常有如下特征:
•包含硬编码,即字符串与代码混在一起,没有任何标签加以区分。如下面的代码中,黄色高亮部分即为硬编码:
硬编码字符串
• 不支持阿拉伯语、希伯来语等从右到左的语言。
未国际化版本
已国际化版本
•仅支持一种时区、数字格式及货币。
•无法切换语言/区域。
•不支持Unicode字符,等等……
4 前期准备
要开展网站国际化,我们会用到 PyCharm IDE(只是建议)。如果您想直接用 Python,推荐 3.10 版👇🏻
https://www.python.org/ftp/python/3.10.7/python-3.10.7-amd64.exe
如需了解如何安装 Python,请点击👇🏻
https://realpython.com/installing-python/
我们还需要用到下面两个 Python 库:
•Flask-Babel: 为 Flask (Python) Web 应用提供 i18n 和 l10n 支持的库。
•Flask: Python 编写的轻量级 Web 应用框架。
虽然编程不是必备能力,但却是加分项——许多难题将迎刃而解。
要练习如何实现网站国际化,首先要有个网站。您可以建一个,也可以从我们的GitHub仓库(https://github.com/Transphere-Sunyu/i18n-python) clone:
git clone https://github.com/Transphere-Sunyu/i18n-python.git
5 项目配置
新建i18n-python文件夹,并在这个文件夹下另外新建三个文件夹,即 static、locales 和 templates,以及一个 app.py 文件。
UNIX/Linux 系统:
mkdir i18n-python && cd i18n-python
mkdir static locales templates && touch app.py
Windows 系统:
mkdir i18n-python && cd i18n-python
mkdir static locales templates && type nul > app.py
运行以下命令,指向项目文件夹路径,将 Flask 和 Flask-Babel 安装到项目中。
pip3 install Flask_Babel Flask
新建一个 babel.cfg 文件,向 Babel 指示在哪里查找翻译并添加以下代码:
[python: **.py]
[jinja2: **/templates/**.html]
前两行分别定义了 Python 和 Jinja2 模板文件的文件名模式。https://pypi.org/project/Jinja2/是一个可扩展的模板引擎,支持使用类似于 Python 语法的代码。它用传递过来的数据来生成最终文档。
项目文件夹结构如下所示:
6 后端设置
在 app.py 文件的开头导入以下模块:
from flask import Flask, render_template, request, session
from flask_babel import Babel
import os
将下列代码添加到同一文件中:
app = Flask(__name__)
babel = Babel(app)
app.config['BABEL_DEFAULT_LOCALE'] = 'en'
app.config['LANGUAGES'] = {
'en': 'English',
'zh': 'Chinese(Simplified)',
'ar': 'Arabic'
}
app.config['SECRET_KEY'] = 'your secret key'
app.config["BABEL_TRANSLATION_DIRECTORIES"] = os.path.abspath('locales/')
# Make languages and current_languages variables
# accessible in all the templates
@app.context_processor
def inject_conf_var():
return dict(languages=app.config['LANGUAGES'],
current_language=session.get('lang',
request.accept_languages.best_match(app.config['LANGUAGES'].keys())))
@babel.localeselector
def get_locale():
if request.args.get('lang'):
session['lang'] = request.args.get('lang')
return session.get('lang', request.accept_languages.best_match(app.config['LANGUAGES'].keys()))
@app.route('/')
def index():
get_locale()
return render_template('index.html')
if __name__ == '__main__':
app.run()
请务必将“BABEL_TRANSLATION_DIRECTORIES”的值替换为翻译文件夹的路径。
借助👇🏻https://flask.palletsprojects.com/en/2.2.x/templating/#context-processors,language 和 current_language 变量能够以字典形式在每个模板中使用,如下所示。
{
'languages': {'en': 'English', 'zh': 'Chinese(Simplified)'}, 'current_language': 'en'
}
7 替换硬编码字符串
硬编码字符串是嵌在HTML代码中的文本。如果不处理硬编码,增加语言时会非常麻烦。有一种处理方法是用 _() 文本标记将 HTML 代码中的字符串(即要翻译的文本)用括号括起来,向 Flask Babel 表明待译字符串,即 {{ _("HTML string!")}},如下所示:
<div class="ui-section-hero--content">
<h1>{{ _('Design better.') }}</h1>
<p class="ui-text-intro">
{{ _('Design Mobile UI faster and better with our
product and produce professional designs for your
business') }}
</p>
</div>
这样,以上这段代码已经符合国际化的要求,因为其中的待译文字可以方便提取、翻译并和地区关联,用户可通过选择地区,让系统呈现相应的文字。
8 生成待译文件
运行以下命令,从 html 文件中提取字符串。
pybabel extract -F babel.cfg -o messages.pot .
如果您的代码是从咱们的GitHub仓库clone的,就会看到以下提示:
extracting messages from app.py
extracting messages from templates\index.html
pybabel extract 命令会读取 -F 选项中指定的配置文件,然后扫描目录中与配置源相匹配的所有文件。默认情况下,pybabel 会查找作为文本标记的 _()。-o 选项确定了输出 .pot 文件的名称。
pybabel init -i messages.pot -d locales -l zh
pybabel init 命令对 messages.pot 进行初始化,指定其译文为中文,并生成 translation.po 文件,如下所示。
#: templates/index.html:62 templates/next.html:62
msgid "Design better."
msgstr ""
#: templates/index.html:63 templates/next.html:63
msgid ""
"Design Mobile UI faster and better with our product and produce "
"professional designs for your business"
msgstr ""
msgid 为源语言字符串,而 msgstr 为目标语言字符串。
9 翻译字符串
可以用Trados来翻译刚刚生成的 translation.po 文件。新建项目,导入该文件:
Trados内嵌的解析器已经将待译文字提取出来,打开文件直接翻译即可:
翻译完成后,将文件导出到locales文件夹(locales/zh/LC_MESSAGES)。此时,messages.po 文件中的 msgstr会被译文填充,如下所示:
#: templates/index.html:71 templates/next.html:71
msgid "Available on Android and iOS."
msgstr "可在 Android 和 iOS 上使用。"
#: templates/index.html:86 templates/next.html:86
msgid "Features"
msgstr "功能"
运行下列命令,将区域语言 (locales) 文件夹中的翻译文件编译为 .mo 文件,而 flask babel 会用这些文件来加载网站翻译。
pybabel compile -d locales
10 添加语言选择器
添加语言选择器后,用户可以选择不同语言。
为实现这个功能,先在 body 标签底部添加👇🏻https://getbootstrap.com/docs/5.2/getting-started/download/#cdn-via-jsdelivr代码:
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-u1OknCvxWvY5kfmNBILK2hRnQC3Pr17a+RTT6rIHI7NnikvbZlHgTPOOmMi466C8"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"
integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3"
crossorigin="anonymous"></script>
然后将下面的代码添加到 header 标签中:
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">
通过以下命令创建一个下拉菜单,其中包含网站支持的所有语言:
<!-- MENU -->
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ current_language }}
</button>
<ul class="dropdown-menu">
{% for language in languages.items() %}
<li><a class="dropdown-item" href="{{url_for('index',lang=language[0]) }}">
{{ language[1] }}</a></li>
{% endfor %}
</ul>
</div>
下拉菜单截图:
用了上文提到的👇🏻
https://flask.palletsprojects.com/en/2.2.x/templating/#context-processors装饰器,便可在 html 文件中访问 current_language 和 language 变量。
.items() 方法以列表返回元组形式的语言,其经过循环访问后生成语言列表,以下拉列表显示。
运行下列命令,在浏览器上查看网站并切换语言。
flask run
以下是一些翻译成简体中文 (zh) 的网页截图。
11 更新待译字符串
若要在网页上新增文本,先按步骤7替换硬编码字符串;再在index.html中添加段落标签,标签间放入新的待译字符串。
<p class="ui-text-intro">{{ _('Free for 3 months') }}</p>
运行以下命令提取待译字符串。
pybabel extract -F babel.cfg -o messages.pot .
messages.pot 文件会更新,其中新增待译字符串。
再运行 update 命令,更新 message.po 文件:
pybabel update -i messages.pot -d locales
在 Trados或其他 CAT 工具中翻译 message.po 文件,完成后导回,并运行 compile 命令:
pybabel compile -d locales
12 向网站添加多语种内容
若您按照以上步骤操作,会发现用代码在网站上添加一种新的语言并不难,真正的难点在于如何呈现符合目标地语言文化习惯的内容。有些内容若直接从中文翻译,往往无法让目标读者产生共鸣,纯属白花钱;而若译文违反了当地的法律法规或者触碰了当地人的禁忌,引起舆论声讨,就更得不偿失了。
鉴于此,您可以考虑和成熟的语言服务商合作,以专业的方式开展网站本地化。语言服务商不仅能确保多语言内容的地道性和合规性,还可以提供技术支持,让整个本地化流程更为自动化和高效。并且,有些语言服务商还可以省略翻译环节,让当地写手或艺术家直接创作内容,这样更能打动人心、获得认同,是打开或拓展当地市场不可或缺的助力。
舜禹环球通的母语内容创作团队为多家知名公司提供服务,可从语言质量、设计及搜索引擎优化 (SEO) 等维度出具专业的网站内容分析报告,助力您的网站发挥出最大价值。
-END-
关注我们,获取更多资讯!
往期回顾
行业动向1. 行业动态 | 全国翻译专业学位研究生教育2022年会分论坛一:“翻译专业学位教育规范化标准建设”2. 行业动态 | 全国翻译专业学位研究生教育2022年会分论坛二:“高层次中译外人才培养与国际传播能力建设”3. 行业资讯 | 全国翻译硕士专业学位(MTI)培养单位名单(316所/最新版)4. 行业资讯 | 语言服务业首次列入国家《鼓励外商投资产业目录》!5. 行业报告 |《2022年机器翻译评测报告》解读(下)行业榜单 | 翻译类院校、翻译技术和本地化类公众号前10强榜单出炉!(2022年11月)
行业洞见1. 行业观察 | 大数据时代译者如何提升数字素养—《翻译搜索指南》主编王华树博士专访2. 行业观察 | 黄友义《从“翻译世界”到“翻译中国”》
3. 行业观察 | 翻译博士专业学位2023年推出,专博培养步入快车道4. 研究动态 | 《外国语言文学》2022年第5期5. 研究动态|王华树、刘世界:新文科背景下翻译技术核心课程教学模式探索
行业技术1. 技术科普 | 什么是游戏本地化?远不止翻译那么简单!2. 技术应用 | TransWAI 上线语音合成功能,支持多语合成3. 技术应用 | 表达匮乏?词汇不够?用这个助你突破知识茧房!4. 技术应用 | Zotero零基础教程5. 智慧教育 | 智能翻译教学与实训平台新发展
精品课程1. 第三期“译起向未来”翻译技术云端实习冬令营报名开启~2.翻译技术2023全年班限时预售!技术小白速速加入~3. 英专生只能做翻译?不!你还可以做管理!
资源干货1. 书籍推荐 | 人人都用的上的《翻译搜索指南》2. 书籍推荐|戴光荣、王华树等合力编写翻译技术入门级指南3. 资源宝库 | 徐彬教授的翻译技术和翻译批评视频汇总4. 语言趣谈 | 韦氏词典公布2022年度词汇:Gaslighting--煤气灯效应5. 语言趣谈 | 《人民日报》公布常见文字错误,词语、标点等避坑指南!
招聘就业1. 招聘快报 | 舜禹年度热门岗位放出,三大城市30名+译员招募!2. 招聘快报 | 字节跳动招募英文内容翻译实习生,提供实习证明3. 招聘快报 | 网易招聘高级英语翻译4. 招聘快报 | 中新网招募英文编辑,要求硕士学历,通过专八或CATTI5. 招聘快报 | 教育部中外语言交流合作中心2023年度公开招聘