Skip to content

Commit

Permalink
Merge branch 'master' of git@github.com:rails/rails
Browse files Browse the repository at this point in the history
  • Loading branch information
rick committed Apr 23, 2008
2 parents 69d29e8 + 6c1c16b commit eacb5cf
Show file tree
Hide file tree
Showing 146 changed files with 1,696 additions and 3,858 deletions.
8 changes: 7 additions & 1 deletion .gitignore
@@ -1 +1,7 @@
debug.log
debug.log
activeresource/doc
activerecord/doc
actionpack/doc
actionmailer/doc
activesupport/doc
railties/doc
39 changes: 27 additions & 12 deletions actionmailer/lib/action_mailer/base.rb
Expand Up @@ -73,21 +73,36 @@ module ActionMailer #:nodoc:
# <%= truncate(note.body, 25) %>
#
#
# = Generating URLs for mailer views
# = Generating URLs
#
# URLs can be generated in mailer views using <tt>url_for</tt> or named routes.
# Unlike controllers from Action Pack, the mailer instance doesn't have any context about the incoming request,
# so you'll need to provide all of the details needed to generate a URL.
#
# If your view includes URLs from the application, you need to use url_for in the mailing method instead of the view.
# Unlike controllers from Action Pack, the mailer instance doesn't have any context about the incoming request. That's
# why you need to jump this little hoop and supply all the details needed for the URL. Example:
# When using <tt>url_for</tt> you'll need to provide the <tt>:host</tt>, <tt>:controller</tt>, and <tt>:action</tt>:
#
# <%= url_for(:host => "example.com", :controller => "welcome", :action => "greeting") %>
#
# def signup_notification(recipient)
# recipients recipient.email_address_with_name
# from "system@example.com"
# subject "New account information"
# body :account => recipient,
# :home_page => url_for(:host => "example.com", :controller => "welcome", :action => "greeting")
# end
# When using named routes you only need to supply the <tt>:host</tt>:
#
# <%= users_url(:host => "example.com") %>
#
# You will want to avoid using the <tt>name_of_route_path</tt> form of named routes because it doesn't make sense to
# generate relative URLs in email messages.
#
# It is also possible to set a default host that will be used in all mailers by setting the <tt>:host</tt> option in
# the <tt>ActionMailer::Base.default_url_options</tt> hash as follows:
#
# ActionMailer::Base.default_url_options[:host] = "example.com"
#
# This can also be set as a configuration option in <tt>environment.rb</tt>:
#
# config.action_mailer.default_url_options = { :host => "example.com" }
#
# You can now access @home_page in the template and get http://example.com/welcome/greeting.
# If you do decide to set a default <tt>:host</tt> for your mailers you will want to use the
# <tt>:only_path => false</tt> option when using <tt>url_for</tt>. This will ensure that absolute URLs are generated because
# the <tt>url_for</tt> view helper will, by default, generate relative URLs when a <tt>:host</tt> option isn't
# explicitly provided.
#
# = Sending mail
#
Expand Down
14 changes: 14 additions & 0 deletions actionpack/CHANGELOG
@@ -1,5 +1,19 @@
*SVN*

* Reduce number of instance variables being copied from controller to view. [Pratik]

* select_datetime and select_time default to Time.zone.now when config.time_zone is set [Geoff Buesing]

* datetime_select defaults to Time.zone.now when config.time_zone is set [Geoff Buesing]

* Remove ActionController::Base#view_controller_internals flag. [Pratik]

* Add conditional options to caches_page method. [Paul Horsfall]

* Move missing template logic to ActionView. [Pratik]

* Introduce ActionView::InlineTemplate class. [Pratik]

* Automatically parse posted JSON content for Mime::JSON requests. [rick]

POST /posts
Expand Down
56 changes: 8 additions & 48 deletions actionpack/lib/action_controller/base.rb
Expand Up @@ -16,9 +16,6 @@ class ActionControllerError < StandardError #:nodoc:
class SessionRestoreError < ActionControllerError #:nodoc:
end

class MissingTemplate < ActionControllerError #:nodoc:
end

class RenderError < ActionControllerError #:nodoc:
end

Expand Down Expand Up @@ -256,16 +253,12 @@ class Base
DEFAULT_RENDER_STATUS_CODE = "200 OK"

include StatusCodes

# Determines whether the view has access to controller internals @request, @response, @session, and @template.
# By default, it does.
@@view_controller_internals = true
cattr_accessor :view_controller_internals

# Protected instance variable cache
@@protected_variables_cache = nil
cattr_accessor :protected_variables_cache


# Controller specific instance variables which will not be accessible inside views.
@@protected_view_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
@action_name @before_filter_chain_aborted @action_cache_path @_session @_cookies @_headers @_params
@_flash @_response)

# Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
# and images to a dedicated asset server away from the main web server. Example:
# ActionController::Base.asset_host = "http://assets.example.com"
Expand Down Expand Up @@ -330,9 +323,6 @@ class Base
# Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
cattr_accessor :logger

# Turn on +ignore_missing_templates+ if you want to unit test actions without making the associated templates.
cattr_accessor :ignore_missing_templates

# Controls the resource action separator
@@resource_action_separator = "/"
cattr_accessor :resource_action_separator
Expand Down Expand Up @@ -870,7 +860,7 @@ def render(options = nil, extra_options = {}, &block) #:doc:

elsif inline = options[:inline]
add_variables_to_assigns
tmpl = ActionView::Template.new(@template, options[:inline], false, options[:locals], true, options[:type])
tmpl = ActionView::InlineTemplate.new(@template, options[:inline], options[:locals], options[:type])
render_for_text(@template.render_template(tmpl), options[:status])

elsif action_name = options[:action]
Expand Down Expand Up @@ -1105,7 +1095,6 @@ def reset_session #:doc:
private
def render_for_file(template_path, status = nil, use_full_path = false, locals = {}) #:nodoc:
add_variables_to_assigns
assert_existence_of_template_file(template_path) if use_full_path
logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
render_for_text(@template.render_file(template_path, use_full_path, locals), status)
end
Expand Down Expand Up @@ -1201,7 +1190,6 @@ def self.action_methods
def add_variables_to_assigns
unless @variables_added
add_instance_variables_to_assigns
add_class_variables_to_assigns if view_controller_internals
@variables_added = true
end
end
Expand All @@ -1215,30 +1203,11 @@ def reset_variables_added_to_assigns
end

def add_instance_variables_to_assigns
@@protected_variables_cache ||= Set.new(protected_instance_variables)
instance_variable_names.each do |var|
next if @@protected_variables_cache.include?(var)
(instance_variable_names - @@protected_view_variables).each do |var|
@assigns[var[1..-1]] = instance_variable_get(var)
end
end

def add_class_variables_to_assigns
%w(view_paths logger ignore_missing_templates).each do |cvar|
@assigns[cvar] = self.send(cvar)
end
end

def protected_instance_variables
if view_controller_internals
%w(@assigns @performed_redirect @performed_render)
else
%w(@assigns @performed_redirect @performed_render
@_request @request @_response @response @_params @params
@_session @session @_cookies @cookies
@template @request_origin @parent_controller)
end
end

def request_origin
# this *needs* to be cached!
# otherwise you'd get different results if calling it more than once
Expand Down Expand Up @@ -1267,15 +1236,6 @@ def template_exempt_from_layout?(template_name = default_template_name)
@@exempt_from_layout.any? { |ext| name_with_extension =~ ext }
end

def assert_existence_of_template_file(template_name)
unless template_exists?(template_name) || ignore_missing_templates
full_template_path = template_name.include?('.') ? template_name : "#{template_name}.#{@template.template_format}.erb"
display_paths = view_paths.join(':')
template_type = (template_name =~ /layouts/i) ? 'layout' : 'template'
raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}")
end
end

def default_template_name(action_name = self.action_name)
if action_name
action_name = action_name.to_s
Expand Down
5 changes: 0 additions & 5 deletions actionpack/lib/action_controller/caching/actions.rb
Expand Up @@ -41,7 +41,6 @@ def self.included(base) #:nodoc:
base.extend(ClassMethods)
base.class_eval do
attr_accessor :rendered_action_cache, :action_cache_path
alias_method_chain :protected_instance_variables, :action_caching
end
end

Expand All @@ -55,10 +54,6 @@ def caches_action(*actions)
end

protected
def protected_instance_variables_with_action_caching
protected_instance_variables_without_action_caching + %w(@action_cache_path)
end

def expire_action(options = {})
return unless cache_configured?

Expand Down
12 changes: 10 additions & 2 deletions actionpack/lib/action_controller/caching/pages.rb
Expand Up @@ -78,10 +78,18 @@ def cache_page(content, path)

# Caches the +actions+ using the page-caching approach that'll store the cache in a path within the page_cache_directory that
# matches the triggering url.
#
# Usage:
#
# # cache the index action
# caches_page :index
#
# # cache the index action except for JSON requests
# caches_page :index, :if => Proc.new { |c| !c.request.format.json? }
def caches_page(*actions)
return unless perform_caching
actions = actions.map(&:to_s)
after_filter { |c| c.cache_page if actions.include?(c.action_name) }
options = actions.extract_options!
after_filter({:only => actions}.merge(options)) { |c| c.cache_page }
end

private
Expand Down
75 changes: 34 additions & 41 deletions actionpack/lib/action_controller/dispatcher.rb
Expand Up @@ -5,6 +5,30 @@ class Dispatcher
@@guard = Mutex.new

class << self
def define_dispatcher_callbacks(cache_classes)
unless cache_classes
# Development mode callbacks
before_dispatch :reload_application
after_dispatch :cleanup_application
end

# Common callbacks
to_prepare :load_application_controller do
begin
require_dependency 'application' unless defined?(::ApplicationController)
rescue LoadError => error
raise unless error.message =~ /application\.rb/
end
end

if defined?(ActiveRecord)
before_dispatch { ActiveRecord::Base.verify_active_connections! }
to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
end

after_dispatch :flush_logger if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush)
end

# Backward-compatible class method takes CGI-specific args. Deprecated
# in favor of Dispatcher.new(output, request, response).dispatch.
def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, output = $stdout)
Expand All @@ -22,7 +46,7 @@ def dispatch(cgi = nil, session_options = CgiRequest::DEFAULT_SESSION_OPTIONS, o
def to_prepare(identifier = nil, &block)
@prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
@prepare_dispatch_callbacks.replace_or_append_callback(callback)
@prepare_dispatch_callbacks | callback
end

# If the block raises, send status code as a last-ditch response.
Expand Down Expand Up @@ -69,23 +93,9 @@ def failsafe_logger
cattr_accessor :error_file_path
self.error_file_path = Rails.public_path if defined?(Rails.public_path)

cattr_accessor :unprepared
self.unprepared = true

include ActiveSupport::Callbacks
define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch

before_dispatch :reload_application
before_dispatch :prepare_application
after_dispatch :flush_logger
after_dispatch :cleanup_application

if defined? ActiveRecord
to_prepare :activerecord_instantiate_observers do
ActiveRecord::Base.instantiate_observers
end
end

def initialize(output, request = nil, response = nil)
@output, @request, @response = output, request, response
end
Expand Down Expand Up @@ -114,40 +124,23 @@ def dispatch_cgi(cgi, session_options)
end

def reload_application
if Dependencies.load?
Routing::Routes.reload
self.unprepared = true
end
end
# Run prepare callbacks before every request in development mode
run_callbacks :prepare_dispatch

def prepare_application(force = false)
begin
require_dependency 'application' unless defined?(::ApplicationController)
rescue LoadError => error
raise unless error.message =~ /application\.rb/
end

ActiveRecord::Base.verify_active_connections! if defined?(ActiveRecord)

if unprepared || force
run_callbacks :prepare_dispatch
ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading
self.unprepared = false
end
Routing::Routes.reload
ActionView::TemplateFinder.reload! unless ActionView::Base.cache_template_loading
end

# Cleanup the application by clearing out loaded classes so they can
# be reloaded on the next request without restarting the server.
def cleanup_application(force = false)
if Dependencies.load? || force
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
Dependencies.clear
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
end
def cleanup_application
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
Dependencies.clear
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
end

def flush_logger
RAILS_DEFAULT_LOGGER.flush if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush)
RAILS_DEFAULT_LOGGER.flush
end

protected
Expand Down
6 changes: 3 additions & 3 deletions actionpack/lib/action_controller/filters.rb
Expand Up @@ -265,7 +265,7 @@ def create_filters(filters, filter_type, &block)
def skip_filter_in_chain(*filters, &test)
filters, conditions = extract_options(filters)
filters.each do |filter|
if callback = find_callback(filter) then delete(callback) end
if callback = find(filter) then delete(callback) end
end if conditions.empty?
update_filter_in_chain(filters, :skip => conditions, &test)
end
Expand Down Expand Up @@ -302,7 +302,7 @@ def find_filter_prepend_position(filters, filter_type)
def find_or_create_filter(filter, filter_type, options = {})
update_filter_in_chain([filter], options)

if found_filter = find_callback(filter) { |f| f.type == filter_type }
if found_filter = find(filter) { |f| f.type == filter_type }
found_filter
else
filter_kind = case
Expand All @@ -326,7 +326,7 @@ def find_or_create_filter(filter, filter_type, options = {})
end

def update_filter_in_chain(filters, options, &test)
filters.map! { |f| block_given? ? find_callback(f, &test) : find_callback(f) }
filters.map! { |f| block_given? ? find(f, &test) : find(f) }
filters.compact!

map! do |filter|
Expand Down
4 changes: 1 addition & 3 deletions actionpack/lib/action_controller/layout.rb
Expand Up @@ -244,9 +244,7 @@ def active_layout(passed_layout = nil)
def render_with_a_layout(options = nil, extra_options = {}, &block) #:nodoc:
template_with_options = options.is_a?(Hash)

if apply_layout?(template_with_options, options) && (layout = pick_layout(template_with_options, options))
assert_existence_of_template_file(layout)

if (layout = pick_layout(template_with_options, options)) && apply_layout?(template_with_options, options)
options = options.merge :layout => false if template_with_options
logger.info("Rendering template within #{layout}") if logger

Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_controller/rescue.rb
Expand Up @@ -26,7 +26,7 @@ module Rescue

DEFAULT_RESCUE_TEMPLATE = 'diagnostics'
DEFAULT_RESCUE_TEMPLATES = {
'ActionController::MissingTemplate' => 'missing_template',
'ActionView::MissingTemplate' => 'missing_template',
'ActionController::RoutingError' => 'routing_error',
'ActionController::UnknownAction' => 'unknown_action',
'ActionView::TemplateError' => 'template_error'
Expand Down

0 comments on commit eacb5cf

Please sign in to comment.