Rails I18n 翻译范围
Rails I18n translations scoping
编写完全翻译的应用程序可能会很乏味。有没有办法为当前上下文设置默认翻译范围?
示例:我正在 show.html.erb 的部分 _deadlines.html.erb 16=]
现在因为我想成为一名优秀的程序员,所以我正在确定我所有翻译的范围。我想生成下面的树
projects:
deadlines:
now: "Hurry the deadline is today !"
....
我怎样才能让它比每次都写整个范围更不乏味?
projects/show.html.erb
...
<%= render 'projects/deadlines', project: @project %>
...
projects/_deadlines.html.erb 从 show.html.erb
调用
<p>Deadline : <%= t(:now, scope: [:projects, :deadlines]) %></p>
有没有办法为当前上下文设置默认范围(这里是整个 _deadlines.html.erb 文件)?
编辑
有些人建议使用 Rails Lazy lookup,但这不会产生我正在寻找的范围。在我的例子中,我想跳过 action
默认范围(显示、索引等...)并为我正在渲染的当前部分添加一个范围(在我的例子中 _deadlines.html.erb)
Rails 惰性查找:
t('.now')
<=> t(:now, scope: [:projects, :show]
但我想要:
t('.now')
<=> t(:now, scope: [:projects, :deadlines]
Rails 实现了一种在视图中查找语言环境的便捷方法。
当你有以下字典时:
es:
projects:
index: # in 'index.html.erb' template file
title: "Título"
deadlines: # in '_deadlines.html.erb' partial file
title: "Fecha límite"
您可以按如下方式查找这些值:
# app/views/projects/index.html.erb
<%= t '.title' %> # => "Título"
# app/views/projects/_deadlines.html.erb
<%= t '.title' %> # => "Fecha límite"
好吧,我其实还是不满意这个。当你想在不同的地方翻译同样的东西时,这个默认的 'lazy lookup' 范围完全是废话。假设我有两个不同的部分,其中包含处理同一模型的信息。使用惰性查找,我需要在我的 yml 文件中进行两次相同的翻译。
这是您可以放入应用程序助手中的一小段代码。它基本上是对默认值 I18n.t 的覆盖,它将在定义时将范围设置为 @t_scope
,您无需再担心范围
我的代码添加
helpers/application_helper.rb
def t(*args)
# If there is just one param and we have defined a translation scope in the view
# only using symbols right now, need extended version to handle strings
if args.size == 1 and args.first.is_a?(Symbol) and @t_scope
super(args.shift, @t_scope)
else
super(*args)
end
end
def set_t_scope(scope)
push_t_scope(@t_scope ||= {})
replace_t_scope(scope)
end
alias :t_scope :set_t_scope
def replace_t_scope(scope)
@t_scope = {scope: scope}
end
def push_t_scope(scope)
(@tscope_stack ||= []) << scope
end
def pop_t_scope
@t_scope = @tscope_stack.pop
end
你可以用它做什么
projects/show.html.erb
<%= t_scope([:projects, :deadlines]) %>
<fieldset>
<legend>Deadlines</legend>
<% if Time.now > @project.deadline.expected_finish_date %>
<p><%= t(:hurry) %></p>
<% else %>
<p><%= t(:you_have_time) %>
</fieldset>
<fieldset>
<legend>Deadlines</legend>
<%= render 'tasks', tasks: @project.tasks %>
...
views/projects/_tasks.html.erb
<%= t_scope([:projects, :tasks]) %>
<% tasks.each do | task| %>
<h2><%= t(:person_in_charge) %></h2>
...
<% pop_t_scope %>
en.yml
en:
projects:
deadlines:
hurry: "Hurry man !"
you_have_time: "Relax, there's still time"
tasks:
person_in_charge: 'The Boss is %{name}'
现在我看到的唯一问题是,当从一个视图中渲染多个部分时,@t_scope 将被转移并且可能会导致问题。但是,在每个文件的开头将@t_scope 设置为nil 不会有问题
由于 t('.foo')
是可能的并且可能有选项(例如用于插值),这是我改进
的建议
def t(*args, **kwargs)
if args.size == 1 and (args.first.is_a?(Symbol) || args.first.to_s.start_with?('.') ) and @t_scope
I18n.t(args.shift, kwargs.reverse_merge!(@t_scope))
else
I18n.t(*args)
end
end
编写完全翻译的应用程序可能会很乏味。有没有办法为当前上下文设置默认翻译范围?
示例:我正在 show.html.erb 的部分 _deadlines.html.erb 16=]
现在因为我想成为一名优秀的程序员,所以我正在确定我所有翻译的范围。我想生成下面的树
projects:
deadlines:
now: "Hurry the deadline is today !"
....
我怎样才能让它比每次都写整个范围更不乏味?
projects/show.html.erb
...
<%= render 'projects/deadlines', project: @project %>
...
projects/_deadlines.html.erb 从 show.html.erb
调用<p>Deadline : <%= t(:now, scope: [:projects, :deadlines]) %></p>
有没有办法为当前上下文设置默认范围(这里是整个 _deadlines.html.erb 文件)?
编辑
有些人建议使用 Rails Lazy lookup,但这不会产生我正在寻找的范围。在我的例子中,我想跳过 action
默认范围(显示、索引等...)并为我正在渲染的当前部分添加一个范围(在我的例子中 _deadlines.html.erb)
Rails 惰性查找:
t('.now')
<=> t(:now, scope: [:projects, :show]
但我想要:
t('.now')
<=> t(:now, scope: [:projects, :deadlines]
Rails 实现了一种在视图中查找语言环境的便捷方法。 当你有以下字典时:
es:
projects:
index: # in 'index.html.erb' template file
title: "Título"
deadlines: # in '_deadlines.html.erb' partial file
title: "Fecha límite"
您可以按如下方式查找这些值:
# app/views/projects/index.html.erb
<%= t '.title' %> # => "Título"
# app/views/projects/_deadlines.html.erb
<%= t '.title' %> # => "Fecha límite"
好吧,我其实还是不满意这个。当你想在不同的地方翻译同样的东西时,这个默认的 'lazy lookup' 范围完全是废话。假设我有两个不同的部分,其中包含处理同一模型的信息。使用惰性查找,我需要在我的 yml 文件中进行两次相同的翻译。
这是您可以放入应用程序助手中的一小段代码。它基本上是对默认值 I18n.t 的覆盖,它将在定义时将范围设置为 @t_scope
,您无需再担心范围
我的代码添加
helpers/application_helper.rb
def t(*args)
# If there is just one param and we have defined a translation scope in the view
# only using symbols right now, need extended version to handle strings
if args.size == 1 and args.first.is_a?(Symbol) and @t_scope
super(args.shift, @t_scope)
else
super(*args)
end
end
def set_t_scope(scope)
push_t_scope(@t_scope ||= {})
replace_t_scope(scope)
end
alias :t_scope :set_t_scope
def replace_t_scope(scope)
@t_scope = {scope: scope}
end
def push_t_scope(scope)
(@tscope_stack ||= []) << scope
end
def pop_t_scope
@t_scope = @tscope_stack.pop
end
你可以用它做什么
projects/show.html.erb
<%= t_scope([:projects, :deadlines]) %>
<fieldset>
<legend>Deadlines</legend>
<% if Time.now > @project.deadline.expected_finish_date %>
<p><%= t(:hurry) %></p>
<% else %>
<p><%= t(:you_have_time) %>
</fieldset>
<fieldset>
<legend>Deadlines</legend>
<%= render 'tasks', tasks: @project.tasks %>
...
views/projects/_tasks.html.erb
<%= t_scope([:projects, :tasks]) %>
<% tasks.each do | task| %>
<h2><%= t(:person_in_charge) %></h2>
...
<% pop_t_scope %>
en.yml
en:
projects:
deadlines:
hurry: "Hurry man !"
you_have_time: "Relax, there's still time"
tasks:
person_in_charge: 'The Boss is %{name}'
现在我看到的唯一问题是,当从一个视图中渲染多个部分时,@t_scope 将被转移并且可能会导致问题。但是,在每个文件的开头将@t_scope 设置为nil 不会有问题
由于 t('.foo')
是可能的并且可能有选项(例如用于插值),这是我改进
def t(*args, **kwargs)
if args.size == 1 and (args.first.is_a?(Symbol) || args.first.to_s.start_with?('.') ) and @t_scope
I18n.t(args.shift, kwargs.reverse_merge!(@t_scope))
else
I18n.t(*args)
end
end