给出以下i18n密钥:
greeting: "Hi %{name}! Feeling %{adjective}?"
如果我致电I18n.t!("greeting", adjective: "strigine")
,我会收到例外:I18n::MissingInterpolationArgument
。这很好。
但是,如果我根本没有传递任何参数,我只需要获取原始字符串。
I18n.t!("greeting") # => "Hi %{name}! Feeling %{adjective}?"
我想确保不会发生这种情况。 如果没有给出参数,是否会引发此方法调用的版本,或者我是否必须自己编写代码?
答案 0 :(得分:0)
原因是documented in the tests如下:
如果没有给出插值参数,I18n不应改变 串。这种行为有三个原因:
- 检查所有字符串中的插值键会严重影响性能;
- 这允许我们通过I18n检索未触摸的值。例如,我可以有一个返回I18n查找结果的中间件 JSON将通过Javascript进行处理。离开钥匙不动 允许插值在javascript级别发生;
- 安全问题:如果我允许用户翻译网站,他们可以在消息中插入%{},导致I18n查找失败 请求。
如果在这种情况下需要例外,可以定义如下方法:
# Needed because I18n will happily return the raw template string if given
# no interpolation arguments
# https://github.com/svenfuchs/i18n/blob/v0.7.0/lib/i18n/tests/interpolation.rb#L6-L21
def i18n_strict_t!(key, options = {})
localized = I18n.t!(key, options)
if missing = localized.match(I18n::INTERPOLATION_PATTERN)
fail I18n::MissingInterpolationArgument.new(
missing.captures.first, options, localized
)
end
localized
end
用法:
i18n_strict_t!("greeting")
# => I18n::MissingInterpolationArgument: missing
# interpolation argument "name" in
# "Hi %{name}! Feeling %{adjective}?" ({} given)
i18n_strict_t!("greeting", name: "Carla", adjective: "taciturn")
# => "Hi Carla! Feeling taciturn?"
或者更慢但更简单的实施:
def i18n_strict_t!(key, options = {})
options[:force_interpolation] = true if options.empty?
I18n.t!(key, options)
end