Module: SinatraHelpers::Erb::Partials

Defined in:
lib/sinatra_helpers/erb/partials.rb

Instance Method Summary collapse

Instance Method Details

#partial(path, locals = {}, &subject_block) ⇒ Object

helper to somewhat emulate rails’ ‘render :partial’ helper, using erb

> originally taken from the sinatra book:

http://sinatra-book.gittr.com/#implemention_of_rails_style_partials

> updated: pass a block to specify the partial subject (ie object or collection)

> updated: pass a hash to specify locals directly

> if a block is passed, will look for template in a path relative to

to the calling template path.  Specify template with a leading '/'
to force the path to be relative to the views directory.

Render the partial once (no subject) with no locals: Usage: partial :item

> looks for template at <views>/_item.erb

Render a nested template Usage: partial ‘/items/item’

> looks for template at <views>/items/_item.erb

Render the partial once (no subject) WITH locals: Usage: partial :item, :user => @me

Render the partial once on an object: Implicit usage: partial :item { @item }

> knows subject should be treated as an object (and not a collection)

b/c @item is not enumerable

Explicit usage: partial :item, :item => @item_set

-- or --: partial :item, :object => @item_set

> use a local if your subject is enumerable and you want

it treated as a single object

Render the partial over a collection:

> knows subject should be treated as a collection (and not a single object)

b/c @items is enumerable

Implicit usage: partial :item { @items } Explicit usage: partial :item, :collection => @items

Generally, passing a block is the preferred method b/c you can specify templates relative to the calling template’s path, for example:

> if in template <views>/items/_item_list.erb

> partial :item { @items }

> will look for the template at <views>/items/_item.erb

> however

> partial :item, :collection => @items

> will look for the template at <views>/_item.erb

> you can force this behavior in the block version

> by prepending a ‘/’ to the template

> partial ‘/item’ { @items }

> will look for the template at <views>/_item.erb



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/sinatra_helpers/erb/partials.rb', line 57

def partial(path, locals={}, &subject_block)
  raise "locals must be specified with a Hash" unless locals.kind_of?(::Hash)
  params = _partial_params(path, locals, subject_block)
  # locals[:object] takes precedence over whatever calculated subject
  if locals.delete(:object).nil? && params[:subject] && params[:subject].respond_to?(:collect)
    counter = 0
    params[:subject].collect do |subject|
      erb(params[:path], params[:options].merge({
        :locals => params[:locals].merge({
          params[:name].to_sym => subject,
          "#{params[:name]}_counter".to_sym => counter += 1
        })
      }))
    end.join("\n")
  else
    erb(params[:path], params[:options].merge({
      :locals => params[:locals].merge({
        params[:name].to_sym => params[:subject]
      })
    }))
  end
end