aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/lib/action_mailer/base.rb42
-rw-r--r--actionmailer/lib/action_mailer/delivery_method.rb17
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/file.rb2
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/sendmail.rb2
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/smtp.rb2
-rw-r--r--actionmailer/lib/action_mailer/delivery_method/test.rb2
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb20
-rw-r--r--actionpack/lib/action_controller/legacy/layout.rb256
-rw-r--r--actionpack/lib/action_controller/metal/layouts.rb11
9 files changed, 51 insertions, 303 deletions
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 898356075f..29afa2692a 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -1,6 +1,4 @@
-require "active_support/core_ext/class"
-# Use the old layouts until actionmailer gets refactored
-require "action_controller/legacy/layout"
+require 'active_support/core_ext/class'
module ActionMailer #:nodoc:
# Action Mailer allows you to send email from your application using a mailer model and views.
@@ -254,11 +252,12 @@ module ActionMailer #:nodoc:
# +implicit_parts_order+.
class Base
include AdvAttrAccessor, PartContainer, Quoting, Utils
- extend AbstractController::RenderingController
+
+ include AbstractController::RenderingController
+ include AbstractController::Layouts
if Object.const_defined?(:ActionController)
include ActionController::UrlWriter
- include ActionController::Layout
end
private_class_method :new #:nodoc:
@@ -569,8 +568,7 @@ module ActionMailer #:nodoc:
end
@template = initialize_template_class(body)
- layout = _pick_layout(layout, true) unless
- ActionController::Base.exempt_from_layout.include?(template.handler)
+ layout = _layout_for_option(:default, :formats => formats)
@template._render_template(template, layout, {})
ensure
@current_template_content_type = nil
@@ -583,25 +581,23 @@ module ActionMailer #:nodoc:
end
def render(opts)
+ file = opts[:file]
opts[:locals] ||= {}
- layout, file = opts.delete(:layout), opts[:file]
-
- begin
- @template = initialize_template_class(opts.delete(:body))
-
- if file
- prefix = mailer_name unless file =~ /\//
- template = view_paths.find(file, {:formats => formats}, prefix)
- end
- layout = _pick_layout(layout,
- !template || ActionController::Base.exempt_from_layout.include?(template.handler))
+ @template = initialize_template_class(opts.delete(:body))
- if template
- @template._render_template(template, layout, opts)
- elsif inline = opts[:inline]
- @template._render_inline(inline, layout, opts)
- end
+ if file
+ prefix = mailer_name unless file =~ /\//
+ template = view_paths.find(file, {:formats => formats}, prefix)
+ end
+
+ layout = opts.key?(:layout) ? opts.delete(:layout) : :default
+ layout = _layout_for_option(layout, :formats => formats)
+
+ if template
+ @template._render_template(template, layout, opts)
+ elsif inline = opts[:inline]
+ @template._render_inline(inline, layout, opts)
end
end
diff --git a/actionmailer/lib/action_mailer/delivery_method.rb b/actionmailer/lib/action_mailer/delivery_method.rb
index ffba3c418c..29a51afdc3 100644
--- a/actionmailer/lib/action_mailer/delivery_method.rb
+++ b/actionmailer/lib/action_mailer/delivery_method.rb
@@ -2,10 +2,10 @@ require "active_support/core_ext/class"
module ActionMailer
module DeliveryMethod
- autoload :File, 'action_mailer/delivery_method/file'
+ autoload :File, 'action_mailer/delivery_method/file'
autoload :Sendmail, 'action_mailer/delivery_method/sendmail'
- autoload :Smtp, 'action_mailer/delivery_method/smtp'
- autoload :Test, 'action_mailer/delivery_method/test'
+ autoload :Smtp, 'action_mailer/delivery_method/smtp'
+ autoload :Test, 'action_mailer/delivery_method/test'
# Creates a new DeliveryMethod object according to the given options.
#
@@ -27,18 +27,17 @@ module ActionMailer
def self.lookup_method(delivery_method)
case delivery_method
when Symbol
- method_name = delivery_method.to_s.camelize
+ method_name = delivery_method.to_s.camelize
method_class = ActionMailer::DeliveryMethod.const_get(method_name)
- method_class.new()
- when nil
+ method_class.new
+ when nil # default
Smtp.new
else
delivery_method
end
end
- # An abstract delivery method class. There are multiple delivery method
- # classes, documented under
+ # An abstract delivery method class. There are multiple delivery method classes.
# See the classes under the ActionMailer::DeliveryMethod, e.g.
# ActionMailer::DeliveryMethod::Smtp.
# Smtp is the default delivery method for production
@@ -47,8 +46,8 @@ module ActionMailer
# each delivery method exposes just one method
#
# delivery_method = ActionMailer::DeliveryMethod::Smtp.new
- #
# delivery_method.perform_delivery(mail) # send the mail via smtp
+ #
class Method
superclass_delegating_accessor :settings
self.settings = {}
diff --git a/actionmailer/lib/action_mailer/delivery_method/file.rb b/actionmailer/lib/action_mailer/delivery_method/file.rb
index 8807a05221..587ae37ffa 100644
--- a/actionmailer/lib/action_mailer/delivery_method/file.rb
+++ b/actionmailer/lib/action_mailer/delivery_method/file.rb
@@ -1,10 +1,10 @@
require 'tmpdir'
+
module ActionMailer
module DeliveryMethod
# A delivery method implementation which writes all mails to a file.
class File < Method
-
self.settings = {
:location => defined?(Rails) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"
}
diff --git a/actionmailer/lib/action_mailer/delivery_method/sendmail.rb b/actionmailer/lib/action_mailer/delivery_method/sendmail.rb
index 34e03b8060..db55af79f1 100644
--- a/actionmailer/lib/action_mailer/delivery_method/sendmail.rb
+++ b/actionmailer/lib/action_mailer/delivery_method/sendmail.rb
@@ -3,7 +3,6 @@ module ActionMailer
# A delivery method implementation which sends via sendmail.
class Sendmail < Method
-
self.settings = {
:location => '/usr/sbin/sendmail',
:arguments => '-i -t'
@@ -18,5 +17,6 @@ module ActionMailer
end
end
end
+
end
end
diff --git a/actionmailer/lib/action_mailer/delivery_method/smtp.rb b/actionmailer/lib/action_mailer/delivery_method/smtp.rb
index e39f97330c..86b0ae8329 100644
--- a/actionmailer/lib/action_mailer/delivery_method/smtp.rb
+++ b/actionmailer/lib/action_mailer/delivery_method/smtp.rb
@@ -1,6 +1,5 @@
module ActionMailer
module DeliveryMethod
-
# A delivery method implementation which sends via smtp.
class Smtp < Method
@@ -27,5 +26,6 @@ module ActionMailer
end
end
end
+
end
end
diff --git a/actionmailer/lib/action_mailer/delivery_method/test.rb b/actionmailer/lib/action_mailer/delivery_method/test.rb
index e63e0abbb8..6e3239d52a 100644
--- a/actionmailer/lib/action_mailer/delivery_method/test.rb
+++ b/actionmailer/lib/action_mailer/delivery_method/test.rb
@@ -3,10 +3,10 @@ module ActionMailer
# A delivery method implementation designed for testing, which just appends each record to the :deliveries array
class Test < Method
-
def perform_delivery(mail)
ActionMailer::Base.deliveries << mail
end
end
+
end
end
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 796ef40584..4723e18a01 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -171,6 +171,26 @@ module AbstractController
name && _find_layout(name, details)
end
+ # Determine the layout for a given name and details, taking into account
+ # the name type.
+ #
+ # ==== Parameters
+ # name<String|TrueClass|FalseClass|Symbol>:: The name of the template
+ # details<Hash{Symbol => Object}>:: A list of details to restrict
+ # the lookup to. By default, layout lookup is limited to the
+ # formats specified for the current request.
+ def _layout_for_option(name, details)
+ case name
+ when String then _layout_for_name(name, details)
+ when true then _default_layout(details, true)
+ when :default then _default_layout(details, false)
+ when false, nil then nil
+ else
+ raise ArgumentError,
+ "String, true, or false, expected for `layout'; you passed #{name.inspect}"
+ end
+ end
+
# Take in the name and details and find a Template.
#
# ==== Parameters
diff --git a/actionpack/lib/action_controller/legacy/layout.rb b/actionpack/lib/action_controller/legacy/layout.rb
deleted file mode 100644
index 4e3b67de20..0000000000
--- a/actionpack/lib/action_controller/legacy/layout.rb
+++ /dev/null
@@ -1,256 +0,0 @@
-require 'active_support/core_ext/enumerable'
-require 'active_support/core_ext/class'
-require 'active_support/core_ext/class/delegating_attributes'
-require 'active_support/core_ext/class/inheritable_attributes'
-
-module ActionController #:nodoc:
- # MegasuperultraHAX
- # plz refactor ActionMailer
- class Base
- @@exempt_from_layout = [ActionView::TemplateHandlers::RJS]
- cattr_accessor :exempt_from_layout
- end
-
- module Layout #:nodoc:
- def self.included(base)
- base.extend(ClassMethods)
- base.class_inheritable_accessor :layout_name, :layout_conditions
- end
-
- # Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
- # repeated setups. The inclusion pattern has pages that look like this:
- #
- # <%= render "shared/header" %>
- # Hello World
- # <%= render "shared/footer" %>
- #
- # This approach is a decent way of keeping common structures isolated from the changing content, but it's verbose
- # and if you ever want to change the structure of these two includes, you'll have to change all the templates.
- #
- # With layouts, you can flip it around and have the common structure know where to insert changing content. This means
- # that the header and footer are only mentioned in one place, like this:
- #
- # // The header part of this layout
- # <%= yield %>
- # // The footer part of this layout
- #
- # And then you have content pages that look like this:
- #
- # hello world
- #
- # At rendering time, the content page is computed and then inserted in the layout, like this:
- #
- # // The header part of this layout
- # hello world
- # // The footer part of this layout
- #
- # == Accessing shared variables
- #
- # Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
- # references that won't materialize before rendering time:
- #
- # <h1><%= @page_title %></h1>
- # <%= yield %>
- #
- # ...and content pages that fulfill these references _at_ rendering time:
- #
- # <% @page_title = "Welcome" %>
- # Off-world colonies offers you a chance to start a new life
- #
- # The result after rendering is:
- #
- # <h1>Welcome</h1>
- # Off-world colonies offers you a chance to start a new life
- #
- # == Automatic layout assignment
- #
- # If there is a template in <tt>app/views/layouts/</tt> with the same name as the current controller then it will be automatically
- # set as that controller's layout unless explicitly told otherwise. Say you have a WeblogController, for example. If a template named
- # <tt>app/views/layouts/weblog.erb</tt> or <tt>app/views/layouts/weblog.builder</tt> exists then it will be automatically set as
- # the layout for your WeblogController. You can create a layout with the name <tt>application.erb</tt> or <tt>application.builder</tt>
- # and this will be set as the default controller if there is no layout with the same name as the current controller and there is
- # no layout explicitly assigned with the +layout+ method. Nested controllers use the same folder structure for automatic layout.
- # assignment. So an Admin::WeblogController will look for a template named <tt>app/views/layouts/admin/weblog.erb</tt>.
- # Setting a layout explicitly will always override the automatic behaviour for the controller where the layout is set.
- # Explicitly setting the layout in a parent class, though, will not override the child class's layout assignment if the child
- # class has a layout with the same name.
- #
- # == Inheritance for layouts
- #
- # Layouts are shared downwards in the inheritance hierarchy, but not upwards. Examples:
- #
- # class BankController < ActionController::Base
- # layout "bank_standard"
- #
- # class InformationController < BankController
- #
- # class VaultController < BankController
- # layout :access_level_layout
- #
- # class EmployeeController < BankController
- # layout nil
- #
- # The InformationController uses "bank_standard" inherited from the BankController, the VaultController overwrites
- # and picks the layout dynamically, and the EmployeeController doesn't want to use a layout at all.
- #
- # == Types of layouts
- #
- # Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes
- # you want to alternate layouts depending on runtime information, such as whether someone is logged in or not. This can
- # be done either by specifying a method reference as a symbol or using an inline method (as a proc).
- #
- # The method reference is the preferred approach to variable layouts and is used like this:
- #
- # class WeblogController < ActionController::Base
- # layout :writers_and_readers
- #
- # def index
- # # fetching posts
- # end
- #
- # private
- # def writers_and_readers
- # logged_in? ? "writer_layout" : "reader_layout"
- # end
- #
- # Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing
- # is logged in or not.
- #
- # If you want to use an inline method, such as a proc, do something like this:
- #
- # class WeblogController < ActionController::Base
- # layout proc{ |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
- #
- # Of course, the most common way of specifying a layout is still just as a plain template name:
- #
- # class WeblogController < ActionController::Base
- # layout "weblog_standard"
- #
- # If no directory is specified for the template name, the template will by default be looked for in <tt>app/views/layouts/</tt>.
- # Otherwise, it will be looked up relative to the template root.
- #
- # == Conditional layouts
- #
- # If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering
- # a given action or set of actions without a layout, or restricting a layout to only a single action or a set of actions. The
- # <tt>:only</tt> and <tt>:except</tt> options can be passed to the layout call. For example:
- #
- # class WeblogController < ActionController::Base
- # layout "weblog_standard", :except => :rss
- #
- # # ...
- #
- # end
- #
- # This will assign "weblog_standard" as the WeblogController's layout except for the +rss+ action, which will not wrap a layout
- # around the rendered view.
- #
- # Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an arbitrary number of method references, so
- # #<tt>:except => [ :rss, :text_only ]</tt> is valid, as is <tt>:except => :rss</tt>.
- #
- # == Using a different layout in the action render call
- #
- # If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above.
- # Sometimes you'll have exceptions where one action wants to use a different layout than the rest of the controller.
- # You can do this by passing a <tt>:layout</tt> option to the <tt>render</tt> call. For example:
- #
- # class WeblogController < ActionController::Base
- # layout "weblog_standard"
- #
- # def help
- # render :action => "help", :layout => "help"
- # end
- # end
- #
- # This will render the help action with the "help" layout instead of the controller-wide "weblog_standard" layout.
- module ClassMethods
- extend ActiveSupport::Memoizable
-
- # If a layout is specified, all rendered actions will have their result rendered
- # when the layout <tt>yield</tt>s. This layout can itself depend on instance variables assigned during action
- # performance and have access to them as any normal template would.
- def layout(template_name, conditions = {}, auto = false)
- add_layout_conditions(conditions)
- self.layout_name = template_name
- end
-
- def memoized_default_layout(formats) #:nodoc:
- self.layout_name || begin
- layout = default_layout_name
- layout.is_a?(String) ? find_layout(layout, formats) : layout
- rescue ActionView::MissingTemplate
- end
- end
-
- def default_layout(*args)
- memoized_default_layout(*args)
- @_memoized_default_layout ||= {}
- @_memoized_default_layout[args] ||= memoized_default_layout(*args)
- end
-
- def memoized_find_layout(layout, formats) #:nodoc:
- return layout if layout.nil? || layout.respond_to?(:render)
- prefix = layout.to_s =~ /layouts\// ? nil : "layouts"
- find_template(layout.to_s, {:formats => formats}, :_prefix => prefix)
- end
-
- def find_layout(*args)
- @_memoized_find_layout ||= {}
- @_memoized_find_layout[args] ||= memoized_find_layout(*args)
- end
-
- def layout_list #:nodoc:
- Array(view_paths).sum([]) { |path| Dir["#{path}/layouts/**/*"] }
- end
- memoize :layout_list
-
- def default_layout_name
- layout_match = name.underscore.sub(/_controller$/, '')
- if layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty?
- superclass.default_layout_name if superclass.respond_to?(:default_layout_name)
- else
- layout_match
- end
- end
- memoize :default_layout_name
-
- private
- def add_layout_conditions(conditions)
- # :except => :foo == :except => [:foo] == :except => "foo" == :except => ["foo"]
- conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} }
- write_inheritable_hash(:layout_conditions, conditions)
- end
- end
-
- def active_layout(name)
- name = self.class.default_layout(formats) if name == true
-
- layout_name = case name
- when Symbol then __send__(name)
- when Proc then name.call(self)
- else name
- end
-
- self.class.find_layout(layout_name, formats)
- end
-
- def _pick_layout(layout_name = nil, implicit = false)
- return unless layout_name || implicit
- layout_name = true if layout_name.nil?
- active_layout(layout_name) if action_has_layout? && layout_name
- end
-
- private
- def action_has_layout?
- if conditions = self.class.layout_conditions
- if only = conditions[:only]
- return only.include?(action_name)
- elsif except = conditions[:except]
- return !except.include?(action_name)
- end
- end
- true
- end
-
- end
-end
diff --git a/actionpack/lib/action_controller/metal/layouts.rb b/actionpack/lib/action_controller/metal/layouts.rb
index cac529b1ae..e7859e3fec 100644
--- a/actionpack/lib/action_controller/metal/layouts.rb
+++ b/actionpack/lib/action_controller/metal/layouts.rb
@@ -177,16 +177,5 @@ module ActionController
options[:_layout] = _layout_for_option(layout, options[:_template].details)
end
- def _layout_for_option(name, details)
- case name
- when String then _layout_for_name(name, details)
- when true then _default_layout(details, true)
- when :default then _default_layout(details, false)
- when false, nil then nil
- else
- raise ArgumentError,
- "String, true, or false, expected for `layout'; you passed #{name.inspect}"
- end
- end
end
end