Phoenix应用中如何用Gettext翻译数据库中的材料名称?
这个问题我之前也碰到过!核心原因是Gettext的工作机制——它是编译时提取静态字符串来生成翻译条目,动态拼接的#{material.name}在编译阶段根本不会被识别,自然找不到对应的翻译。下面给你一步步解决的方案:
解决方案步骤
1. 先让Gettext识别所有需要翻译的材料名称
Gettext只会扫描代码里的静态字符串来生成.po翻译文件,所以你得把所有可能的材料名称用gettext_noop标记出来,这样提取工具才能抓到它们。
找个合适的地方(比如你的材料模块lib/amazing_app/material.ex,或者专门的翻译辅助模块)添加这些标记:
defmodule AmazingApp.Material do # 导入Gettext方便使用 import AmazingApp.Gettext # 把所有数据库里的材料名称都列在这里,用gettext_noop标记 gettext_noop("cotton") gettext_noop("wood") gettext_noop("wool") gettext_noop("kapok") # 其他材料名称依次添加... end
然后运行提取命令,让Gettext把这些字符串写入.po文件:
mix gettext.extract mix gettext.merge priv/gettext
这时候你就能在priv/gettext/materials/对应的语言文件里看到这些材料名称,接下来就可以添加对应的翻译内容了。
2. 修改模板代码,直接传入变量
现在这些材料名称已经在翻译文件里存在了,模板里不需要再用字符串插值,直接传material.name给dgettext就行:
<%= for material <- @materials do %> <td><%= AmazingApp.Gettext.dgettext("materials", material.name) %></td> <% end %>
注意:material.name的值必须和你用gettext_noop标记的字符串完全一致(大小写、拼写都不能错),否则Gettext会返回原字符串。
3. 处理未翻译的边缘情况
如果数据库里突然新增了一个没标记过的材料名称,Gettext会直接返回原名称。如果你想做个提示或者自定义处理,可以加个简单的判断:
<%= for material <- @materials do %> <td> <%= translated = AmazingApp.Gettext.dgettext("materials", material.name) %> <%= if translated == material.name do %> <%# 没有找到翻译,这里可以显示原名称或者加个小标记 %> <%= material.name %> <span class="text-gray-500">(未翻译)</span> <% else %> <%= translated %> <% end %> </td> <% end %>
这样就能完美解决动态变量的翻译问题啦!
内容的提问来源于stack exchange,提问作者Alisso
相关产品推荐
相关产品推荐

