Skip to content
pollybird edited this page Sep 9, 2026 · 2 revisions

国际化

国际化

基于 Flask-Babel,前台+后台全站生效。默认关闭(i18n_enable=0),不影响现有站点;仅界面文案翻译,内容数据不翻译。

后台配置

入口:系统设置 → 国际化(权限 system:settings)。

设置项 默认值 说明
i18n_enable 关闭 总开关
i18n_default_locale zh 兜底语种
i18n_available_locales zh 逗号分隔,如 zh,en
Locale 选择优先级
  1. URL 参数 ?lang=en(一次性,写回 session)
  2. session 中记录的语种
  3. cookie 中的语种
  4. 浏览器 Accept-Language 自动匹配
  5. 默认语种 zh 兜底

翻译工作流

模板中用 _() 标记可翻译字符串:

`{{ _('仪表盘') }}
`

翻译文件位于 app/translations//LC_MESSAGES/messages.po(当前提供英文 en)。.po 入库,.mo 不入库,部署前需编译:

`# 提取
pybabel extract -F babel.cfg -o app/translations/messages.pot app/
# 更新
pybabel update -i app/translations/messages.pot -d app/translations
# 编译(部署前必做)
pybabel compile -d app/translations
# 新增语种
pybabel init -i app/translations/messages.pot -d app/translations -l ja`

插件国际化

每个插件拥有独立翻译域,在 plugins//translations/ 下维护 .po/.mo,核心启动时自动发现。

模板层:_p() 函数
`
{{ _p('product', '产品列表') }}
{{ _p('product', '上一个产品') }}`
Python 层:plugin._()
`from . import plugin

title = plugin._('产品详情')   # 等价于 _p('product', '产品详情')`
提取/编译命令
`# 提取插件模板和 Python 代码
pybabel extract -F babel.cfg -o plugins/product/translations/messages.pot plugins/product/
# 初始化/更新/编译(与核心相同,指定插件目录)
pybabel init -i ... -d plugins/product/translations -l en
pybabel update -i ... -d plugins/product/translations
pybabel compile -d plugins/product/translations`

⚠️ .mo 文件在 .gitignore 中排除。v2.5.2 起核心与插件的 .mo 在启动时自动编译(缺失或比 .po 旧即触发),无需手动操作;也可仍按上述命令手工编译。

内容级多语言(i18n 2.0)

v2.3 的国际化是界面文案级别(后台按钮、菜单等固定文案的中英文切换)。v2.5 新增内容级多语言:文章标题、栏目名称、碎片内容、产品详情、表单说明、岗位描述、友情链接名称等动态数据也支持多语言版本存储,前台按当前 locale 自动渲染对应语言内容。

翻译表设计
主表 翻译表 翻译字段
articles article_translations title, summary, content, seo_title, seo_keywords, seo_description
columns column_translations name, summary, page_content, seo_title, seo_keywords, seo_description
fragments fragment_translations value(仅内容值,名称不翻译)
products product_translations title, summary, content, seo_*;specs(规格参数 JSON,v2.5.2)
forms form_translations name, description, success_message
recruit_jobs recruit_job_translations title, description;department, location, salary(v2.5.2)
friend_links friend_link_translations name(仅名称,URL 不翻译)

设计原则:主表保留默认语言字段(冗余),翻译表仅存非默认语言。查不到翻译时 fallback 主表默认语言,不会出现空白。slug 不随语言变化,URL 保持稳定。v2.5.2 起结构化字段同样可翻译:产品规格参数(JSON,结构同主表,留空回退主表)、岗位的部门/工作地点/薪资待遇(短文本,留空回退主表),对应 Alembic 迁移 0007。

前台模板:t() 全局函数
`
{{ t(article, 'title') }}
{{ t(article, 'summary') }}
{{ t(article, 'content')|safe }}

{{ t(column, 'name') }}

{{ t(fragment, 'value')|safe }}

{{ t(l, 'name') }}`

页面缓存键自动加入 locale,不同语言互不串扰。产品 API 缓存键同样加入 locale。

后台编辑:多语言版本 Tab

在文章/栏目/碎片/产品/表单/岗位/友情链接编辑页,开启 i18n 后显示「多语言版本」Tab,按语种切换录入翻译。富文本翻译字段使用 CKEditor5,与主编辑器配置一致。产品多语言 Tab 含该语言规格参数编辑器;岗位多语言 Tab 含部门/工作地点/薪资翻译输入框(v2.5.2)。

💡 碎片仅翻译内容值(名称不随语言变化);友情链接仅翻译名称(URL/LOGO 不随语言变化)。

Clone this wiki locally