You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:11:37