36

This might be I18n-ception but lets say I have an en.yml file as below

en:
  my_var: Foo
  my_message: "This is a message where I'd like to interpolate I18n's %{my_var}"

Is there a way to indicate to I18n that %{my_var} should be the my_var key in en.yml?

I know I could accomplish it by doing something like

I18n.t 'my_message', :my_var => I18n.t('my_var')

but I was hoping I18n has a way to self reference keys.

Aaron
  • 13,349
  • 11
  • 66
  • 105

3 Answers3

42

This is actually a pretty common question, but the short answer is no, this isn't possible unfortunately :(

tigrish
  • 2,488
  • 18
  • 21
  • 4
    This is the correct answer, unfortunately. For your reference @Aaron, see SO questions/answers [here](http://stackoverflow.com/q/13055753/567863) and [here](http://stackoverflow.com/q/13937891/567863). – Paul Fioravanti Jan 14 '13 at 01:09
  • 1
    Is this answer actually right? Still having no way to do it? – joaofraga Jun 15 '16 at 17:59
5

Currently I struggle for it... And finally I create a custom yaml type.

in init section.

Psych.add_builtin_type('i18n') { |_type, value|
  ->(_key, _options) do
    value.gsub(/%\{([\w.]+)\}/) do |match|
      key = $1.to_sym
      if I18n.exists?(key)
        I18n.t(key)
      else
        match
      end
    end
  end
}
I18n.reload!

in en.yml

en:
  my_var: Foo
  my_message: !!i18n "This is a message where I'd like to interpolate I18n's %{my_var}"

!!i18n apply custom builtin type.

odk
  • 51
  • 1
  • 4
  • 1
    Very cool! I'll have to read up on Psych and `add_builtin_type` to fully understand the performance characteristics but this looks like a great patch. – Aaron Mar 10 '16 at 15:50
2

As you said, maybe it is not a so straight solution to call twice from the view to the translation

<%= t("my_message", my_var: t("my_var") ) %>

but gives you the flexibility to call with a variable

<%= t("my_message", my_var: t("my_#{$item[:slug]}") ) %>
yondemon
  • 51
  • 5