Reputation: 1660
I am starting a project, and plan on keeping strings separated out by using the en.yml file. I am keeping strings organised by controller and action, i.e:
en:
users:
new:
title: "Sign up"
email_label: "E-mail address:"
password_label: "Password:"
password_confirmation_label: "Password confirmation:"
submit: "Sign up"
I was hoping to write a method that works out where it's being called from so that I could just call s("email_label")
instead of t("users.new.email_label")
:
def s(str, locals{})
t("#{params[:controller]}.#{params[:action]}.#{str}", locals)
end
This works great for the users/new page, however when processing the 'create' action, it calls render 'new'
inside this if it fails. The re-rendered page will then look for strings in 'users.create' instead of 'users.new'.
Is there a way to fix this without overriding the params[:action] value, or manually setting variables at the top of each view?
Thanks in advance
Upvotes: 0
Views: 143
Reputation: 34072
Not an answer to the original question, but perhaps an alternative?
Why not just have translations for :new_title
, :edit_title
, and so on, then call them explicitly?
Doing it by action probably isn't correct, as demonstrated by the issue you're having. You're not looking for translation based on action, but really by template. And even that is probably situational. Also, would there ever even be template translations for update
or create
? Probably not, as they don't render templates (your issue).
Plus, what if you later wanted to have a form to create a record on a different page? E.g. a "new comment" form on a "posts" page handled by the posts controller. Things could get hairy.
It seems like you'd gain more control by providing translations for the keys you know will exist, and calling them explicitly.
# translations
en:
users:
new_title: Sign Up
edit_title: Edit User
index_title: Users
# new.html.erb (and so on)
<%= title s(:new_title) %>
...
# controller helper method
def s(key, locals = {})
I18n.t key, locals.merge(:scope => controller_name)
end
Additionally, you may know this already, but the label helpers have i18n baked in using model translations, which may help to avoid repetitive definitions. These will also be the translations used for attribute names in generated errors. E.g.
en:
attributes:
# globally defined attribute translations
password: Password
activerecord:
attributes:
user:
# per model overrides
password: User Password
# The label helpers then use these (this label would translate to "User Password")
= form_for(@user) do |f|
= f.label :password
There are also dynamic translations for button helpers, based on whether or not the record is persisted. Depending on how you're handling sign ups, this may or may not work cleanly out of the box. If your sign up is just creating Users, though, it should.
en:
helpers:
user:
create: "Sign Up Now!"
update: "Update User!"
# This label would translate to "Sign Up Now!"
= form_for(User.new) do |f|
= f.submit
Upvotes: 1