diff options
Diffstat (limited to 'actionpack/lib/action_view/renderer/partial_renderer.rb')
-rw-r--r-- | actionpack/lib/action_view/renderer/partial_renderer.rb | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index a351fbc04f..c0ac332c4e 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -12,8 +12,7 @@ module ActionView # # <%= render :partial => "account" %> # - # This would render "advertiser/_account.html.erb" and pass the instance variable @account in as a local variable - # +account+ to the template for display. + # This would render "advertiser/_account.html.erb". # # In another template for Advertiser#buy, we could have: # @@ -28,32 +27,24 @@ module ActionView # # == The :as and :object options # - # By default <tt>ActionView::Partials::PartialRenderer</tt> has its object in a local variable with the same - # name as the template. So, given + # By default <tt>ActionView::Partials::PartialRenderer</tt> doesn't have any local variables. + # The <tt>:object</tt> option can be used to pass an object to the partial. For instance: # - # <%= render :partial => "contract" %> + # <%= render :partial => "account", :object => @buyer %> # - # within contract we'll get <tt>@contract</tt> in the local variable +contract+, as if we had written + # would provide the +@buyer+ object to the partial, available under the local variable +account+ and is + # equivalent to: # - # <%= render :partial => "contract", :locals => { :contract => @contract } %> + # <%= render :partial => "account", :locals => { :account => @buyer } %> # # With the <tt>:as</tt> option we can specify a different name for said local variable. For example, if we - # wanted it to be +agreement+ instead of +contract+ we'd do: - # - # <%= render :partial => "contract", :as => 'agreement' %> - # - # The <tt>:object</tt> option can be used to directly specify which object is rendered into the partial; - # useful when the template's object is elsewhere, in a different ivar or in a local variable for instance. + # wanted it to be +user+ instead of +account+ we'd do: # - # Revisiting a previous example we could have written this code: + # <%= render :partial => "account", :object => @buyer, :as => 'user' %> # - # <%= render :partial => "account", :object => @buyer %> - # - # <% @advertisements.each do |ad| %> - # <%= render :partial => "ad", :object => ad %> - # <% end %> + # This is equivalent to # - # The <tt>:object</tt> and <tt>:as</tt> options can be used together. + # <%= render :partial => "account", :locals => { :user => @buyer } %> # # == Rendering a collection of partials # @@ -300,6 +291,11 @@ module ActionView else paths.map! { |path| retrieve_variable(path).unshift(path) } end + if String === partial && @variable.to_s !~ /^[a-z_][a-zA-Z_0-9]*$/ + raise ArgumentError.new("The partial name (#{partial}) is not a valid Ruby identifier; " + + "make sure your partial name starts with a letter or underscore, " + + "and is followed by any combinations of letters, numbers, or underscores.") + end self end @@ -366,11 +362,25 @@ module ActionView def partial_path(object = @object) @partial_names[object.class.name] ||= begin object = object.to_model if object.respond_to?(:to_model) - object.class.model_name.partial_path.dup.tap do |partial| path = @lookup_context.prefixes.first - partial.insert(0, "#{File.dirname(path)}/") if partial.include?(?/) && path.include?(?/) + merge_path_into_partial(path, partial) + end + end + end + + def merge_path_into_partial(path, partial) + if path.include?(?/) && partial.include?(?/) + overlap = [] + path_array = File.dirname(path).split('/') + partial_array = partial.split('/')[0..-3] # skip model dir & partial + + path_array.each_with_index do |dir, index| + overlap << dir if dir == partial_array[index] end + + partial.gsub!(/^#{overlap.join('/')}\//,'') + partial.insert(0, "#{File.dirname(path)}/") end end |