What does the percent sign mean in Yaml? - ruby-on-rails

I noticed that in the i18n rails guide, they have the following code:
en:
activerecord:
errors:
template:
header:
one: "1 error prohibited this %{model} from being saved"
other: "%{count} errors prohibited this %{model} from being saved"
body: "There were problems with the following fields:"
What do the %{...} mean? How is this different from #{...}?

If you read the guide a little more, you'll come across the Passing variables to translations section:
You can use variables in the translation messages and pass their values from the view.
# app/views/home/index.html.erb
<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %>
# config/locales/en.yml
en:
greet_username: "%{message}, %{user}!"
and the Interpolation section:
In many cases you want to abstract your translations so that variables can be interpolated into the translation. For this reason the I18n API provides an interpolation feature.
All options besides :default and :scope that are passed to #translate will be interpolated to the translation:
I18n.backend.store_translations :en, :thanks => 'Thanks %{name}!'
I18n.translate :thanks, :name => 'Jeremy'
# => 'Thanks Jeremy!'
So the %{...} stuff doesn't have anything to do with YAML, that's I18n's way of handling variable interpolation in the messages.

Related

Rails I18n: error 'translation missing' when i try translate this words "off"

Why I can't translate this word?
config/locales/pt-BR.yml
pt-BR:
testing:
off: 'Desligado'
offff: 'Test'
rails console
> I18n.t 'testing.offff'
=> "Test"
> I18n.t 'testing.off'
=> "translation missing: pt-BR.testing.off"
Special words are restricted such as
'true, false, yes, no, on, off'
Juste change the key 'off' to something else, which is not restricted.
The doc about booleans in YAML

Ruby: CSV to YAML

I have the following csv example:
en.activerecord.models.admin_user.one;Guide
en.activerecord.models.admin_user.other;Guides
en.simple_captcha.placeholder;Type here
Is there a ruby gem or method to turn it into a Yaml file:
en:
activerecord:
models:
admin_user:
one: Guide
other: Guides
simple_captcha:
placeholder: Type here
I'm still trying (using tree data model) but no results.
Any idea?
require 'yaml'
hash = {}
file = "en.activerecord.models.admin_user.one;Guide
en.activerecord.models.admin_user.other;Guides
en.simple_captcha.placeholder;Type here"
file.split("\n").each { |line| hash.deep_merge!(line.split(/\.|;/).reverse.inject() { |m,v| {v => m} }) }
puts YAML.dump(hash)
---
en:
activerecord:
models:
admin_user:
one: Guide
other: Guides
simple_captcha:
placeholder: Type here

Attribute translation in Rails

So the issue I've encountered days ago still makes me unconfortable with my code. I can't get proper translation for my application: Yml looks like that:
pl:
errors: &errors
format: ! '%{attribute} %{message}'
messages:
confirmation: nie zgadza się z potwierdzeniem
activemodel:
errors:
<<: *errors
activerecord:
errors:
<<: *errors
And model looks like that:
module Account
class User < ActiveRecord::Base
attr_accessor: password_confirmation
end
end
And flash in controller declared:
flash[:errors] = #user.errors.full_messages
I tried and read activerecord documentation and stack previous questions (How to use Rails I18n.t to translate an ActiveRecord attribute?, Translated attributes in Rails error messages (Rails 2.3.2, I18N)). Yet it still doesn't work as I wanted.
password_confirmation remains "Password Confirmation", and not "Potwierdzenie hasła" as it shoul be. The screenshot might explain it better: http://i42.tinypic.com/1glz5.png
Your User model is in a namespace, thus you have to declare the namespace in your translation file also. Try the following to get the correct translation for password_confirmation:
pl:
activerecord:
attributes:
account/user:
password_confirmation: "Potwierdzenie hasła"

How to translate default error messages in rails?

This not worked for me when i tried to change error_messages_for messages in translation.yml file:
activerecord:
errors:
template:
header:
one: "Oops error"
other: "Many errors"
body: "There were problems:"
What can i do to translate "1 error prohibited this product from being saved:"? What file contain their text?
I believe you only need the activerecord: part if you're on Rails 2.x. The problem may be that your top level wasn't a language. As of Rails 3.x (which uses the separate dynamic_form plugin now to handle this), the defaults are:
en:
errors:
template:
header:
one: "1 error prohibited this %{model} from being saved"
other: "%{count} errors prohibited this %{model} from being saved"
# The variable :count is also available
body: "There were problems with the following fields:"

I18n: How to check if a translation key/value pairs is missing?

I am using Ruby on Rails 3.1.0 and the I18n gem. I (am implementing a plugin and) I would like to check at runtime if the I18n is missing a translation key/value pairs and, if so, to use a custom string. That is, I have:
validates :link_url,
:format => {
:with => REGEX,
:message => I18n.t(
'custom_invalid_format',
:scope => 'activerecord.errors.messages'
)
}
If in the .yml file there is not the following code
activerecord:
errors:
messages:
custom_invalid_format: This is the test error message 1
I would like to use the This is the test error message 2. Is it possible? If so, how can I make that?
BTW: For performance reasons, is it advisable to check at runtime if the translation key/value pairs is present?
You could pass a :default parameter to I18n.t:
I18n.t :missing, :default => 'Not here'
# => 'Not here'
You can read more about it here.
I just had the same question and I want to compute an automatic string in case the translation is missing. If I use the :default option I have to compute the automatic string every time even when the translation is not missing. So I searched for another solution.
You can add the option :raise => true or use I18n.translate! instead of I18n.translate. If no translation can be found an exception is raised.
begin
I18n.translate!('this.key.should.be.translated', :raise => true)
rescue I18n::MissingTranslationData
do_some_resource_eating_text_generation_here
end
I don't know how to this at runtime but you can use rake to find it out. You'll have create your own rake task for that. Here's one:
namespace :i18n do
desc "Find and list translation keys that do not exist in all locales"
task :missing_keys => :environment do
def collect_keys(scope, translations)
full_keys = []
translations.to_a.each do |key, translations|
new_scope = scope.dup << key
if translations.is_a?(Hash)
full_keys += collect_keys(new_scope, translations)
else
full_keys << new_scope.join('.')
end
end
return full_keys
end
# Make sure we've loaded the translations
I18n.backend.send(:init_translations)
puts "#{I18n.available_locales.size} #{I18n.available_locales.size == 1 ? 'locale' : 'locales'} available: #{I18n.available_locales.to_sentence}"
# Get all keys from all locales
all_keys = I18n.backend.send(:translations).collect do |check_locale, translations|
collect_keys([], translations).sort
end.flatten.uniq
puts "#{all_keys.size} #{all_keys.size == 1 ? 'unique key' : 'unique keys'} found."
missing_keys = {}
all_keys.each do |key|
I18n.available_locales.each do |locale|
I18n.locale = locale
begin
result = I18n.translate(key, :raise => true)
rescue I18n::MissingInterpolationArgument
# noop
rescue I18n::MissingTranslationData
if missing_keys[key]
missing_keys[key] << locale
else
missing_keys[key] = [locale]
end
end
end
end
puts "#{missing_keys.size} #{missing_keys.size == 1 ? 'key is missing' : 'keys are missing'} from one or more locales:"
missing_keys.keys.sort.each do |key|
puts "'#{key}': Missing from #{missing_keys[key].join(', ')}"
end
end
end
put the given in a .rake file in your lib/tasks directory and execute:
rake i18n:missing_keys
Information source is here and code on github here.
If you wish to pass variable to the message like This is the test error message {variable}
This is possible using variable in language file like below.
# app/views/home/index.html.erb
<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %>
# config/locales/en.yml
en:
greet_username: "%{message}, %{user}!"
More description you can find here.

Resources