easy_partials 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/easy_partials.gemspec +3 -1
- data/lib/easy_partials.rb +6 -155
- data/lib/easy_partials/controller_additions.rb +4 -7
- data/lib/easy_partials/helper_additions.rb +109 -0
- data/lib/easy_partials/object_additions.rb +44 -0
- metadata +5 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/easy_partials.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{easy_partials}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Samer Abukhait"]
|
@@ -28,6 +28,8 @@ Gem::Specification.new do |s|
|
|
28
28
|
"easy_partials.gemspec",
|
29
29
|
"lib/easy_partials.rb",
|
30
30
|
"lib/easy_partials/controller_additions.rb",
|
31
|
+
"lib/easy_partials/helper_additions.rb",
|
32
|
+
"lib/easy_partials/object_additions.rb",
|
31
33
|
"spec/easy_partials_spec.rb",
|
32
34
|
"spec/spec.opts",
|
33
35
|
"spec/spec_helper.rb"
|
data/lib/easy_partials.rb
CHANGED
@@ -1,166 +1,17 @@
|
|
1
|
-
class Object
|
2
|
-
# Obtain the metaclass of this object instance.
|
3
|
-
def metaclass
|
4
|
-
class << self
|
5
|
-
self
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
# Define an instance method using a symbol for the method name and a
|
10
|
-
# block for the method contents. This makes it so a closure can be
|
11
|
-
# used to define a singleton method.
|
12
|
-
def meta_def(name, &block)
|
13
|
-
metaclass.send :define_method, name, &block
|
14
|
-
end
|
15
|
-
|
16
|
-
# Define an instance method using a block that will accept a block
|
17
|
-
# as the first parameter, and the rest of the arguments as the
|
18
|
-
# second. This requires the block to have the first parameter act
|
19
|
-
# as the block.
|
20
|
-
#
|
21
|
-
# For example:
|
22
|
-
# o.meta_def_with_block(:say_hi) { |block, name|
|
23
|
-
# block.call
|
24
|
-
# puts "hello #{name}!"
|
25
|
-
# }
|
26
|
-
#
|
27
|
-
# Will create a method that can be invoked as such:
|
28
|
-
# o.say_hi("Mike") { puts "Saying hi:" }
|
29
|
-
#
|
30
|
-
# Implicitly, 2 methods are created... __real__say_hi, which is
|
31
|
-
# created using the given block, and say_hi, which will accept the
|
32
|
-
# arguments and block and pass them to __real__say_hi in reverse
|
33
|
-
# order.
|
34
|
-
def meta_def_with_block(name, &block)
|
35
|
-
meta_def "__real__#{name}".to_sym, &block
|
36
|
-
metaclass.instance_eval "
|
37
|
-
def #{name}(*args, &block)
|
38
|
-
__real__#{name} block, *args
|
39
|
-
end
|
40
|
-
"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
1
|
module EasyPartials
|
45
|
-
def self.shared_directories
|
46
|
-
@ep_shared_directories || ["shared"]
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.shared_directories=(arglist)
|
50
|
-
@ep_shared_directories = arglist
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
module ApplicationHelper
|
55
2
|
|
56
3
|
METHOD_REGEXP = /^_/
|
57
4
|
|
58
|
-
|
59
|
-
|
60
|
-
def respond_to?(method_name, inc_priv = false)
|
61
|
-
return true if method_name =~ METHOD_REGEXP
|
62
|
-
|
63
|
-
original_respond_to?(method_name, inc_priv)
|
64
|
-
end
|
65
|
-
|
66
|
-
alias_method :original_method_missing, :method_missing
|
67
|
-
|
68
|
-
def method_missing(method_name, *args, &block)
|
69
|
-
method_str = method_name.to_s
|
70
|
-
|
71
|
-
if method_str.sub! METHOD_REGEXP, ''
|
72
|
-
locations = [method_str]
|
73
|
-
locations.push *additional_partials(method_str)
|
74
|
-
new_method = partial_method locations, *args, &block
|
75
|
-
meta_def_with_block method_name, &new_method
|
76
|
-
else
|
77
|
-
original_method_missing method_name, *args, &block
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def additional_partials(partial_name)
|
82
|
-
@additional_partials ||= EasyPartials.shared_directories
|
83
|
-
@additional_partials.map { |location| "#{location}/#{partial_name}" }
|
84
|
-
end
|
85
|
-
|
86
|
-
# Utility method to create and invoke a Proc which will concat the
|
87
|
-
# partial given the possible locations. The Proc is then returned
|
88
|
-
# so it can be added as a new method for caching purposes (otherwise
|
89
|
-
# method_missing will have to be invoked each time the partial is
|
90
|
-
# invoked). The locations parameter is modified in the process.
|
91
|
-
# This is used by method_missing.
|
92
|
-
def partial_method(locations, *args, &block)
|
93
|
-
raise "No possible locations!" if locations.empty?
|
94
|
-
partial_name = locations.delete_at 0
|
95
|
-
new_method = lambda do |block, *args|
|
96
|
-
if params[:format] == "pdf"
|
97
|
-
invoke_partial partial_name, *args, &block
|
98
|
-
else
|
99
|
-
concat_partial partial_name, *args, &block
|
100
|
-
end
|
101
|
-
end
|
102
|
-
begin
|
103
|
-
new_method.call block, *args
|
104
|
-
rescue ActionView::MissingTemplate
|
105
|
-
if locations.empty?
|
106
|
-
raise
|
107
|
-
else
|
108
|
-
new_method = partial_method locations, *args, &block
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
new_method
|
113
|
-
end
|
114
|
-
|
115
|
-
def invoke_partial(partial, *args, &block)
|
116
|
-
locals = {}
|
117
|
-
|
118
|
-
if args.length == 1 && args[0].is_a?(Hash)
|
119
|
-
locals.merge! args[0]
|
120
|
-
else
|
121
|
-
locals.merge! :args => args
|
122
|
-
end
|
123
|
-
|
124
|
-
locals.merge! :body => capture(&block) if block
|
125
|
-
locals[:body] = nil unless locals[:body]
|
126
|
-
|
127
|
-
if locals.has_key? :collection
|
128
|
-
return "" if locals[:collection].blank?
|
129
|
-
render :partial => partial.to_s, :collection => locals[:collection],
|
130
|
-
:locals => locals.except(:collection)
|
131
|
-
else
|
132
|
-
render :partial => partial.to_s, :locals => locals
|
133
|
-
end
|
134
|
-
|
5
|
+
def self.shared_directories
|
6
|
+
@shared_directories || ["shared"]
|
135
7
|
end
|
136
8
|
|
137
|
-
|
138
|
-
|
139
|
-
# invoking the partial as a method with "_" prepended to the name.
|
140
|
-
#
|
141
|
-
# Invoking the method:
|
142
|
-
#
|
143
|
-
# <% concat_partial "my_partial", { :var => "value" } do %>
|
144
|
-
# <strong>Contents stored as a "body" local</strong>
|
145
|
-
# <% end %>
|
146
|
-
#
|
147
|
-
# Or invoking implicitly:
|
148
|
-
#
|
149
|
-
# <% _my_partial :var => "value" do %>
|
150
|
-
# <strong>Contents stored as a "body" local</strong>
|
151
|
-
# <% end %>
|
152
|
-
#
|
153
|
-
# Note that with the implicit partials the partial will first be
|
154
|
-
# searched for locally within the current view directory, and then
|
155
|
-
# additional directories defined by the controller level
|
156
|
-
# 'additional_partials' method, and finally within the views/shared
|
157
|
-
# directory.
|
158
|
-
def concat_partial(partial, *args, &block)
|
159
|
-
rendered = invoke_partial partial, *args, &block
|
160
|
-
concat rendered
|
9
|
+
def self.shared_directories=(arglist)
|
10
|
+
@shared_directories = arglist
|
161
11
|
end
|
162
|
-
|
163
12
|
end
|
164
13
|
|
14
|
+
require "easy_partials/object_additions"
|
15
|
+
require "easy_partials/helper_additions"
|
165
16
|
require 'easy_partials/controller_additions'
|
166
17
|
|
@@ -17,13 +17,10 @@ module EasyPartials
|
|
17
17
|
#
|
18
18
|
# additional_partials "shared/forms"
|
19
19
|
# additional_partials "shared/accounting", "shared_accounting"
|
20
|
-
def additional_partials(*
|
21
|
-
before_filter
|
22
|
-
|
23
|
-
|
24
|
-
values.push *partials
|
25
|
-
controller.instance_variable_set :@additional_partials, values
|
26
|
-
}
|
20
|
+
def additional_partials(*locations)
|
21
|
+
before_filter do |controller|
|
22
|
+
controller.instance_variable_set :@additional_partials, (locations + EasyPartials.shared_directories).flatten.uniq
|
23
|
+
end
|
27
24
|
end
|
28
25
|
|
29
26
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module EasyPartials
|
2
|
+
|
3
|
+
module HelperAdditions
|
4
|
+
|
5
|
+
def respond_to?(method_name, inc_priv = false)
|
6
|
+
return true if method_name =~ METHOD_REGEXP
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing(method_name, *args, &block)
|
11
|
+
method_str = method_name.to_s
|
12
|
+
return super unless method_str.sub! METHOD_REGEXP, ''
|
13
|
+
locations = [method_str]
|
14
|
+
locations.push *additional_partials(method_str)
|
15
|
+
new_method = partial_method locations, *args, &block
|
16
|
+
meta_def_with_block method_name, &new_method
|
17
|
+
end
|
18
|
+
|
19
|
+
def additional_partials(partial_name)
|
20
|
+
(@additional_partials || EasyPartials.shared_directories).map { |location| "#{location}/#{partial_name}" }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Utility method to create and invoke a Proc which will concat the
|
24
|
+
# partial given the possible locations. The Proc is then returned
|
25
|
+
# so it can be added as a new method for caching purposes (otherwise
|
26
|
+
# method_missing will have to be invoked each time the partial is
|
27
|
+
# invoked). The locations parameter is modified in the process.
|
28
|
+
# This is used by method_missing.
|
29
|
+
def partial_method(locations, *args, &block)
|
30
|
+
raise "No possible locations!" if locations.empty?
|
31
|
+
partial_name = locations.delete_at 0
|
32
|
+
new_method = lambda do |block, *args|
|
33
|
+
if params[:format] == "pdf"
|
34
|
+
invoke_partial partial_name, *args, &block
|
35
|
+
else
|
36
|
+
concat_partial partial_name, *args, &block
|
37
|
+
end
|
38
|
+
end
|
39
|
+
begin
|
40
|
+
new_method.call block, *args
|
41
|
+
rescue ActionView::MissingTemplate
|
42
|
+
if locations.empty?
|
43
|
+
raise
|
44
|
+
else
|
45
|
+
new_method = partial_method locations, *args, &block
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
new_method
|
50
|
+
end
|
51
|
+
|
52
|
+
def invoke_partial(partial, *args, &block)
|
53
|
+
locals = {}
|
54
|
+
|
55
|
+
if args.length == 1 && args[0].is_a?(Hash)
|
56
|
+
locals.merge! args[0]
|
57
|
+
else
|
58
|
+
locals.merge! :args => args
|
59
|
+
end
|
60
|
+
|
61
|
+
locals.merge! :body => capture(&block) if block
|
62
|
+
locals[:body] = nil unless locals[:body]
|
63
|
+
|
64
|
+
if locals.has_key? :collection
|
65
|
+
return "" if locals[:collection].blank?
|
66
|
+
render :partial => partial.to_s, :collection => locals[:collection],
|
67
|
+
:locals => locals.except(:collection)
|
68
|
+
else
|
69
|
+
render :partial => partial.to_s, :locals => locals
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
# Used to create nice templated "tags" while keeping the html out of
|
75
|
+
# our helpers. Additionally, this can be invoked implicitly by
|
76
|
+
# invoking the partial as a method with "_" prepended to the name.
|
77
|
+
#
|
78
|
+
# Invoking the method:
|
79
|
+
#
|
80
|
+
# <% concat_partial "my_partial", { :var => "value" } do %>
|
81
|
+
# <strong>Contents stored as a "body" local</strong>
|
82
|
+
# <% end %>
|
83
|
+
#
|
84
|
+
# Or invoking implicitly:
|
85
|
+
#
|
86
|
+
# <% _my_partial :var => "value" do %>
|
87
|
+
# <strong>Contents stored as a "body" local</strong>
|
88
|
+
# <% end %>
|
89
|
+
#
|
90
|
+
# Note that with the implicit partials the partial will first be
|
91
|
+
# searched for locally within the current view directory, and then
|
92
|
+
# additional directories defined by the controller level
|
93
|
+
# 'additional_partials' method, and finally within the views/shared
|
94
|
+
# directory.
|
95
|
+
def concat_partial(partial, *args, &block)
|
96
|
+
rendered = invoke_partial partial, *args, &block
|
97
|
+
concat rendered
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
if defined? ApplicationHelper
|
105
|
+
ApplicationHelper.module_eval do
|
106
|
+
include EasyPartials::HelperAdditions
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Object
|
2
|
+
# Obtain the metaclass of this object instance.
|
3
|
+
def metaclass
|
4
|
+
class << self
|
5
|
+
self
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# Define an instance method using a symbol for the method name and a
|
10
|
+
# block for the method contents. This makes it so a closure can be
|
11
|
+
# used to define a singleton method.
|
12
|
+
def meta_def(name, &block)
|
13
|
+
metaclass.send :define_method, name, &block
|
14
|
+
end
|
15
|
+
|
16
|
+
# Define an instance method using a block that will accept a block
|
17
|
+
# as the first parameter, and the rest of the arguments as the
|
18
|
+
# second. This requires the block to have the first parameter act
|
19
|
+
# as the block.
|
20
|
+
#
|
21
|
+
# For example:
|
22
|
+
# o.meta_def_with_block(:say_hi) { |block, name|
|
23
|
+
# block.call
|
24
|
+
# puts "hello #{name}!"
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
# Will create a method that can be invoked as such:
|
28
|
+
# o.say_hi("Mike") { puts "Saying hi:" }
|
29
|
+
#
|
30
|
+
# Implicitly, 2 methods are created... __real__say_hi, which is
|
31
|
+
# created using the given block, and say_hi, which will accept the
|
32
|
+
# arguments and block and pass them to __real__say_hi in reverse
|
33
|
+
# order.
|
34
|
+
def meta_def_with_block(name, &block)
|
35
|
+
meta_def "__real__#{name}".to_sym, &block
|
36
|
+
metaclass.instance_eval "
|
37
|
+
def #{name}(*args, &block)
|
38
|
+
__real__#{name} block, *args
|
39
|
+
end
|
40
|
+
"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Samer Abukhait
|
@@ -55,6 +55,8 @@ files:
|
|
55
55
|
- easy_partials.gemspec
|
56
56
|
- lib/easy_partials.rb
|
57
57
|
- lib/easy_partials/controller_additions.rb
|
58
|
+
- lib/easy_partials/helper_additions.rb
|
59
|
+
- lib/easy_partials/object_additions.rb
|
58
60
|
- spec/easy_partials_spec.rb
|
59
61
|
- spec/spec.opts
|
60
62
|
- spec/spec_helper.rb
|