Breadcrumbs II: the Internationalization

This is a quick followup to my breadcrumb solution. If your application is internationalized, I think you might be interested in the code presented below. If not, stick with the original version.

Without further ado, here’s how to make breadcrumbs work nicely with Ruby-GetText:

class ApplicationController < ActionController::Base
  ...
protected
  def add_breadcrumb_without_translation name, path = ''
    @breadcrumbs ||= []
    path = eval(path) if path =~ /_path|_url|@/
    @breadcrumbs << [name, path]
  end

  def add_breadcrumb name, path = ''
    add_breadcrumb_without_translation _(name), path
  end

  def self.add_breadcrumb name, path, options = {}
    before_filter options do |controller|
      controller.send(:add_breadcrumb, name, path)
    end
  end
end

As we can see, there are three methods now. We have the add_breadcrumb_without_translation method in case we wanted to add something like @category.name to the breadcrumb trail. The other method, add_breadcrumb uses GetText’s _() function to translate the name parameter. The third method, which defines a filter, is same as before.

And here’s how you would use it:

class ApplicationController < ActionController::Base
  add_breadcrumb N_('Home'), '/'
  ...
end
class ThingsController < ApplicationController
  add_breadcrumb N_('Things'), 'things_path'
  add_breadcrumb N_('Create a new thing'), '', :only => [:new, :create]
  add_breadcrumb N_('Edit a thing'), '', :only => [:edit, :update]

  def show
    @thing = Thing.find(params[:id])
    add_breadcrumb_without_translation @thing.name, ''
  end
  ...
end

Caveat: this works with GetText only. If you want to use any other I18N framework, you need to replace GetText’s _() and N_() functions with your framework’s equivalents. The _('string') function provides the translation of given string in current locale, while the N_('string') just declares to GetText that the string is one of the translation keys, but it should not be translated right here. This is required when breadcrumbs are defined at the top of the controller class, because this code is interpreted while the class is being loaded, but we need the translation to occur for each processed request with appropriate locale.

As far as I know, Globalize’s equivalent for _('string') is 'string'.t, but I have no idea how to replace N_(). I’d appreciate any comments from people using Globalize and other frameworks on how to make this work with those frameworks.

~ by szeryf on 2008-07-23.

Leave a Reply