Saturday, October 10, 2009

Simple Navigation Plugin Version 2

About six months ago I wrote about the first release of the simple navigation plugin. It's a GemPlugin to generate the navigation for your ruby on rails applications.

As far I can judge from the feedback I got from the community it seems like a lot of people are using the plugin. So I'm really happy to announce version 2 of the simple navigation plugin.

The main new features are
  • create as many navigation levels you like (so far it was limited to primary and sub navigation
  • the active navigation item gets highlighted automatically (no more explicit configuration of the active item in the controllers needed)
Please check out the
and see some live examples on the demo page.

For providing feedback or get help visit the discussion group or drop me a line on github.

Tuesday, October 6, 2009

Making ActionMailer testable

If you ever create a custom subclass of ActionMailer you'll be having a hard time to test it. That's because - by default - you cannot access the ActionMailer instance after creating a mail. To make ActionMailer testable you have to make its new-method public:

    1 class ActionMailer::Localized < ActionMailer::Base
2
3 #to make ActionMailer testable
4 public_class_method :new
5
6 private
7
8 #we would like to test that the correct template is set
9 def initialize_defaults(method_name)
10 super
11 @template = "#{I18n.locale}_#{method_name}"
12 end
13
14 end

With that change it's easy to test the initialize_defaults-method (as shown here using rspec):

    1 describe ActionMailer::Localized do
2
3 before(:each) do
4 @localized_mailer = Class.new(ActionMailer::Localized) do
5 def mailer_method(mail_object); end
6 end.new
7 @localized_mailer.stub!(:render)
8 I18n.locale = 'de'
9 end
10
11 describe 'after being initialized' do
12 before(:each) do
13 @localized_mailer.create!('mailer_method', Object.new)
14 end
15 it "should have the localized template name set" do
16 @localized_mailer.template.should == 'de_mailer_method'
17 end
18 end
19
20 end

Localized ActionMailer Templates for Rails

Rails actually does support localized templates, however, this does not apply for localized ActionMailer templates (yet?). Even if you add the correct locale to your mailer template names, ActionMailer does not choose the one based on the current locale.

It's really easy to fix this:

Just create a subclass of ActionMailer::Base and override the initialize_defaults method as shown below. Then let your mailers inherit from your new subclass.

    1 class ActionMailer::Localized < ActionMailer::Base
2
3 private
4
5 # we override the template_path to render localized templates (since rails does not support that :-( )
6 # This thing is not testable since you cannot access the instance of a mailer...
7 def initialize_defaults(method_name)
8 super
9 @template = "#{I18n.locale}_#{method_name}"
10 end
11
12 end

Define your desired template name as shown on line 9, just do not add your locale as dot-notation at the end of the file. E.g. method_name.de.text.plain.erb will not work.