error_messages_for

本文解答了一个关于Ruby on Rails应用中如何正确使用error_messages_for显示表单验证错误的问题。作者解释了error_messages_for的工作原理,并给出了实例说明如何针对不同变量名的对象正确调用此方法。
 在http://www.ruby-forum.com/topic/114652#new论坛中看到如下问题:
   I have a database table called "hvd_codes", the model is called HvdCode.
In my form partial, what should I enter as a parameter to
error_messages_for? I've tried <%= error_messages_for 'hvd_codes' %> but nothing is
displayed.
IRC error_messages_for simply looks for a global variable named after
its parameter and parse the result 'errors' called on it.
So if you have a @hvdcode which is a HvdCode instance, just use
'hvdcode'. If you had a @foo instance of HvdCode, you'd use 'foo'...
(venv) gapinyc@DESKTOP-9QS7RL5:~/superset/venv/lib/python3.10/site-packages/superset/translations$ pybabel compile -d . -l zh error: ./zh/LC_MESSAGES/messages.po:154: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:158: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:162: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:281: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:1177: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:1626: incompatible format for placeholder 1: 's' and 'd' are not compatible error: ./zh/LC_MESSAGES/messages.po:3614: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:3728: unknown named placeholder 'name' error: ./zh/LC_MESSAGES/messages.po:4468: unknown named placeholder 'columns' error: ./zh/LC_MESSAGES/messages.po:5945: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:9381: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:9901: placeholders are incompatible error: ./zh/LC_MESSAGES/messages.po:10645: unknown named placeholder 'table_name' error: ./zh/LC_MESSAGES/messages.po:12956: positional format placeholders are unbalanced error: ./zh/LC_MESSAGES/messages.po:14236: positional format placeholders are unbalanced error: ./zh/LC_MESSAGES/messages.po:14245: positional format placeholders are unbalanced compiling catalog ./zh/LC_MESSAGES/messages.po to ./zh/LC_MESSAGES/messages.mo 16 errors encountered. (venv) gapinyc@DESKTOP-9QS7RL5:~/superset/venv/lib/python3.10/site-packages/superset/translations$ file zh/LC_MESSAGES/messages.mo zh/LC_MESSAGES/messages.mo: GNU message catalog (little endian), revision 0.0, 2474 messages, Project-Id-Version: Apache Superset 0.22.1 '\346\255\244\350\277\207\346\273\244\346\235\241\344\273\266\346\230\257\344\273\216\347\234\213\346\235\277\344\270\212\344\270\213\346\226\207\347\273\247\346\211\277\347\232\204\343\200\202\344\277\235\345\255\230\345\233\276\350\241\250\346\227\266\344\270\215\344\274\232\344\277\235\345\255\230\343\200\202' (venv) gapinyc@DESKTOP-9QS7RL5:~/superset/venv/lib/python3.10/site-packages/superset/translations$
10-28
你遇到的错误: ``` error: ./zh/LC_MESSAGES/messages.po:154: placeholders are incompatible ... 16 errors encountered. ``` 以及最后虽然生成了 `.mo` 文件,但 **很多翻译条目可能未生效或导致运行时异常**。 --- ## 🔍 错误原因:`.po` 文件中的 `msgstr` 占位符与 `msgid` 不匹配 这是 **Babel 的严格校验机制**在起作用。当原始英文字符串(`msgid`)中包含格式化占位符(如 `%s`, `%d`, `{name}`, `{0}` 等),而中文翻译(`msgstr`)里的占位符类型、数量或命名不一致时,`pybabel compile` 会报错并拒绝正确编译。 ### 示例说明 ```po msgid "User %s logged in %d times" msgstr "用户 %s 登录了 %d 次" ✅ 正确:两个位置参数 %s 和 %d 匹配 msgid "User %s logged in %d times" msgstr "用户 %s 登录了 %s 次" ❌ 错误:%d vs %s 类型不兼容 msgid "Hello {name}, you have {count} messages" msgstr "你好,{username}!" ❌ 错误:{name} 和 {count} 缺失,且 {username} 不存在于原文 ``` 这些都会触发: > `placeholders are incompatible` 或 `unknown named placeholder` --- ## ✅ 解决方案:修复 `.po` 文件中的占位符问题 ### 方法一:使用工具自动检查和修复(推荐) #### 使用 `msgfmt --check` 验证问题 ```bash msgfmt --check zh/LC_MESSAGES/messages.po ``` 如果没有安装 `gettext` 工具链,请先安装: ```bash # Ubuntu/Debian sudo apt-get install gettext # CentOS/RHEL sudo yum install gettext # 或者 dnf install gettext # macOS (Homebrew) brew install gettext ``` 然后运行验证: ```bash msgfmt -c -o /dev/null zh/LC_MESSAGES/messages.po ``` 输出将详细列出每一行的问题。 --- ### 方法二:手动查找并修复常见错误类型 #### 🔹 错误类型 1:`%s` vs `%d` 不兼容 比如这个错误: ``` error: ./zh/LC_MESSAGES/messages.po:1626: incompatible format for placeholder 1: 's' and 'd' are not compatible ``` 说明某一行用了 `%s` 但应该是 `%d`(字符串 vs 整数) 🔍 查找该行附近内容: ```bash sed -n '1620,1630p' zh/LC_MESSAGES/messages.po ``` 你会看到类似: ```po msgid "Deleted %d dashboards" msgstr "删除了 %s 个仪表板" ``` ❌ 错误:原文是 `%d`(整数),翻译用了 `%s`(字符串)→ 不兼容! ✅ 修正为: ```po msgstr "删除了 %d 个仪表板" ``` --- #### 🔹 错误类型 2:未知命名占位符(`unknown named placeholder`) 例如: ``` error: ./zh/LC_MESSAGES/messages.po:3728: unknown named placeholder 'name' ``` 说明你在 `msgstr` 中用了 `{name}`,但 `msgid` 中没有 `{name}`。 🔍 查看上下文: ```bash sed -n '3725,3730p' zh/LC_MESSAGES/messages.po ``` 可能是: ```po msgid "Hello {user}, welcome!" msgstr "你好 {name},欢迎!" ``` ❌ 错误:原文是 `{user}`,你写成了 `{name}` → 不合法! ✅ 修正为: ```po msgstr "你好 {user},欢迎!" ``` --- #### 🔹 错误类型 3:位置参数不平衡(`positional format placeholders are unbalanced`) ```po msgid "Added %s to %s successfully" msgstr "成功添加 %s" ``` ❌ 错误:原句有两个 `%s`,翻译只有一个 → 数量不匹配! ✅ 修正为: ```po msgstr "成功添加 %s 到 %s" ``` --- ## 🛠️ 推荐做法:下载经过验证的稳定版 `.po` 文件 GitHub 上的 `master` 分支有时包含开发中的变更,可能导致 `.po` 与当前 Superset 版本不兼容。 ### ✅ 建议:根据你的 Superset 版本选择对应 `.po` #### 步骤 1:查看当前 Superset 版本 ```bash superset --version # 输出示例:Superset 3.1.0 ``` #### 步骤 2:去 GitHub 找对应 tag 的 `.po` 文件 访问: ``` https://github.com/apache/superset/tree/v3.1.0/superset/translations/zh/LC_MESSAGES/ ``` 替换 `v3.1.0` 为你实际版本号。 然后点击 `messages.po` → Raw → 下载: ```bash curl -L https://raw.githubusercontent.com/apache/superset/v3.1.0/superset/translations/zh/LC_MESSAGES/messages.po \ --output zh/LC_MESSAGES/messages.po ``` 这样能避免 master 分支带来的格式冲突。 --- ## ✅ 最终安全流程(推荐执行) ```bash # 1. 进入目录 cd "$VIRTUAL_ENV/lib/python*/site-packages/superset/translations/" # 2. 删除旧文件 rm -f zh/LC_MESSAGES/messages.{po,mo} # 3. 下载指定版本的 messages.po(以 v3.1.0 为例) curl -L https://raw.githubusercontent.com/apache/superset/v3.1.0/superset/translations/zh/LC_MESSAGES/messages.po \ --output zh/LC_MESSAGES/messages.po # 4. 安装 gettext 并检查语法 sudo apt-get install gettext -y # 如果还没装 msgfmt -c -o /dev/null zh/LC_MESSAGES/messages.po || echo "有语法错误" # 5. 编译语言包 pybabel compile -d . -l zh # 6. 验证输出 file zh/LC_MESSAGES/messages.mo ``` 你应该看到: ``` compiling catalog ./zh/LC_MESSAGES/messages.po to ./zh/LC_MESSAGES/messages.mo ``` 并且 **没有任何 error 提示**。 --- ## 💡 补充建议:如何长期维护中文翻译? | 目标 | 方案 | |------|------| | 企业定制术语 | 修改 `.po` 后重新编译 | | 自动同步上游更新 | 写脚本定期拉取最新 `.po` 并校验 | | 贡献回社区 | Fork Apache Superset → 修改 `messages.po` → 提交 PR | --- ## ✅ 如何验证是否修复成功? 重启 Superset: ```bash pkill -f superset && superset run -h 0.0.0.0 -p 8088 --with-threads --reload ``` 访问: ``` http://your-ip/?lang=zh ``` 观察日志是否还有: ``` ERROR:superset.translations.utils:Error loading language pack for, falling back on en zh ``` ✅ 如果没有,且界面正常显示中文 → 成功! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值