Changeset 958

Show
Ignore:
Timestamp:
11/11/07 22:07:01 (1 year ago)
Author:
iv..@gweezlebur.com
Message:

Rendering partials with a collection or an object / Closes #292 / Thanks nagash

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/merb/mixins/render.rb

    r926 r958  
    277277    # if you create a views/shared directory then you can call 
    278278    # partials that live there like partial('shared/foo') 
    279     def partial(template, locals={}) 
     279    def partial(template, opts={}) 
    280280      choose_template_format(Merb.available_mime_types, {}) unless @_template_format 
    281281      template = _cached_partials["#{template}.#{@_template_format}"] ||= find_partial(template) 
    282       @_merb_partial_locals = locals 
    283282      unless template 
    284283        raise TemplateNotFound, "No template matched at #{unmatched}" 
    285284      end 
    286  
    287       engine = Template.engine_for(template) 
    288       options = { 
    289         :file => template, 
    290         :view_context  => clean_view_context(engine), 
    291         :opts => {:locals => locals} 
    292       } 
    293       engine.transform(options) 
     285       
     286      opts[:as] ||= template[(template.rindex('/_') + 2)..-1].split('.').first 
     287 
     288      if opts[:with] # Render a collection or an object 
     289       partial_for_collection(template, opts[:with], opts) 
     290      else # Just render a partial 
     291       engine = Template.engine_for(template) 
     292       render_partial(template, engine, opts || {}) 
     293      end 
    294294    end 
    295295 
     
    302302     
    303303    private 
     304 
     305      def render_partial(template, engine, locals={}) 
     306       @_merb_partial_locals = locals 
     307       options = { 
     308         :file => template, 
     309         :view_context => clean_view_context(engine), 
     310         :opts => { :locals => locals } 
     311       } 
     312       engine.transform(options) 
     313      end 
     314 
     315      def partial_for_collection(template, collection, opts={}) 
     316       # Delete the internal keys, so that everything else is considered 
     317       # a local declaration in the partial 
     318       local_name = opts.delete(:as) 
     319       opts.delete(:with) 
     320 
     321       engine = Template.engine_for(template) 
     322 
     323       ret = '' 
     324       [ collection ].flatten.each do |object| 
     325         opts.merge!({local_name.to_sym => object}) 
     326         ret << render_partial(template, engine, opts) 
     327       end 
     328       ret 
     329      end 
    304330     
    305331      # this returns a ViewContext object populated with all 
  • trunk/spec/merb/render_spec.rb

    r918 r958  
    3232    content = c.partial("partials/#{@engine}", :yo => "Locals!") 
    3333    content.clean.should == "Locals!" 
     34  end 
     35 
     36  it "should render a partial iterating over a collection" do 
     37    c = new_controller 
     38    content = c.partial("partials/#{@engine}_collection", 
     39      :with => (1..10).to_a) 
     40    content.clean.should == (1..10).to_a.join("\n") 
     41  end 
     42 
     43  it "should render a partial with an object" do 
     44    c = new_controller 
     45    content = c.partial("partials/#{@engine}_collection", :with => 1) 
     46    content.clean.should == '1' 
     47  end 
     48 
     49  it "should allow you to overwrite the local var using :as when rendering a collection" do 
     50    c = new_controller 
     51    content = c.partial("partials/#{@engine}_collection_with_locals", :with => (1..10).to_a, :as => :number) 
     52    content.clean.should == (1..10).to_a.join("\n") 
     53  end 
     54 
     55  it "should allow you to overwrite the local var using :as when render an object" do 
     56    c = new_controller 
     57    content = c.partial("partials/#{@engine}_collection_with_locals", :with => 1, :as => :number) 
     58    content.clean.should == '1' 
     59  end 
     60 
     61  it "should render a partial iterating over a collection with extra locals" do 
     62    c = new_controller 
     63    content = c.partial("partials/#{@engine}_collection_with_locals", :with => (1..10).to_a, :number => 'Locals!') 
     64    content.clean.should == (1..10).to_a.map { |i| "Locals!" }.join("\n") 
    3465  end 
    3566