Skip to content

Commit

Permalink
use radiant layouts in ActionMailer subclasses
Browse files Browse the repository at this point in the history
  • Loading branch information
will-r committed Sep 21, 2009
1 parent ccb0557 commit 31a73b1
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 10 deletions.
23 changes: 19 additions & 4 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,42 @@

Created by: Sean Cribbs (seancribbs AT gmail DOT com), September 20, 2007
Updated to work with 0.8 RC1 by: Johannes Fahrenkrug (http://springenwerk.com), May 22, 2009
Updated to work with ActionMailer by: Will (http://spanner.org), September 17, 2009

Allows Rails controllers/actions to use Radiant layouts as their "layout".
Allows Rails controllers/actions and mailers to use Radiant layouts as their "layout".
content_for blocks are mapped to page parts, with the exception of :title and
:breadcrumbs, which map to their specific default tags. The default content,
or @content_for_layout, is mapped to the 'body' part.
:breadcrumbs, which map to their specific default tags. The default content, or
@content_for_layout, is mapped to the 'body' part.

== What to do in your controllers
== What to do in your controllers

radiant_layout 'Layout name'

-or-

radiant_layout { |controller| # some code to determine layout name }

== What to do in your mailers

radiant_layout # defaults to config['email.layout'] and then to 'email'

-or-

radiant_layout 'Layout name'

-or-

radiant_layout { |mailer| # some code to determine layout name }

radiant_layout takes the same options as the built-in layout. To specifically
override the Radiant layout and use a standard Rails one use
:layout => "mine", or :layout => false for no layout, as options to render.

To choose a different Radiant layout, set the @radiant_layout instance
variable to the name of a Radiant layout in your controller or view.

The mailers

== Acknowledgments

Thanks to John Long for clarifying and simplifying the process for me!
Expand Down
14 changes: 14 additions & 0 deletions app/models/message_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class MessagePage < Page
display_name "Not really a page at all"

def find_by_url(url, live=true, clean=true)
self
end

def build_parts_from_hash!(content)
content.each do |k,v|
(part(k) || parts.build(:name => k.to_s, :filter_id => "")).content = v
end
end

end
1 change: 1 addition & 0 deletions app/views/layouts/radiant_mailer.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= radiant_mailer_layout %>
16 changes: 11 additions & 5 deletions lib/share_layouts/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ def radiant_layout(name = @radiant_layout)
page.render
end

def radiant_mailer_layout(name = @radiant_mailer_layout)
radiant_layout(name)
end

def assign_attributes!(page, name = @radiant_layout)
page.layout = Layout.find_by_name(name) || page.layout
page.title = @title || @content_for_title || page.title || ''
page.breadcrumb = @breadcrumb || @content_for_breadcrumb || page.breadcrumb || page.title
page.breadcrumbs = @breadcrumbs || @content_for_breadcrumbs || nil
page.url = request.path
page.slug = page.url.split("/").last
page.published_at ||= Time.now
page.request = request
page.response = response
if request
page.url = request.path
page.slug = page.url.split("/").last
page.published_at ||= Time.now
page.request = request
page.response = response
end
end

def extract_captures
Expand Down
40 changes: 40 additions & 0 deletions lib/share_layouts/radiant_mailer_layouts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module ShareLayouts::RadiantMailerLayouts
def self.included(base)
base.extend ClassMethods
base.class_eval {
include InstanceMethods
alias_method_chain :initialize_defaults, :layout
}
end

module ClassMethods
def radiant_layout(name=nil, options={}, &block)
raise ArgumentError, "A layout name or block is required!" unless name || block
write_inheritable_attribute 'radiant_mailer_layout_name', name || block
layout 'radiant_mailer', options
end
end

module InstanceMethods
def initialize_defaults_with_layout(method_name)
set_mailer_layout
initialize_defaults_without_layout(method_name)
end

def set_mailer_layout
@radiant_mailer_layout = self.class.read_inheritable_attribute 'radiant_mailer_layout_name'
@radiant_mailer_layout = @radiant_mailer_layout.call(self) if @radiant_mailer_layout.is_a? Proc
end

def layout_for(purpose = :email)
if defined? Site && current_site && current_site.respond_to?(:layout_for)
current_site.layout_for(purpose)
elsif config_layout = Radiant::Config["#{purpose}.layout"]
config_layout
else
'email'
end
end
end

end
1 change: 1 addition & 0 deletions share_layouts_extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class ShareLayoutsExtension < Radiant::Extension
def activate
RailsPage
ActionController::Base.send :include, ShareLayouts::RadiantLayouts
ActionMailer::Base.send :include, ShareLayouts::RadiantMailerLayouts
ActionView::Base.send :include, ShareLayouts::Helper
end

Expand Down
5 changes: 5 additions & 0 deletions spec/lib/share_layouts_extension_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
ActionController::Base.should respond_to(:radiant_layout)
ActionController::Base.new.should respond_to(:set_radiant_layout)
end

it "should add mailer hooks" do
ActionMailer::Base.should respond_to(:radiant_layout)
ActionMailer::Base.instance_methods.include?('set_mailer_layout').should be_true
end

it "should add helper" do
ActionView::Base.included_modules.include?(ShareLayouts::Helper).should be_true
Expand Down
53 changes: 53 additions & 0 deletions spec/models/notifier_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
require File.dirname(__FILE__) + '/../spec_helper'

class NotifierWithRadiantLayout < ActionMailer::Base
radiant_layout 'main'
end

class NotifierWithRadiantLayoutBlock < ActionMailer::Base
radiant_layout {|c| c.action_name == "index" ? "main" : "utf8" }
end

class Notifier < ActionMailer::Base
radiant_layout { |m| m.layout_for :test }

def test(recipient="test@spanner.org")
from "someone@spanner.org"
subject "test"
recipients recipient
content_type "text/html"
end
end

describe NotifierWithRadiantLayout do
dataset :layouts

it "should have radiant layout attribute" do
NotifierWithRadiantLayout.read_inheritable_attribute('radiant_mailer_layout_name').should == 'main'
end
end

describe NotifierWithRadiantLayoutBlock do
dataset :layouts

it "should have radiant layout block" do
NotifierWithRadiantLayoutBlock.read_inheritable_attribute('radiant_mailer_layout_name').should be_kind_of(Proc)
end
end

describe Notifier do
dataset :layouts

before(:each) do
Radiant::Config['test.layout'] = 'utf8'
end

it "should apply the radiant layout" do
message = Notifier.create_test("anyone@all.com")
message.should_not be_nil
message.body.should =~ /Rendered with the mailer_layout:/
message.body.should =~ /Test message template./
message.content_type.should == 'text/html'
end
end

4 changes: 3 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@
#
# If you declare global fixtures, be aware that they will be declared
# for all of your examples, even those that don't use them.
end
end

ActionMailer::Base.template_root = File.dirname(__FILE__) + '/templates/' # there must be a way to stub the mailer templates but I don't have time to dig it out :(
3 changes: 3 additions & 0 deletions spec/templates/layouts/radiant_mailer.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>Rendered with the mailer_layout:</p>

<%= radiant_mailer_layout %>
1 change: 1 addition & 0 deletions spec/templates/notifier/test.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test message template.

0 comments on commit 31a73b1

Please sign in to comment.