36

I want to make a translation my_translation with an optional parameter. For example:

> I18n.t('my_translation')
=> "This is my translation"
> I18n.t('my_translation', parameter: 1)
=> "This is my translation with an optional parameter which value is 1"

Is this possible?

j0k
  • 22,600
  • 28
  • 79
  • 90
Bishma Stornelli
  • 2,539
  • 4
  • 22
  • 30

4 Answers4

36

Yes, definitely. You just write the translations like this:

my_translation: This is my translation with an optional parameter which value is %{parameter}

Is the parameter really optional? In above translation, you have to provide all parameters.

UPDATE: Sorry, I answered too soon. I don't think it's easy to do. Maybe the easiest way is like this:

> I18n.t('my_translation1')
=> "This is my translation"
> I18n.t('my_translation2', parameter: 1)
=> "This is my translation with an optional parameter which value is 1"
Yanhao
  • 5,264
  • 1
  • 22
  • 15
  • Yes, it's optional. I want it to change depending if the parameter is present or not. Like in my example above. – Bishma Stornelli Nov 01 '12 at 14:16
  • Instead of being present or not, can the parameter always being passed? This way it'll be possible to do it with pluralization. BTW, are those values numbers? – Yanhao Nov 01 '12 at 15:12
  • 1
    No, it's a title of a report. I want to pass a date so it could be "My report on %{date}" if the parameter is passed or just "My report" if it's not. – Bishma Stornelli Nov 01 '12 at 16:04
19

I would say it is possible, though not recommended. You have two completely separate strings, based on your comments in @Yanhao's answer, and I would say they should be two separate entries in your yaml file:

report_name: My report
report_name_with_date: My report on %{date}

Since the existence of the date determines which string to display, you could perhaps test for its existence in in the params hash in a controller method, assign the title to a variable, and then use it in a view. Perhaps something like:

report_date = params[:report_date]
if report_date && report_date.is_a?(Date)
  @report_name = I18n.t('report_name_with_date', date: report_date.to_s)
else
  @report_name = I18n.t('report_name')
end

If you want behaviour exactly as you have described, you'd need two yaml entries anyway, and you'd have extra convolution, and you'd be doing a I18n no-no by creating a string by concatenating two strings together, which assumes a fixed grammatical sentence structure (not to mention this drives translators up the wall):

report_name_with_date: My report%{on_date}
on_date: on %{date}

with code something like this:

report_date = params[:report_date]
if report_date && report_date.is_a?(Date)
  on_date = I18n.t('on_date', date: report_date.to_s)
  @report_name = I18n.t('report_name_with_date', on_date: " #{on_date}")
else
  @report_name = I18n.t('report_name_with_date', on_date: nil)
end

So, in summary, I'd say go with two separate whole strings, like in the first example.

Paul Fioravanti
  • 16,423
  • 7
  • 71
  • 122
3

This is the way i did it!

  1. First set my translation

    I18n.t('my_translation', parameter: optional_parameter)
    
  2. Check if value is nil

    optional_parameter = value.nil? "" : "with an optional parameter which value is #{value}"
    I18n.t('my_translation', parameter: optional_parameter)
    
    • if value is nil =>"This is my translation"
    • if value is 1 => "This is my translation with an optional parameter which value is 1"
Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
1

If you're using a number as an optional argument, Rails provides a better way to handle it.

e.g.

  invoice:
    zero: "Great! You have no pending invoices."
    one: "You have only 1 pending invoice."
    other: "You have %{count} pending invoices."
  
  >> t("invoice", count: 0) 
  => Great! You have no pending invoices.

  >> t("invoice", count: 1)
  => You have only 1 pending invoice.

  >> t("invoice", count: 5) 
  => You have 5 pending invoices.
Datt
  • 851
  • 9
  • 21