lulalala
lulalala

Reputation: 17981

Rails I18n: calling different logic based on locale

I have a custom helper method which outputs the percentage saved. For example it will calculate the discount for an item and output "20 percent off".

I am localizing the site to Chinese, and in Chinese the same discount is expressed differently. "20% off" is expressed as "8 Cut" or "80% of original price". Since these two expression are quite different, I think I need to write two versions of the helper method.

Currently I wrote it like this, checking locale in the helper itself:

  def percent_off(discount, locale=I18n.locale)
      if not locale.to_s.include?('zh')
        n = ((1 - (discount.preferential_price / discount.original_price)) * 100) .to_i
        "#{n}% off"
      else
        # Chinese
        n = ((discount.preferential_price / discount.original_price) * 10) .to_i
        "#{n} cut"
      end
  end

Is there a better way to do this?

Upvotes: 1

Views: 523

Answers (2)

buruzaemon
buruzaemon

Reputation: 3907

You might want to refactor your code so that the calculation of the number used to represent the discount is separated from the selection/creation of your localized message.

Here is an idea along those lines:

In your en.yml:

  # value for "n% off"
  discount_msg: "%{n}% off!"

In your zh.yml:

  # value for "(100-n)% of original price"
  discount_msg: "%{n}% of original price (in Chinese)"

Next refactor the percent_off helper method so that it only calculates the correct value discount value depending upon the implied locale:

def percent_off(discount)  
  n = ((1 - (discount.preferential_price / discount.original_price)) * 100) .to_i    
  if I18n.locale.to_s.include?('zh')
    n = 100 - n
  end
  n
end

Then, you could invoke the above like this:

I18n.t('discount_msg', :n=>percent_off(discount))

Upvotes: 2

icanhazbroccoli
icanhazbroccoli

Reputation: 1035

The only bad thing gere in your helper I can see is that you write percent_off discount, but it's not evident what it'll return ( so I would create 2 different helper methods here.

Is I noted using locale check in views doesn't look pretty when you view blocks became completely different for different translations, so I've created an i18n helper method for that purpose:

module ApplicationHelper
  def translate_to(locales, &blk)
    locales = [locales.to_s] if !locales.is_a?(Array)
    yield if locales.include?(I18n.locale.to_s)
  end
  alias :tto :translate_to
end

and in views:

<% tto :en do %>
  <% # some en-translated routine %>
<% end %>
<% tto :zh do %>
  <% # zh-translated routine %>
<% end %>

Not sure it's a best way to manage translated blocks but I found it useful ))

Upvotes: 1

Related Questions