rails i18n adjectives - ruby-on-rails

I'm currently stuck with a small but not so uncommon problem in rails i18n ( hopefully I just haven't used the wrong search terms...)
In a standard rails crud app, you often have models like "contract", "group" etc..
So far, if you want a button for "new group" oder "new contract", this is simple in the english language, since it's basically always something like "new" + model_name.
Unfortunately, languages like german are not so computer-friendly :)
"new contract" translates to "neuer vertrag" while "new group" translates to "neue gruppe" (note the adjective change).
So, no problem with pluralisation this time but with adjective changes.
Is there any rails i18n support for such cases?
Don't want to use ugly i18n concatenation :)
thanks a lot!

just to understand your question correctly, you don't want to translate 'new' to german?
What is wrong with:
en:
new_contract: New contract
new_group: New group
de:
new_contract: Neuer Vertrag
new_group: Neue Gruppe
This is the standard way to do it and I don't see any advantage of DRYing up the 'new'. You remove something from the context there. Btw. you have this problem in a lot of languages. It is not possible to translate an adjective just once and then reuse, since it belongs to another word (cannot stand in its own context).
I would definitely go with the approach above.

Related

Rails admin views' titles & views' links

I'm working with a RESTful Rails App since long time ago.
But this week I received a requirement to change the titles for a Rails App. I think it could be easy. But I'm reading the views (in hamlet)
And found the titles are not written and come from other place. I found they use things like:
label: t("common.email")
f.input :password_confirmation,
ep.check_box :followed_issues
link_to t('common.profile'), csn_profile_path
I wrote a lote of code in rails' controllers but this is the first time I'm trying to understand rails views. Is this standard? Where can I find all this information? is this the way to do?
I think what you are looking for is Rails internationalization.
The internationalization allows use the same views but with different languages. You can find the translations in config/local/, there you will find one yml file per language.
So, when you use t("common.email") it will search the translation in config/local/[language_abbreviation].yml
For example en.yml should look like:
common:
welcome: "Welcome to my page"
email: "Email"
bye: "Bye bye"
And, at the same time es.yml:
common:
welcome: "Bienvenido a mi pagina"
email: "Correo electronico"
bye: "Adios"
Thus, you only need to find the translation and change it for each language and it will change the titles in the views.

I18n to call different Model Attribute depending on Locale?

So I am building an on-line shop and I want two language options, English and Spanish.
I am using I18n as you would normally do for all my static text and headings ect.
But, I have a products Model that can have new Products created for listing on the site. This has fields like :name_en and :name_es, :description_en and :description_es ect.
When the admin uploads a new product they obviously need to add the English and the Spanish text.
Because I have only 2 locales what I would like to do i think is call something like
<%= Product.name_"#{I18n.locale.downcase}" %>
But obviously this does not work. How can i, or just can I, interpolate a method or Attribute?
Have I missed something obvious here and just going about it the wrong way or is there a way to do this along the lines of my thinking?
Any Help massively appreciated.
Thanks
You can use send method. Try something like:
<%= Product.send("name_#{I18n.locale.downcase}") %>
Just a word of explanation, the following are equal:
string = "Hello"
string.upcase
# => "HELLO"
string.send("upcase")
# => "HELLO"
Hope that puts you in proper direction!
Good luck!

Using a/an on an I18n message

I have the following error message on my en.yml file:
invalid_transition: "Cannot %{action} a %{state} timesheet"
Problem is that sometimes the state can be approved, other times it can be rejected.
With that, the error can end up being mispelled like "Cannot submit a approved timesheet", instead of "an approved timesheet".
Does Rails provide this flexibility in I18n?
The most simple answer to your question, I think, would be to pass in the entire state with the correct indefinite article together.
There's a question that looks at how to prepend "a" or "an" depending on a given word. A short answer is that there's a gem indefinite_article that does it.
Your translation then becomes:
invalid_transition: "Cannot %{action} %{state_with_article} timesheet"
Then call the I18n.t and pass in "a rejected" or "an approved" as a variable to interpolate.
However, if you want to get your hands a bit dirtier you may be able to use the i18n-inflector gem and it's companion i18n-inflector-rails gem. For many languages the choice is more complicated than in English because of different genders and tenses affecting the choice of indefinite article. (Disclaimer: I've not used either of those gems but they look like they would help you solve the problem).

Keeping track of changes using rails - "changed?"

I am building a multi lingual website, using ruby on rails, where part of the content is supposed to be user generated and they are supposed to be able to create different versions of it for all languages. The language support is handled by i18n gem.
Part of their content is created using Markdown through http://daringfireball.net/projects/markdown/basics .
In my database I save: object.content_markdown_en, object.content_html_en, object.content_markdown_sv, object.content_html_sv and so on for the different locales.
Now if a user changes the content, new html is supposed to be generated. But it seems unnecessary to regenerate the html for all locales if he only made changes in one of the languages.
I thought there might be some way to use something like
if object.content_markdown_[locale]_changed?
generate_new_html
end
that can be run in a loop for all possible locales. But I can't find any nice ways of doing this.
How about:
[:en, :sv].each do |locale|
if object.send("content_markdown_#{ locale }_changed?".to_sym)
send("generate_new_#{ locale }_html".to_sym)
end
end
You can use send to call methods by name:
object.send("content_markdown_#{locale}_changed?".to_sym)
Your loop would look like this:
%w(en sv).each { |locale|
if object.send("content_markdown_#{locale}_changed?".to_sym)
generate_new_html
end
}
However, using a separate translation table might be a better approach.

Shortest way of determining a name ends with an `s`, `x` or `z`, and then use the `I18n.t` method with it

I'm creating a Rails application where users can have a first and last name. Since I'm a perfectionist, the application may not show something like Dennis's profile or Xianx's profile, but rather Dennis' profile and Xianx' profile. I use I18n, so I wanted to ask what is the shortest way of implementing this? This grammar is the same for both English and Dutch, where the application will be translated to.
Oh, some important things:
I am not afraid of using helpers and the application controller
My language files are in Ruby, not YAML
Thanks!
It's hard to be perfect in Dutch
def having_s( word ) # maybe genitiv_s is a better name
case word[-1,1] # [-1] will do in ruby 1.9
when 's', 'x', 'z'
"#{word}'"
else
"#{word}'s"
end
end
names=%w(Alex Inez Kees Maria Bordeaux)
names.each{|name| puts having_s(name)}
The last testcase ("Bordeaux") yields a wrong result, according to this.
One way to implement this with little risk of not being correct:
Instead of:
Person X's profile
Do:
Profile: Person X
There's not going to be a way to do the first for all languages/countries/cultures. The 2nd option may not look ideal, but you won't ever present anything incorrectly.

Resources