Module: EasyPartials::HelperAdditions

Included in:
ApplicationHelper
Defined in:
lib/easy_partials/helper_additions.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/easy_partials/helper_additions.rb', line 3

def method_missing(method_name, *args, &block)
  method_str = method_name.to_s
  return super unless method_str.sub! METHOD_REGEXP, ''
  locations = [method_str]
  locations.push *additional_partials(method_str)

  begin
    locals = partial_args *args, &block
    new_method = partial_method locations, locals
    meta_def_with_block method_name, &new_method
  rescue ActionView::MissingTemplate
    super
  end
end

Instance Method Details

#additional_partials(partial_name) ⇒ Object



18
19
20
# File 'lib/easy_partials/helper_additions.rb', line 18

def additional_partials(partial_name)
  (@additional_partials || EasyPartials.shared_directories).map { |location| "#{location}/#{partial_name}" }
end

#concat_partial(partial, *args, &block) ⇒ Object

Used to create nice templated “tags” while keeping the html out of our helpers. Additionally, this can be invoked implicitly by invoking the partial as a method with “_” prepended to the name.

Invoking the method:

<% concat_partial "my_partial", { :var => "value" } do %>
  <strong>Contents stored as a "body" local</strong>
<% end %>

Or invoking implicitly:

<% _my_partial :var => "value" do %>
  <strong>Contents stored as a "body" local</strong>
<% end %>

Note that with the implicit partials the partial will first be searched for locally within the current view directory, and then additional directories defined by the controller level ‘additional_partials’ method, and finally within the views/shared directory.



101
102
103
104
# File 'lib/easy_partials/helper_additions.rb', line 101

def concat_partial(partial, *args, &block)
  rendered = invoke_partial partial, *args, &block
  concat rendered
end

#invoke_partial(partial, *args, &block) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/easy_partials/helper_additions.rb', line 67

def invoke_partial(partial, *args, &block)
  locals = partial_args *args, &block
  locals[:options] = locals.dup unless locals.has_key?(:options)

  if locals.has_key? :collection
    return "" if locals[:collection].blank?
    render :partial => partial.to_s, :collection => locals[:collection],
           :locals => locals.except(:collection)
  else
    render :partial => partial.to_s, :locals => locals
  end
end

#partial_args(*args, &block) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/easy_partials/helper_additions.rb', line 53

def partial_args(*args, &block)
  locals = {}

  if args.length == 1 && args[0].is_a?(Hash)
    locals.merge! args[0]
  else
    locals.merge! :args => args
  end

  locals.merge! :body => capture(&block) if block
  locals[:body] = nil unless locals[:body]
  locals
end

#partial_method(locations, locals) ⇒ Object

Utility method to create and invoke a Proc which will concat the partial given the possible locations. The Proc is then returned so it can be added as a new method for caching purposes (otherwise method_missing will have to be invoked each time the partial is invoked). The locations parameter is modified in the process. This is used by method_missing.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/easy_partials/helper_additions.rb', line 28

def partial_method(locations, locals)
  raise "No possible locations!" if locations.empty?
  partial_name = locations.delete_at 0

  new_method = lambda do |block, *args|
    if params[:format] == "pdf"
      invoke_partial partial_name, *args, &block
    else
      concat_partial partial_name, *args, &block
    end
  end

  begin
    new_method.call nil, locals
  rescue ActionView::MissingTemplate
    if locations.empty?
      raise
    else
      new_method = partial_method locations, locals
    end
  end

  new_method
end