mcpField
F
frappe-core-translation

frappe-core-translation

github.com/impertio-studio开发198111 次安装30 周前更新
代码仓库

关于 frappe-core-translation

面向开发者的 Frappe 应用翻译参考技能,涵盖 14、15 和 16 版。内容包括翻译 API、字符串提取、翻译文件格式及从右向左语言支持。

主要功能

  1. 01Python 和 JavaScript 翻译 API
  2. 02按文件类型划分的字符串提取规则
  3. 03CSV 与 PO/MO 翻译流程
  4. 04用于翻译任务的 Bench 命令
  5. 05从右向左语言支持

适用场景

  1. 01为自定义应用添加可翻译字符串
  2. 02提取并导入未翻译文本
  3. 03将 CSV 翻译迁移到 PO 文件
  4. 04适配从右向左书写的语言界面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/impertio-studio/frappe_claude_skill_package --skill frappe-core-translation

安装后在 Claude Code 中输入/frappe-core-translation确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
anti-patterns.md
api-reference.md
csv-and-bench.md

详细介绍

Frappe 翻译 / i18n

适用于 v14、v15 和 v16 的 Frappe 应用翻译确定性模式。


快速参考

任务PythonJavaScript
翻译字符串_("Hello")__("Hello")
带替换参数_("Hello {0}").format(name)__("Hello {0}", [name])
带上下文_("Change", context="Coins")__("Change", null, "Coins")
延迟翻译(模块级)_lt("Pending") [v15+]不适用
检查是否为 RTLfrappe.utils.is_rtl()frappe.utils.is_rtl()

决策树

Need to translate a string?
├── In Python (.py)?
│   ├── Inside a function/method → _("text {0}").format(val)
│   ├── Module-level constant [v15+] → _lt("text")
│   └── Module-level constant [v14] → define inside function or use lazy
├── In JavaScript (.js)?
│   └── ALWAYS → __("text {0}", [val])
├── In Jinja template (.html)?
│   └── {{ _("text") }}
├── In Vue (.vue)?
│   └── __("text") in <script>, {{ __("text") }} in <template>
└── DocType label/description/option?
    └── Auto-extracted — no _() needed

Where do translations live?
├── v14 → apps/{app}/{app}/translations/{lang}.csv
├── v15+ → apps/{app}/{app}/locale/{lang}/LC_MESSAGES/{app}.po
└── User overrides → Translation DocType (highest priority)

Need to extract untranslated strings?
├── v14 → bench --site {site} get-untranslated {lang} {output}
└── v15+ → bench generate-pot-file --app {app}

翻译优先级(从高到低)

优先级来源范围
1Translation DocType(用户覆盖)每个站点
2MO 文件(locale/{lang}/.../{app}.mo)每个应用 [v15+]
3CSV 文件(translations/{lang}.csv)每个应用
4父语言(例如,pt-BR 对应的 pt)回退

版本差异

功能v14v15v16
_() / __()是是是
_lt() 延迟翻译否是是
CSV 翻译是是(旧版)是(旧版)
PO/MO(gettext)否是是
bench generate-pot-file否是是
Babel JS 提取器否是是
_() 的类型提示否否是

自动提取的字符串(无需使用 _())

这些内容由框架自动提取:

  • DocType 标签和说明
  • Select 字段选项(每行一个选项)
  • 工作流状态和操作
  • Print Format 标签
  • 报告列标签
  • 通知主题(不包括正文)
  • 仪表板图表标签

字符串提取规则

文件类型提取器提取内容
.pyBabel(AST)_("...")、_lt("...") 调用
.jsBabel tokenizer [v15+] / regex [v14]__("...") 调用
.htmlRegexJinja 中的 {{ _("...") }}
.vue与 JS 相同script/template 中的 __("...")
.jsonDocType parser标签、说明、选项

重要:提取器基于 AST/令牌工作,无法提取动态构造的字符串。请参阅反模式。


反模式(绝不要这样做)

模式为什么会出错正确写法
_(f"Hello {name}")无法提取 f-string_("Hello {0}").format(name)
_("Hello " + name)拼接会拆分字符串_("Hello {0}").format(name)
_("Welcome %s") % name无法提取旧式格式_("Welcome {0}").format(name)
__(`Hello ${name}`)无法提取模板字面量__("Hello {0}", [name])
_(" Hello ")首尾空格会被移除_("Hello")
_("item" if x else "items")_() 中使用了三元表达式_("item") if x else _("items")
_(variable)无法提取变量_("Known String")

完整的反模式目录及代码示例:references/anti-patterns.md


CSV 翻译文件格式

位置:apps/{app}/{app}/translations/{lang}.csv

"source","translation","context"
"Hello","Hallo",""
"Change","Wisselgeld","Coins"
"Change","Wijziging","Amendment"
  • 始终使用 UTF-8 编码(不带 BOM)
  • 始终使用双引号括起所有字段
  • Context 列为可选,但必须存在(未使用时填写空字符串)
  • 无需注册 hooks——系统会自动从 translations/ 目录发现文件

PO/MO 文件 [v15+]

位置:apps/{app}/{app}/locale/{lang}/LC_MESSAGES/{app}.po

# Generate POT template
bench generate-pot-file --app {app}

# Migrate existing CSV to PO
bench migrate-csv-to-po --app {app}

# Compile PO to MO (required for runtime)
bench compile-po-to-mo --app {app}

PO 文件遵循标准 GNU gettext 格式。可使用任意 PO 编辑器(Poedit、Weblate、Transifex)。


Bench 命令

命令版本用途
bench --site {site} get-untranslated {lang} {output.csv}全部导出未翻译的字符串
bench update-translations {lang} {untranslated.csv} {translated.csv}全部导入翻译
bench generate-pot-file --app {app}v15+生成 .pot 模板
bench migrate-csv-to-po --app {app}v15+将 CSV 转换为 PO 格式
bench compile-po-to-mo --app {app}v15+将 PO 编译为二进制 MO

RTL 支持

硬编码的 RTL 语言:ar(阿拉伯语)、he(希伯来语)、fa(波斯语/法尔西语)、ps(普什图语)

# Python
if frappe.utils.is_rtl():
    # Apply RTL-specific logic
// JavaScript
if (frappe.utils.is_rtl()) {
    // Apply RTL-specific logic
}
  • Frappe 会自动为 <html> 元素应用 dir="rtl"
  • 为确保兼容 RTL,始终使用逻辑 CSS 属性(margin-inline-start,而非 margin-left)
  • 启用 RTL 语言时,会自动加载 Bootstrap RTL 样式表

自定义应用翻译工作流

为自定义应用添加翻译:
  1. 使用 _() / __() 和位置占位符编写可翻译字符串
  2. 提取未翻译的字符串:
    • v14:bench --site {site} get-untranslated {lang} untranslated.csv
    • v15+:bench generate-pot-file --app {app}
  3. 翻译提取出的字符串(手动翻译或使用 PO 编辑器)
  4. 放置翻译文件:
    • CSV:apps/{app}/{app}/translations/{lang}.csv
    • PO:apps/{app}/{app}/locale/{lang}/LC_MESSAGES/{app}.po
  5. 编译(仅适用于 v15+ PO):bench compile-po-to-mo --app {app}
  6. 清除缓存:bench --site {site} clear-cache

参考文件

文件内容
references/api-reference.md完整的 Python _() 和 JS __() API,包含所有签名和边缘情况
references/csv-and-bench.mdCSV 格式规范、bench 命令、PO/MO 工作流、自定义应用设置
references/anti-patterns.md完整的反模式目录,包含失败示例和修正示例

评论

支持 Markdown