nifty-generators
nifty-generators copied to clipboard
Model translation in the message header
I used nifty-geberators gem on before-3.0* Rails version, all the translations worked fine. After passing to Rails 3.0.5, nifty-generators 0.4.5, i18n 0.5.0, Ruby 1.9.2p180, I can't figure out how to achive the translation of error meassage header wher the name of the model should be translated. Without using the nifty-generators gem, I solved it as follows in my view:
<%= form_for(@user) do |f| %> <% if @user.errors.any? %> <div id="error_explanation"> <h2><%= t('errors.template.header', :model=> @user.class.human_name, :count=> @user.errors.count) %></h2> <ul> <% @user.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %>
I changed nothing in the translation YAML file downloaded from Github https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale except adding some model-specific translation and its attributes. How can i modify the 'error_messages_helper.rb' file or what to pass from the view to solve the problem? Thanks.
Hi, Ryan!
I fixed the headr translation as follows for the moment:
#in a form partial, for example
<%= form_for @user do |f| %>
<%= f.error_messages(:header_message => t('errors.template.header', :model=> @user.class.model_name.human, :count=> @user.errors.count), :message => t('errors.template.body')) %>
<p>
<%= f.label t 'activerecord.attributes.user.firstname' %><br />
<%= f.text_field :firstname %>
</p>
<p>
<%= f.label t 'activerecord.attributes.user.lastname' %><br />
<%= f.text_field :lastname %>
</p>
<p><%= f.submit %></p>
<% end %>
what means that I have to use the same tecnhic to pass parameter from the view to the translation file as I did in any other RoR application that doen't use nifty_generators gem. May be it is not DRY enough. Would it be better to modify directly the ErrorMessages helper ? Thanks & regards
The helper in NiftyGenerators has a translation like this: activerecord.errors.header
and activerecord.errors.message
so you'll need to adjust those in your en.yml
file. Does setting those translations work?
So what your'e showing here is the previous translation keys Rails 2 used? Maybe they should be changed to match that.
In yml translation file that I downloaded from https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale, there is no more activerecord.errors.header but errors.template.header instead. The 'activerecord' tree is defined as follows:
activerecord: models: user: "Utilisateur" attributes: user: firstname: "Prénom" lastname: "Nom" errors: messages: taken: "n'est pas disponible" record_invalid: "La validation a échoué : %{errors}"
and 'errors' tree is defined as follows:
errors: format: "%{attribute} %{message}" messages: &errors_messages inclusion: "n'est pas inclus(e) dans la liste" exclusion: "n'est pas disponible" invalid: "n'est pas valide" confirmation: "ne concorde pas avec la confirmation" accepted: "doit être accepté(e)" empty: "doit être rempli(e)" blank: "doit être rempli(e)" too_long: "est trop long (pas plus de %{count} caractères)" too_short: "est trop court (au moins %{count} caractères)" wrong_length: "ne fait pas la bonne longueur (doit comporter %{count} caractères)" not_a_number: "n'est pas un nombre" not_an_integer: "doit être un nombre entier" greater_than: "doit être supérieur à %{count}" greater_than_or_equal_to: "doit être supérieur ou égal à %{count}" equal_to: "doit être égal à %{count}" less_than: "doit être inférieur à %{count}" less_than_or_equal_to: "doit être inférieur ou égal à %{count}" odd: "doit être impair" even: "doit être pair" template: &errors_template header: one: "Impossible d'enregistrer %{model} : 1 erreur" other: "Impossible d'enregistrer %{model} : %{count} erreurs" body: "Veuillez vérifier les champs suivants : "
That's why I modified the 'ErrorMessagesHelper' as follows:
module ErrorMessagesHelper # Render error messages for the given objects. The :message and :header_message options are allowed. def error_messages_for(*objects) options = objects.extract_options! error_object = objects[0] options[:header_message] ||= I18n.t('errors.template.header', :model=> error_object.class.model_name.human, :count=> error_object.errors.count) options[:message] ||= I18n.t('errors.template.body') # options[:header_message] ||= I18n.t(:"activerecord.errors.header", :default => "Invalid Fields") # options[:message] ||= I18n.t(:"activerecord.errors.message", :default => "Correct the following errors and try again.") ``` messages = objects.compact.map { |o| o.errors.full_messages }.flatten unless messages.empty? content_tag(:div, :class => "error_messages") do list_items = messages.map { |msg| content_tag(:li, msg) } content_tag(:h2, options[:header_message]) + content_tag(:p, options[:message]) + content_tag(:ul, list_items.join.html_safe) end end ``` end module FormBuilderAdditions def error_messages(options = {}) @template.error_messages_for(@object, options) end end end ActionView::Helpers::FormBuilder.send(:include, ErrorMessagesHelper::FormBuilderAdditions)
May be there is a better solution ?
Hmm, so it looks like it shouldn't go under the activerecord namespace. I'll consider changing this in the nifty:layout generator.
@ryanb I just wanted to place my support here for this problem, but I don't think the solution of @javix is correct.
As far as I can see, errors still go in the activerecord namespace, see: https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en-US.yml
Some more problems I am running into with the ErrorMessagesHelper:
-
activerecord.errors.header
has now been changed toactiverecord.errors.template.header
-
activerecord.errors.message
has been replaced byactiverecord.errors.template.body
-
Model and attribute names aren't translated
This is the returned error: Users email can't be blank
While this is in my en-US.yml:
en:
activerecord:
models:
user: "person"
attributes:
user:
email: "e-mail"
Any thoughts on this?
Actually, it seems my issues had to do with nested_forms, which is kind of weird:
The above didn't work, but this will:
activerecord:
attributes:
website:
domain: "domein"
users:
email: "e-mail"
password_digest: "wachtwoord"
user:
email: "e-mail"
password_digest: "wachtwoord"
errors:
template:
header:
one: "%{model} niet opgeslagen: 1 fout gevonden"
other: "%{model} niet opgeslagen: %{count} fouten gevonden"
body: "Controleer de volgende velden:"
Though I wonder if this isn't something that should be fixed/changed in Rails. It isn't exactly DRY in this case, because I have to declare the attributes again for each nested field, but I don't see any reason why a nested form field should be named different than a regular field.
edit: seems this method is soon to be deprecated, not sure if there will be some replacement for this though, see: https://github.com/rails/rails/issues/1869
@JeanMertz thanks for looking into this issue. I hope to spend some time on it soon and find a good fix. If you do find a concrete solution feel free to submit a pull request.