From b7529ed1cc7cfd8df5fd1b069e2881d39d3d984c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 7 Aug 2008 23:43:12 -0700 Subject: Simplifying usage of ETags and Last-Modified and conditional GET requests --- actionpack/lib/action_view/renderable.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 5fe1ca86f3..89ac500717 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -31,10 +31,10 @@ module ActionView view.send(:evaluate_assigns) view.send(:set_controller_content_type, mime_type) if respond_to?(:mime_type) - view.send(:execute, method(local_assigns), local_assigns) + view.send(:execute, method_name(local_assigns), local_assigns) end - def method(local_assigns) + def method_name(local_assigns) if local_assigns && local_assigns.any? local_assigns_keys = "locals_#{local_assigns.keys.map { |k| k.to_s }.sort.join('_')}" end @@ -44,7 +44,7 @@ module ActionView private # Compile and evaluate the template's code (if necessary) def compile(local_assigns) - render_symbol = method(local_assigns) + render_symbol = method_name(local_assigns) @@mutex.synchronize do if recompile?(render_symbol) -- cgit v1.2.3 From 1b127fcdea28d6c6ab2f2c6370125c8817ba99d6 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 12 Aug 2008 20:18:03 -0700 Subject: Set asset-cached file ctime and mtime to the max mtime of the combined files. Allows for consistent ETag generation without having a shared filesystem. --- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 1e44b166d9..c2b4f51c9c 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -618,6 +618,11 @@ module ActionView def write_asset_file_contents(joined_asset_path, asset_paths) FileUtils.mkdir_p(File.dirname(joined_asset_path)) File.open(joined_asset_path, "w+") { |cache| cache.write(join_asset_file_contents(asset_paths)) } + + # Set mtime to the latest of the combined files to allow for + # consistent ETag without a shared filesystem. + mt = asset_paths.map { |p| File.mtime(File.join(ASSETS_DIR, p)) }.max + File.utime(mt, mt, joined_asset_path) end def collect_asset_files(*path) -- cgit v1.2.3 From 3b9324e62f770f1a0a457f7ad5fe6a3287ecae1f Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 13 Aug 2008 19:15:35 -0500 Subject: Fix rendering partials at the top level [#795 state:resolved] --- actionpack/lib/action_view/partials.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index eb74d4a4c7..894b88534c 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -146,7 +146,7 @@ module ActionView def find_partial_path(partial_path) if partial_path.include?('/') - "#{File.dirname(partial_path)}/_#{File.basename(partial_path)}" + File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}") elsif respond_to?(:controller) "#{controller.class.controller_path}/_#{partial_path}" else -- cgit v1.2.3 From f1f4e84a7ef88d941f6508673bb448de640d6f77 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 14 Aug 2008 12:23:29 -0700 Subject: Fix asset file paths with dangling queries in mtime check --- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index c2b4f51c9c..623ed1e8df 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -612,7 +612,7 @@ module ActionView end def join_asset_file_contents(paths) - paths.collect { |path| File.read(File.join(ASSETS_DIR, path.split("?").first)) }.join("\n\n") + paths.collect { |path| File.read(asset_file_path(path)) }.join("\n\n") end def write_asset_file_contents(joined_asset_path, asset_paths) @@ -621,10 +621,14 @@ module ActionView # Set mtime to the latest of the combined files to allow for # consistent ETag without a shared filesystem. - mt = asset_paths.map { |p| File.mtime(File.join(ASSETS_DIR, p)) }.max + mt = asset_paths.map { |p| File.mtime(asset_file_path(p)) }.max File.utime(mt, mt, joined_asset_path) end + def asset_file_path(path) + File.join(ASSETS_DIR, path.split('?').first) + end + def collect_asset_files(*path) dir = path.first -- cgit v1.2.3 From 38c7d73e73d569211c4dfadf96fc295a925b7c9c Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Sun, 17 Aug 2008 19:29:24 -0500 Subject: pass yielded arguments to block for ActionView::Base#render with :layout [#847 state:resolved] Signed-off-by: Joshua Peek --- actionpack/lib/action_view/base.rb | 23 +++++++------------ actionpack/lib/action_view/partials.rb | 38 ++++++++++++++++++++++++++++++-- actionpack/lib/action_view/renderable.rb | 9 +++++++- 3 files changed, 52 insertions(+), 18 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index ad59d92086..f7f9f70298 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -246,12 +246,18 @@ module ActionView #:nodoc: if partial_layout = options.delete(:layout) if block_given? - wrap_content_for_layout capture(&block) do + begin + @_proc_for_layout = block concat(render(options.merge(:partial => partial_layout))) + ensure + @_proc_for_layout = nil end else - wrap_content_for_layout render(options) do + begin + original_content_for_layout, @content_for_layout = @content_for_layout, render(options) render(options.merge(:partial => partial_layout)) + ensure + @content_for_layout = original_content_for_layout end end elsif options[:file] @@ -367,13 +373,6 @@ module ActionView #:nodoc: InlineTemplate.new(text, type).render(self, local_assigns) end - def wrap_content_for_layout(content) - original_content_for_layout, @content_for_layout = @content_for_layout, content - yield - ensure - @content_for_layout = original_content_for_layout - end - # Evaluate the local assigns and pushes them to the view. def evaluate_assigns unless @assigns_added @@ -392,11 +391,5 @@ module ActionView #:nodoc: controller.response.content_type ||= content_type end end - - def execute(method, local_assigns = {}) - send(method, local_assigns) do |*names| - instance_variable_get "@content_for_#{names.first || 'layout'}" - end - end end end diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 894b88534c..b661a62677 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -68,7 +68,7 @@ module ActionView # # <%# app/views/users/_editor.html.erb &> #
- # Deadline: $<%= user.deadline %> + # Deadline: <%= user.deadline %> # <%= yield %> #
# @@ -82,7 +82,7 @@ module ActionView # # Here's the editor: #
- # Deadline: $<%= user.deadline %> + # Deadline: <%= user.deadline %> # Name: <%= user.name %> #
# @@ -101,6 +101,40 @@ module ActionView # # # As you can see, the :locals hash is shared between both the partial and its layout. + # + # If you pass arguments to "yield" then this will be passed to the block. One way to use this is to pass + # an array to layout and treat it as an enumerable. + # + # <%# app/views/users/_user.html.erb &> + #
+ # Budget: $<%= user.budget %> + # <%= yield user %> + #
+ # + # <%# app/views/users/index.html.erb &> + # <% render :layout => @users do |user| %> + # Title: <%= user.title %> + # <% end %> + # + # This will render the layout for each user and yield to the block, passing the user, each time. + # + # You can also yield multiple times in one layout and use block arguments to differentiate the sections. + # + # <%# app/views/users/_user.html.erb &> + #
+ # <%= yield user, :header %> + # Budget: $<%= user.budget %> + # <%= yield user, :footer %> + #
+ # + # <%# app/views/users/index.html.erb &> + # <% render :layout => @users do |user, section| %> + # <%- case section when :header -%> + # Title: <%= user.title %> + # <%- when :footer -%> + # Deadline: <%= user.deadline %> + # <%- end -%> + # <% end %> module Partials extend ActiveSupport::Memoizable diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 89ac500717..a28689dc69 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -31,7 +31,14 @@ module ActionView view.send(:evaluate_assigns) view.send(:set_controller_content_type, mime_type) if respond_to?(:mime_type) - view.send(:execute, method_name(local_assigns), local_assigns) + + view.send(method_name(local_assigns), local_assigns) do |*names| + if proc = view.instance_variable_get("@_proc_for_layout") + view.capture(*names, &proc) + else + view.instance_variable_get("@content_for_#{names.first || 'layout'}") + end + end end def method_name(local_assigns) -- cgit v1.2.3 From c1a8690d582c08777055caf449c03f85b4c8aa4b Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 18 Aug 2008 22:38:58 -0500 Subject: Consistently use the framework's configured logger and avoid reverting to RAILS_DEFAULT_LOGGER unless necessary. --- actionpack/lib/action_view/base.rb | 3 ++- actionpack/lib/action_view/paths.rb | 2 +- actionpack/lib/action_view/renderable.rb | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index f7f9f70298..62a01b33dd 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -169,6 +169,7 @@ module ActionView #:nodoc: class << self delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB' + delegate :logger, :to => 'ActionController::Base' end def self.cache_template_loading=(*args) @@ -328,7 +329,7 @@ module ActionView #:nodoc: else template = Template.new(template_path, view_paths) - if self.class.warn_cache_misses && logger = ActionController::Base.logger + if self.class.warn_cache_misses && logger logger.debug "[PERFORMANCE] Rendering a template that was " + "not found in view path. Templates outside the view path are " + "not cached and result in expensive disk operations. Move this " + diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index d97f963540..6a118a1cfa 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -3,7 +3,7 @@ module ActionView #:nodoc: def self.type_cast(obj) if obj.is_a?(String) if Base.warn_cache_misses && defined?(Rails) && Rails.initialized? - Rails.logger.debug "[PERFORMANCE] Processing view path during a " + + Base.logger.debug "[PERFORMANCE] Processing view path during a " + "request. This an expense disk operation that should be done at " + "boot. You can manually process this view path with " + "ActionView::Base.process_view_paths(#{obj.inspect}) and set it " + diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index a28689dc69..c011f21550 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -72,7 +72,7 @@ module ActionView end_src begin - logger = ActionController::Base.logger + logger = Base.logger logger.debug "Compiling template #{render_symbol}" if logger ActionView::Base::CompiledTemplates.module_eval(source, filename, 0) -- cgit v1.2.3 From a8ece12fe2ac7838407954453e0d31af6186a5db Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Tue, 19 Aug 2008 19:09:04 -0500 Subject: Return nil instead of a space when passing an empty collection or nil to 'render :partial' [#791 state:resolved] Signed-off-by: Joshua Peek --- actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/partials.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 62a01b33dd..46bacbcbc1 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -263,7 +263,7 @@ module ActionView #:nodoc: end elsif options[:file] render_file(options[:file], nil, options[:locals]) - elsif options[:partial] && options[:collection] + elsif options[:partial] && options.has_key?(:collection) render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals], options[:as]) elsif options[:partial] render_partial(options[:partial], options[:object], options[:locals]) diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index b661a62677..074ba5a2b5 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -161,7 +161,7 @@ module ActionView end def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc: - return " " if collection.empty? + return nil if collection.blank? local_assigns = local_assigns ? local_assigns.clone : {} spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : '' -- cgit v1.2.3 From f388725bd61d8ae246c0c8e42eaec1a2be4620ac Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 21 Aug 2008 00:28:25 -0500 Subject: Partial revert of 2681685 premature TypeArray abstraction --- actionpack/lib/action_view/paths.rb | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 6a118a1cfa..d6bf2137af 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -1,5 +1,5 @@ module ActionView #:nodoc: - class PathSet < ActiveSupport::TypedArray #:nodoc: + class PathSet < Array #:nodoc: def self.type_cast(obj) if obj.is_a?(String) if Base.warn_cache_misses && defined?(Rails) && Rails.initialized? @@ -15,6 +15,30 @@ module ActionView #:nodoc: end end + def initialize(*args) + super(*args).map! { |obj| self.class.type_cast(obj) } + end + + def <<(obj) + super(self.class.type_cast(obj)) + end + + def concat(array) + super(array.map! { |obj| self.class.type_cast(obj) }) + end + + def insert(index, obj) + super(index, self.class.type_cast(obj)) + end + + def push(*objs) + super(*objs.map { |obj| self.class.type_cast(obj) }) + end + + def unshift(*objs) + super(*objs.map { |obj| self.class.type_cast(obj) }) + end + class Path #:nodoc: def self.eager_load_templates! @eager_load_templates = true -- cgit v1.2.3 From 7e4ea5f4a2fd25e06820689688e3db5a4851f8e0 Mon Sep 17 00:00:00 2001 From: Darragh Curran Date: Wed, 25 Jun 2008 11:15:26 +0100 Subject: Allow overriding id for feed and entry with atom_feed_builder. [#485 state:resolved] Signed-off-by: Pratik Naik --- .../lib/action_view/helpers/atom_feed_helper.rb | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'actionpack/lib/action_view') diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index ebb1cb34bc..e65d5d1f60 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -17,7 +17,7 @@ module ActionView # # GET /posts.atom # def index # @posts = Post.find(:all) - # + # # respond_to do |format| # format.html # format.atom @@ -29,12 +29,12 @@ module ActionView # atom_feed do |feed| # feed.title("My great blog!") # feed.updated((@posts.first.created_at)) - # + # # for post in @posts # feed.entry(post) do |entry| # entry.title(post.title) # entry.content(post.body, :type => 'html') - # + # # entry.author do |author| # author.name("DHH") # end @@ -47,8 +47,9 @@ module ActionView # * :language: Defaults to "en-US". # * :root_url: The HTML alternative that this feed is doubling for. Defaults to / on the current host. # * :url: The URL for this feed. Defaults to the current URL. - # * :schema_date: The date at which the tag scheme for the feed was first used. A good default is the year you - # created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, + # * :id: The id for this feed. Defaults to "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}" + # * :schema_date: The date at which the tag scheme for the feed was first used. A good default is the year you + # created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, # 2005 is used (as an "I don't care" value). # # Other namespaces can be added to the root element: @@ -81,7 +82,7 @@ module ActionView else options[:schema_date] = "2005" # The Atom spec copyright date end - + xml = options[:xml] || eval("xml", block.binding) xml.instruct! @@ -89,10 +90,10 @@ module ActionView feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)} xml.feed(feed_opts) do - xml.id("tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}") + xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}") xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port)) xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url) - + yield AtomFeedBuilder.new(xml, self, options) end end @@ -102,7 +103,7 @@ module ActionView def initialize(xml, view, feed_options = {}) @xml, @view, @feed_options = xml, view, feed_options end - + # Accepts a Date or Time object and inserts it in the proper format. If nil is passed, current time in UTC is used. def updated(date_or_time = nil) @xml.updated((date_or_time || Time.now.utc).xmlschema) @@ -115,9 +116,10 @@ module ActionView # * :published: Time first published. Defaults to the created_at attribute on the record if one such exists. # * :updated: Time of update. Defaults to the updated_at attribute on the record if one such exists. # * :url: The URL for this entry. Defaults to the polymorphic_url for the record. + # * :id: The ID for this entry. Defaults to "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}" def entry(record, options = {}) - @xml.entry do - @xml.id("tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}") + @xml.entry do + @xml.id(options[:id] || "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}") if options[:published] || (record.respond_to?(:created_at) && record.created_at) @xml.published((options[:published] || record.created_at).xmlschema) -- cgit v1.2.3