Introducing Ruby Gem I18nLazyScope
Lately, I’ve been working on some projects that require internationalization. I find it annoying to have to type namespace.key
each time I translate something. I can use lazy lookup1–t('.key')
–but it defaults to locale.resource.key
, which is not always desirable.
Wouldn’t it be nice if I could use lazy lookup and have granular control over the namespace? So, for example, if I typed t(:key)
in users#show
the scope would default to en.views.users.show.key
.
So, to have my cake and eat it, I wrote I18nLazyLookup. It lets you use lazy lookup with custom scopes.
How does it work?
The library inserts a customisable namespace in the scope between the locale
and the resource
keys. The following table shows the differences (in bold) between I18nLazyLookup and i18n-rails.
Controllers | locale. controllers .controller_name.action_name.key |
Mailers | locale. mailers .mailer_name.action_name.key |
Views | locale. views .template_or_partial_path.key |
Tell me more
Say you are in users_controller#show
and you want to flash a welcome message.
def create
if @user.save
redirect_to @user, notice: t('welcome_msg')
end
end
Here, the scope for welcome_message
defaults to en
, the top level namespace. This is not a good way to structure locale files, and they’ll soon become messy and unmanagable. It’s better to scope them under a namespace.
en:
controllers:
users:
create:
welcome_msg: "You are such a star!"
redirect_to @user, notice: t('controllers.users.create.welcome_msg')
This is better, but it’s a lot to type. It would be nice if we could write t('.welcome_msg')
, but we can’t because rails-I18n scopes the translation to en.users.create.welcome_msg
. Our controller namespace is missing.
And that’s where I18nLazyLookup helps. It lets you use lazy lookup with custom namespaces. This makes changing the structure of translations easy.
redirect_to @user, notice: t_scoped(:welcome_msg)
If the defaults don’t work for you, you can customise the namespaces with an initializer.
# app/config/initializers/i18n_lazy_lookup.rb
I18nLazyScope.configure do |config|
config.action_controller_scope = [:custom, :scope]
config.action_mailer_scope = [:custom, :scope]
config.action_view_scope = [:custom, :scope]
end
The namespaces now resolve according to the following table.
Controllers | locale.custom.scope.controller_name.action_name.key |
Mailers | locale.my.custom.scope.mailer_name.action_name.key |
Views | locale.my.custom.scope.template_or_partial_path.key |
Check out the project repo on Github for more details.
-
Lazy lookup is a feature built into the I18n gem. It allows you to use translations without explicitly qualifying their scope. For example, calling
t('.hello')
(notice the dot precedinghello
) inapp/views/users/show.html.erb
defaults the translation scope toen.users.show.hello
. ↩