I18nLazyScope
I18nLazyScope is a tiny library that lets you use lazy lookup and keep a better structure for your locale files when localising strings in your Ruby applications. This means quicker translations without sacrificing the structure of your locale files.
# users_controller#create
redirect_to @user, notice: scoped_t('welcome_message')
en:
controllers: # <- Oh, look, it's a controller scope with lazy lookup! Yay!
users:
create:
welcome_message: "You are such a star!"
I18nLazyScope provides a wrapper method around the translate
and t
methods in Rails and the Ruby I18n gem.
What Problem Does This Solve
Imagine you are in the users_controller#show
action, and you want to flash a localised welcome message.
def create
if @user.save
redirect_to @user, notice: t('welcome_message')
end
end
This scopes the translation to locale.welcome_message
. If your current--or default--locale is English, the corresponding key in your locale file would be en.welcome_message
.
Oh dear! This is an awful way to structure translations. You want to scope them instead. You create a key in your locale file.
en:
controllers:
users:
create:
welcome_message: "You are such a star!"
And you add the key to your code.
redirect_to @user, notice: t('controllers.users.create.welcome_message')
Holy Semantics, Batman! controllers.users.create
is a lot to type before each key name. And after some time you tire of typing it repeatedly. You read the documentation and discover lazy lookup--brilliant. You decide to use it, and diligently place a dot before your key name.
redirect_to @user, notice: t('.welcome_message')
Soon after, when testing, you discover that you have a translation missing
error in your template. This is because lazy lookup will scope the translation to en.users.create.welcome_message
. The neat controller
namespace we created is missing.
You have two choices:
- Change the structure of your locale file to match how lazy lookup works.
- Use verbose, fully qualified scopes.
Option one might cause your locale file to become a mess, or worse, cause namespace collisions because views and controllers share part of the namespace: en.users
. And option two is annoying to type all the time.
I18nLazyScope lets you use lazy lookup and keep a better structure for your locale files.
redirect_to @user, notice: scoped_t('welcome_message')
en:
controllers: # or mailers, views, or, whatever you want
users:
create:
welcome_message: "You are such a star!"
Installation
Add this line to your application's Gemfile:
gem 'i18n_lazy_scope'
And then execute:
$ bundle
Or install it yourself as:
$ gem install i18n_lazy_scope
Usage
Call the t_scoped
method instead of t
, or translate
, and make sure you have the corresponding keys in your locale file. Say you are in app/views/users/show.html.erb
.
<%= t_scoped 'greeting' %>
en:
views:
users:
show:
greeting: "Hello!"
The library inserts a top level name in the scope for you. You will be able to customise this in future releases, but for now, the scopes default to:
- Conrollers:
locale.controllers.controller_name.action_name.key
- Mailers:
locale.mailers.mailer_name.action_name.key
- Views:
locale.views.template_or_partial_path.key
Interpolation
It works exactly as it would if you call t
or translate
.
<%= t_scoped 'greeting', name: @user.name %>
en:
views:
users:
show:
greeting: "Hello, %{name}!"
Scoping
If you have to customise the scope on individual basis, then you should use t
and translate
that ship with Rails or the I18n gem. Scoping on individual basis defeates the point of this gem. This gem isn't meant to replace the I18n; it's a tiny wrapper that depends on it.
In future releases you will be able to customise top level namespaces, such as views
, controllers
, mailers
, etc.
API
t_scoped(key, **args)
A Note on Ruby Versions
I18nLazyScope requires Ruby 2.0 because it uses the double splat **
operator to capture all keyword arguments.
Contributing
- Fork it ( https://github.com/abitdodgy/i18n_lazy_scope/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request