How-to use I18n's "Lazy Lookup" in your controllers

Warning, this is a dirty but useful hack. I use Rails 2.3.5 and the gem i18n 0.3.3.

If you use internationalization in Rails, you probably already know about the "Lazy Lookup" of I18n : Description of the "Lazy Lookup&quote;

That's a wonderful feature. However, you can't use it in your controllers, to do things like:

class Admin::BooksController < ApplicationController

  def new
    @book = Book.new
    @page_title = t('.title')
  end

end
... with a config/locales/en.yml containing ...
en:
  admin:
    books:
      new:
        title: 'My fancy title'

I don't really know why it's not available, and I couldn't find anything interesting online, so I did this. You can put it in your application_controller.rb :

  alias_method :t_original, :t
  def t(*args)
    if args.first[0..1] == '..'
      args[0] = params[:controller].gsub('/','.')+args.first[1..-1]
    elsif args.first.first == '.'
      args[0] = params[:controller].gsub('/','.')+'.'+params[:action]+args.first
    end
    t_original(*args)
  end

Now, you can use t() as usual, it will just work the way you intended.

Bonus, if you want do something like t('..new.title'), you can. Here is an example of how it can be used :

class Admin::BooksController < ApplicationController

  def new
    @book = Book.new
    @page_title = t('.title')
  end

  def create
    @book = Book.new(params[:book])
    if @book.save
      flash[:notice] = t('.success')
      redirect_to :action => 'index'
    else
      @page_title = t('..new.title')
      render :action => 'new'
    end
  end

end

This entry was posted on February 20, 2010 . You can follow any any response to this entry through the RSS feed. You can leave a comment.
Tags:              


Comments

Leave a response

  1. Skully @ 10 Mar 18:24:

    Thanks for sharing.

    lazy lookup in views like t(..new.title) are not possible with default rails, right? Is there a way to enable that as well?

    Mail me the answer if possible.

    thanks skully

  2. Christophe @ 11 Mar 00:23:

    I don't think it's working with default rails, I just use the same method as in the controller for my apps, but I'm sure there is a nicer way to do it.

  3. Damien @ 12 Jun 12:10:

    Actually you can do it in your controller and in your models by calling the I18n module.

    I18n.t('.title')

Leave a comment