Skip to navigation

Per-hamster ActionMailer template paths

Published September 06, 2007

If you need per-request (per-site, per-event, per-hamster, etc.) emails templates and you don’t need users modifying the templates you can quite easily break out of the standard ActionMailer directory structure and pull the templates from a subdirectory of your choosing.

Instead of storing mailer templates in #{RAILS_ROOT}/app/views/event_mailer/ I wanted them in #{RAILS_ROOT}/app/views/event_mailer/#{event.slug}/.

Luckily, it’s simply a matter of overriding ActionMailer::Base#template_path:

class EventMailer < ActionMailer::Base

  def purchase_receipt(purchase)
    @event = purchase.event
    # ...
  end

  protected
    def template_path
      if @event
        "#{template_root}/#{mailer_name}/#{@event.slug}"
      else
        super
      end
    end
end

The typical alternative to this approach is to pull user-editable Liquid templates from the DB, but the template_path approach is much simpler for my needs and means I don’t need to code an editing interface and bunch of liquid drops. Use whichever approach makes most sense for your application.

Archived comments

Comments were previously allowed on articles. Though no new comments are being accepted you can see the old comments below.

  1. Arno Nyhm

    i used your patch for template_path:

    def template_path
        "#{template_root}/#{mailer_name}/#{@lang}" 
      end
    

    but the renderer ( in render(opts) ) ignore it and set the file path here to a mailer/actionname.html.haml file and ignore my settings for template_path with [fullpath]/mailer/de for a language selection.

    if i overwrite the render method then i get my result but i think this is not a good solution….

          def render(opts)
            body = opts.delete(:body)
            if opts[:file] && opts[:file] !~ /\//
              opts[:file] = "#{mailer_name}/#{@lang}/#{opts[:file]}"
            end
            initialize_template_class(body).render(opts)
          end
  2. Arno Nyhm

    one solution for me i found to only overwrite the method “mailer_name” with this:

      
      def mailer_name
        @mailer_name + "/#{@lang}"
      end
    

    so i can store the templates in folders:

    
    views/
      mailer/
        de/
          registration.text.html.haml
          registration.text.plain.haml
        en/
          registration.text.html.haml
          registration.text.plain.haml
    

Thoughts

toolmantim

I’m Tim Lucas, a user experience developer currently in Sydney Australia.

I occasionally write, snap photos, present on various technical topics, tweet my going-ons, share teh codes and post tidbits to the scrapbook.

Most recently I published Simplifying ticket sales on sydneyoperahouse.com (February 16, 2010)

Work with me via Agency Rainford, or shoot an email to and say hello.

Powered by your inner voice