building-blocks 1.2.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +32 -14
- data/README.rdoc +48 -8
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/building-blocks.rb +1 -5
- data/lib/building_blocks.rb +28 -0
- data/lib/building_blocks/base.rb +159 -39
- data/lib/building_blocks/view_additions.rb +3 -4
- data/spec/building-blocks/base_spec.rb +160 -99
- data/spec/building-blocks/building_blocks_spec.rb +24 -0
- data/spec/building-blocks/view_additions_spec.rb +11 -0
- data/spec/spec_helper.rb +6 -3
- metadata +56 -42
data/CHANGELOG.rdoc
CHANGED
@@ -1,25 +1,43 @@
|
|
1
|
-
|
1
|
+
2.0.0 (October 18, 2012)
|
2
|
+
|
3
|
+
* Added ability to render a collection of objects and specify the surrounding elements and the html to apply to those surrounding elements
|
4
|
+
For example: blocks.render :test, :collection => @cuisine_types, :as => :cuisine_type, :surrounding_tag => "div", :surrounding_tag_html => {:class => Proc.new {cycle("even", "odd")}}
|
5
|
+
* Added ability to specify "around" blocks, i.e. blocks of view code that render around another block of code, such as:
|
6
|
+
<% blocks.around :test_block do |content_block| %>
|
7
|
+
<h1>
|
8
|
+
<%= content_block.call %>
|
9
|
+
</h1>
|
10
|
+
<% end %> %>
|
11
|
+
* Added a util method BuildingBlocks.render_template(self, partial, options={}, &block) that makes the templating feature easier to use
|
12
|
+
(as opposed to calling the long way: BuildingBlocks::Base.new(self, options={}).render_template(partial, &block))
|
13
|
+
* Aliased "#blocks" method that is available to views as "#buildingblocks", "#bb", and "#building_blocks"
|
14
|
+
* Aliased "#after" method to "#for", so that you can now call <%= blocks.for :block_name %> (should be slightly more familiar to users of content_for with yield)
|
15
|
+
* Added a "#setup" method to initialize BuildingBlocks globally (for example: BuildingBlocks.setup do |config| config.template_folder = "shared" end)
|
16
|
+
* Cleaned up the organization of the code base and not using autoload instead of require
|
17
|
+
* Removed :use_partials_for_before_and_after_hooks option from 1.2.2
|
2
18
|
|
3
|
-
|
4
|
-
* Ability to disable use of partials for before and after hooks
|
5
|
-
* Complete test coverage
|
6
|
-
* :template_folder and :variable options are no longer being passed in as part of the options hash to defined blocks and partials
|
19
|
+
1.2.3 (February 9, 2012)
|
7
20
|
|
8
|
-
|
21
|
+
* Created two new utility methods: evaluated_procs and evaluated_proc that allow parameters for blocks to be Proc objects so long as these methods are called to evaluate them. (These methods have been carried over and renamed from the table-for gem where they were used to be able to dynamically specify table css classes, styles, and ids at runtime).
|
9
22
|
|
10
|
-
|
11
|
-
|
12
|
-
*
|
13
|
-
* Removed the original render method and replaced with render_template that takes the partial and block to render as arguments.
|
23
|
+
1.2.2 (February 9, 2012)
|
24
|
+
|
25
|
+
* Allow :use_partials and :use_partials_for_before_and_after_hooks to be passed in as initialization options to BuildingBlocks::Base to control whether BuildingBlocks attempts to render partials when "blocks.render" is called.
|
14
26
|
|
15
27
|
1.2.1 (February 7, 2012)
|
16
28
|
|
17
29
|
* Only try to render "before" and "after" blocks as partials if that BuildingBlocks::USE_PARTIALS_FOR_BEFORE_AND_AFTER_HOOKS is globally set to true (set to false now by default)
|
18
30
|
|
19
|
-
1.2.
|
31
|
+
1.2.0 (February 5, 2012)
|
20
32
|
|
21
|
-
*
|
33
|
+
* Changed prototype for "use" method, such that the name of the block being rendered is now a required parameter.
|
34
|
+
* Documented BuildingBlocks::Base more thoroughly
|
35
|
+
* Changed the blocks.use method to blocks.render (blocks.use is still available for legacy purposes)
|
36
|
+
* Removed the original render method and replaced with render_template that takes the partial and block to render as arguments.
|
22
37
|
|
23
|
-
1.
|
38
|
+
1.1.0 (February 4, 2012)
|
24
39
|
|
25
|
-
*
|
40
|
+
* Ability to disable use of partials when rendering a block
|
41
|
+
* Ability to disable use of partials for before and after hooks
|
42
|
+
* Complete test coverage
|
43
|
+
* :template_folder and :variable options are no longer being passed in as part of the options hash to defined blocks and partials
|
data/README.rdoc
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
= BuildingBlocks
|
2
2
|
|
3
|
-
|
3
|
+
RDocs[http://rdoc.info/projects/hunterae/building-blocks] | {Screencast Part 1}[https://vimeo.com/36674545]
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
BuildingBlocks is an intricate way of rendering blocks of code, while combining some of the best features of content blocks and partials, and adding several new features that go above and beyond what a simple content_for with yield or a render :partial is capable of doing.
|
6
|
+
|
7
|
+
1. Automatically determines whether you're rendering a content block (i.e. a block of code that you have defined using similar syntax to content_for) or a partial, with exactly the same syntax
|
8
|
+
2. Pass parameters into your blocks of code, regardless of whether your block of code is a content block or a partial (something content_for with yield is incapable of doing)
|
9
|
+
3. Use "before" and "after" hooks to designate code that should be rendered before and after a block of code that is to be rendered
|
10
|
+
4. Define your blocks of code as either a global partial, a controller-specific partial, or an inline block of code
|
11
|
+
5. Provides four different ways to define your block of code: as a global partial, a controller-specific partial, or an inline block of code, all with the same syntax usage.
|
12
|
+
6. Provides a very powerful way of defining templates to build reusable UI components with minimal code, as was done with {table-for}[https://github.com/hunterae/table-for]
|
13
|
+
|
14
|
+
== Author's Note
|
15
|
+
To fully appreciate how powerful BuildingBlocks can be, i highly recommend checking out the project {table-for}[https://github.com/hunterae/table-for] first. This is a gem that was built using BuildingBlocks with very few lines of code, and illustrates how easily the templating feature of BuildingBlocks can be used to build extremely useful reusable UI components.
|
9
16
|
|
10
17
|
== Installation
|
11
18
|
|
@@ -240,7 +247,7 @@ there is a table_for partial that gets rendered, but before it is rendered, the
|
|
240
247
|
template (partial) knows what to render, and occasionally, how to render to render it.
|
241
248
|
|
242
249
|
As an easier example, consider the following call in a view file:
|
243
|
-
<%= BuildingBlocks
|
250
|
+
<%= BuildingBlocks.render_template(self, "blocks/wizard") do |blocks| %>
|
244
251
|
<% blocks.queue :step1 %>
|
245
252
|
<% blocks.queue :step2 do %>
|
246
253
|
My Overridden Step 2 |
|
@@ -279,7 +286,7 @@ Notice the order of the queued blocks was preserved, Step2's definition was succ
|
|
279
286
|
|
280
287
|
This technique could also very easily be used to do something like wrapping content in some complicated markup, such is wrapping code in html tags to display as
|
281
288
|
a header container:
|
282
|
-
<%= BuildingBlocks
|
289
|
+
<%= BuildingBlocks.render_template(self, "blocks/header_container") do |blocks| %>
|
283
290
|
My code to wrap
|
284
291
|
<% end %>
|
285
292
|
|
@@ -299,7 +306,7 @@ What will get rendered will be the following:
|
|
299
306
|
|
300
307
|
The code called from the view could easily be extracted in a helper method as follows:
|
301
308
|
def header_container(options={}, &block)
|
302
|
-
BuildingBlocks
|
309
|
+
BuildingBlocks.render_template(self, "blocks/header_container", options, &block)
|
303
310
|
end
|
304
311
|
|
305
312
|
Then it could be called from the view as follows:
|
@@ -309,6 +316,39 @@ Then it could be called from the view as follows:
|
|
309
316
|
|
310
317
|
VIDEO TUTORIAL TO COME SHOWING HOW TABLE_FOR CAN BE BUILT FROM SCRATCH
|
311
318
|
|
319
|
+
== Block Groups
|
320
|
+
|
321
|
+
Another advanced feature of BuildingBlocks is the ability to queue up multiple different sets of blocks in different queues, called block groups. It will most often be used in conjunction with the templating feature described above and is best demonstrated with an example:
|
322
|
+
|
323
|
+
<%= BuildingBlocks::Base.new(self).render_template("blocks/my_layout") do |blocks| %>
|
324
|
+
<% blocks.left_column do %>
|
325
|
+
<%= blocks.queue :left_column_block1 %>
|
326
|
+
<%= blocks.queue :left_column_block2 do %>
|
327
|
+
Some random content on the left
|
328
|
+
<% end %>
|
329
|
+
<% end %>
|
330
|
+
<% blocks.right_column do %>
|
331
|
+
<%= blocks.queue :right_column_block1 %>
|
332
|
+
<%= blocks.queue :right_column_block2 do %>
|
333
|
+
Some random content on the right
|
334
|
+
<% end %>
|
335
|
+
<% end %>
|
336
|
+
<% end %>
|
337
|
+
|
338
|
+
In this example, two separate block groups are created, one for the left column on the page, one for the right, both of which will contain an ordered list (queue) of blocks. You start a new block group by invoking a method on "blocks" that does not exist, such as :left_column / :right_column. Then, in the template that renders the content, the queue of left and right column blocks can be iterated over and rendered as follows:
|
339
|
+
|
340
|
+
<!-- In /app/views/blocks/_my_layout.html.erb -->
|
341
|
+
<div style="float:left; width: 50%">
|
342
|
+
<% blocks.left_column.each do |block| %>
|
343
|
+
<%= blocks.render block %>
|
344
|
+
<% end %>
|
345
|
+
</div>
|
346
|
+
<div style="float:left; width: 50%">
|
347
|
+
<% blocks.right_column.each do |block| %>
|
348
|
+
<%= blocks.render block %>
|
349
|
+
<% end %>
|
350
|
+
</div>
|
351
|
+
|
312
352
|
== Questions or Problems?
|
313
353
|
|
314
354
|
If you have any issues with BuildingBlocks which you cannot find the solution to in the documentation, please add an {issue on GitHub}[https://github.com/hunterae/building-blocks/issues] or fork the project and send a pull request.
|
data/Rakefile
CHANGED
@@ -9,8 +9,8 @@ begin
|
|
9
9
|
require 'jeweler'
|
10
10
|
Jeweler::Tasks.new do |gemspec|
|
11
11
|
gemspec.name = "building-blocks"
|
12
|
-
gemspec.summary = ""
|
13
|
-
gemspec.description = ""
|
12
|
+
gemspec.summary = "BuildingBlocks is an intricate way of rendering blocks of code, while combining some of the best features of content blocks and partials, and adding several new features that go above and beyond what a simple content_for with yield or a render :partial is capable of doing."
|
13
|
+
gemspec.description = "BuildingBlocks goes beyond blocks and partials"
|
14
14
|
gemspec.email = "hunterae@gmail.com"
|
15
15
|
gemspec.homepage = "http://github.com/hunterae/building-blocks"
|
16
16
|
gemspec.authors = ["Andrew Hunter"]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/lib/building-blocks.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "action_view"
|
2
|
+
|
3
|
+
module BuildingBlocks
|
4
|
+
autoload :Base, "building_blocks/base"
|
5
|
+
autoload :Container, "building_blocks/container"
|
6
|
+
autoload :ViewAdditions, "building_blocks/view_additions"
|
7
|
+
|
8
|
+
mattr_accessor :template_folder
|
9
|
+
@@template_folder = "blocks"
|
10
|
+
|
11
|
+
mattr_accessor :use_partials
|
12
|
+
@@use_partials = true
|
13
|
+
|
14
|
+
mattr_accessor :surrounding_tag_surrounds_before_and_after_blocks
|
15
|
+
@@surrounding_tag_surrounds_before_and_after_blocks = true
|
16
|
+
|
17
|
+
# Shortcut for using the templating feature / rendering templates
|
18
|
+
def self.render_template(view, partial, options={}, &block)
|
19
|
+
BuildingBlocks::Base.new(view, options).render_template(partial, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Default way to setup BuildingBlocks
|
23
|
+
def self.setup
|
24
|
+
yield self
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
ActionView::Base.send :include, BuildingBlocks::ViewAdditions::ClassMethods
|
data/lib/building_blocks/base.rb
CHANGED
@@ -1,8 +1,4 @@
|
|
1
1
|
module BuildingBlocks
|
2
|
-
TEMPLATE_FOLDER = "blocks"
|
3
|
-
USE_PARTIALS = true
|
4
|
-
USE_PARTIALS_FOR_BEFORE_AND_AFTER_HOOKS = false
|
5
|
-
|
6
2
|
class Base
|
7
3
|
# a pointer to the ActionView that called BuildingBlocks
|
8
4
|
attr_accessor :view
|
@@ -23,7 +19,7 @@ module BuildingBlocks
|
|
23
19
|
attr_accessor :global_options
|
24
20
|
|
25
21
|
# The default folder to look in for global partials
|
26
|
-
attr_accessor :
|
22
|
+
attr_accessor :template_folder
|
27
23
|
|
28
24
|
# The variable to use when rendering the partial for the templating feature (by default, "blocks")
|
29
25
|
attr_accessor :variable
|
@@ -31,8 +27,8 @@ module BuildingBlocks
|
|
31
27
|
# Boolean variable for whether BuildingBlocks should attempt to render blocks as partials if a defined block cannot be found
|
32
28
|
attr_accessor :use_partials
|
33
29
|
|
34
|
-
# Boolean variable for whether BuildingBlocks should
|
35
|
-
attr_accessor :
|
30
|
+
# Boolean variable for whether BuildingBlocks should render before and after blocks inside or outside of a collections' elements' surrounding tags
|
31
|
+
attr_accessor :surrounding_tag_surrounds_before_and_after_blocks
|
36
32
|
|
37
33
|
# Checks if a particular block has been defined within the current block scope.
|
38
34
|
# <%= blocks.defined? :some_block_name %>
|
@@ -57,7 +53,16 @@ module BuildingBlocks
|
|
57
53
|
# [+block+]
|
58
54
|
# The block that is to be rendered when "blocks.render" is called for this block.
|
59
55
|
def define(name, options={}, &block)
|
60
|
-
|
56
|
+
collection = options.delete(:collection)
|
57
|
+
|
58
|
+
if collection
|
59
|
+
collection.each do |object|
|
60
|
+
define(evaluated_proc(name, object, options), options, &block)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
self.define_block_container(name, options, &block)
|
64
|
+
end
|
65
|
+
|
61
66
|
nil
|
62
67
|
end
|
63
68
|
|
@@ -84,7 +89,9 @@ module BuildingBlocks
|
|
84
89
|
end
|
85
90
|
|
86
91
|
# Render a block, first rendering any "before" blocks, then rendering the block itself, then rendering
|
87
|
-
# any "after" blocks.
|
92
|
+
# any "after" blocks. Additionally, a collection may also be passed in, and BuildingBlocks will render
|
93
|
+
# an the block, along with corresponding before and after blocks for each element of the collection.
|
94
|
+
# BuildingBlocks will make four different attempts to render block:
|
88
95
|
# 1) Look for a block that has been defined inline elsewhere, using the blocks.define method:
|
89
96
|
# <% blocks.define :wizard do |options| %>
|
90
97
|
# Inline Block Step#<%= options[:step] %>.
|
@@ -110,13 +117,63 @@ module BuildingBlocks
|
|
110
117
|
# The name of the block to render (either a string or a symbol)
|
111
118
|
# [+*args+]
|
112
119
|
# Any arguments to pass to the block to be rendered (and also to be passed to any "before" and "after" blocks).
|
120
|
+
# The last argument in the list can be a hash and can include the following special options:
|
121
|
+
# [:collection]
|
122
|
+
# The collection of elements to render blocks for
|
123
|
+
# [:as]
|
124
|
+
# The variable name to assign the current element in the collection being rendered over
|
125
|
+
# [:surrounding_tag]
|
126
|
+
# The content tag to render around a block, which might be particularly useful when rendering a collection of blocks,
|
127
|
+
# such as for a list or table
|
128
|
+
# [:surrounding_tag_html]
|
129
|
+
# The attributes to be applied to the HTML content tag, such as styling or special properties. Please note, any Procs passed
|
130
|
+
# in will automatically be evaluated (For example: :class => lambda { cycle("even", "odd") })
|
113
131
|
# [+block+]
|
114
132
|
# The default block to render if no such block block that is to be rendered when "blocks.render" is called for this block.
|
115
133
|
def render(name_or_container, *args, &block)
|
134
|
+
options = args.extract_options!
|
135
|
+
collection = options.delete(:collection)
|
136
|
+
|
116
137
|
buffer = ActiveSupport::SafeBuffer.new
|
117
|
-
|
118
|
-
|
119
|
-
|
138
|
+
|
139
|
+
if collection
|
140
|
+
as = options.delete(:as)
|
141
|
+
|
142
|
+
collection.each do |object|
|
143
|
+
cloned_args = args.clone
|
144
|
+
cloned_args.unshift(object)
|
145
|
+
cloned_options = options.clone
|
146
|
+
cloned_options = cloned_options.merge(object.options) if object.is_a?(BuildingBlocks::Container)
|
147
|
+
cloned_args.push(cloned_options)
|
148
|
+
|
149
|
+
block_name = evaluated_proc(name_or_container, *cloned_args)
|
150
|
+
as_name = (as.presence || block_name).to_sym
|
151
|
+
cloned_options[as_name] = object
|
152
|
+
|
153
|
+
buffer << render(block_name, *cloned_args, &block)
|
154
|
+
end
|
155
|
+
else
|
156
|
+
surrounding_tag = options.delete(:surrounding_tag)
|
157
|
+
surrounding_tag_html = options.delete(:surrounding_tag_html)
|
158
|
+
|
159
|
+
args.push(options)
|
160
|
+
|
161
|
+
if surrounding_tag_surrounds_before_and_after_blocks
|
162
|
+
buffer << content_tag(surrounding_tag, surrounding_tag_html, *args) do
|
163
|
+
temp_buffer = ActiveSupport::SafeBuffer.new
|
164
|
+
temp_buffer << render_before_blocks(name_or_container, *args)
|
165
|
+
temp_buffer << render_block_with_around_blocks(name_or_container, *args, &block)
|
166
|
+
temp_buffer << render_after_blocks(name_or_container, *args)
|
167
|
+
end
|
168
|
+
else
|
169
|
+
buffer << render_before_blocks(name_or_container, *args)
|
170
|
+
buffer << content_tag(surrounding_tag, surrounding_tag_html, *args) do
|
171
|
+
render_block_with_around_blocks(name_or_container, *args, &block)
|
172
|
+
end
|
173
|
+
buffer << render_after_blocks(name_or_container, *args)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
120
177
|
buffer
|
121
178
|
end
|
122
179
|
alias use render
|
@@ -222,7 +279,7 @@ module BuildingBlocks
|
|
222
279
|
# Step 1 (:option1 => <%= options[option1] %>, :option2 => <%= options[option2] %>)<br />
|
223
280
|
# <% end %>
|
224
281
|
#
|
225
|
-
# <%= blocks.
|
282
|
+
# <%= blocks.render :wizard %>
|
226
283
|
#
|
227
284
|
# <!-- Will render:
|
228
285
|
# Step 0 (:option1 => 3, :option2 => 2)<br />
|
@@ -261,7 +318,7 @@ module BuildingBlocks
|
|
261
318
|
# Step 4 (:option1 => <%= options[option1] %>, :option2 => <%= options[option2] %>)<br />
|
262
319
|
# <% end %>
|
263
320
|
#
|
264
|
-
# <%= blocks.
|
321
|
+
# <%= blocks.render :wizard %>
|
265
322
|
#
|
266
323
|
# <!-- Will render:
|
267
324
|
# Step 2 (:option1 => 1, :option2 => 2)<br />
|
@@ -283,16 +340,66 @@ module BuildingBlocks
|
|
283
340
|
nil
|
284
341
|
end
|
285
342
|
alias append after
|
343
|
+
alias for after
|
344
|
+
|
345
|
+
# Add a block to render around another block. This around block will be put into an array so that multiple
|
346
|
+
# around blocks may be queued. They will render in the order in which they are declared when the
|
347
|
+
# "blocks#render" method is called, with the last declared around block being rendered as the outer-most code, and
|
348
|
+
# the first declared around block rendered as the inner-most code. Any options specified to the after block will override any options
|
349
|
+
# specified in the block definition. The user of an around block must declare a block with at least one parameter and
|
350
|
+
# should invoke the #call method on that argument.
|
351
|
+
#
|
352
|
+
# <% blocks.define :my_block do %>
|
353
|
+
# test
|
354
|
+
# <% end %>
|
355
|
+
#
|
356
|
+
# <% blocks.around :my_block do |content_block| %>
|
357
|
+
# <h1>
|
358
|
+
# <%= content_block.call %>
|
359
|
+
# </h1>
|
360
|
+
# <% end %>
|
361
|
+
#
|
362
|
+
# <% blocks.around :my_block do |content_block| %>
|
363
|
+
# <span style="color:red">
|
364
|
+
# <%= content_block.call %>
|
365
|
+
# </span>
|
366
|
+
# <% end %>
|
367
|
+
#
|
368
|
+
# <%= blocks.render :my_block %>
|
369
|
+
#
|
370
|
+
# <!-- Will render:
|
371
|
+
# <h1>
|
372
|
+
# <span style="color:red">
|
373
|
+
# test
|
374
|
+
# </span>
|
375
|
+
# </h1>
|
376
|
+
#
|
377
|
+
# Options:
|
378
|
+
# [+name+]
|
379
|
+
# The name of the block to render this code around when that block is rendered
|
380
|
+
# [+options+]
|
381
|
+
# Any options to specify to the around block when it renders. These will override any options
|
382
|
+
# specified when the block was defined.
|
383
|
+
# [+block+]
|
384
|
+
# The block of code to render after another block
|
385
|
+
def around(name, options={}, &block)
|
386
|
+
self.queue_block_container("around_#{name.to_s}", options, &block)
|
387
|
+
nil
|
388
|
+
end
|
286
389
|
|
287
390
|
def evaluated_procs(*args)
|
288
|
-
options = args.
|
289
|
-
options.
|
391
|
+
options = args.shift.presence || {}
|
392
|
+
if options.is_a?(Proc)
|
393
|
+
evaluated_proc(options, *args)
|
394
|
+
else
|
395
|
+
options.inject({}) { |hash, (k, v)| hash[k] = evaluated_proc(v, *args); hash}
|
396
|
+
end
|
290
397
|
end
|
291
398
|
|
292
399
|
def evaluated_proc(*args)
|
293
400
|
return nil unless args.present?
|
294
|
-
v = args.
|
295
|
-
v.is_a?(Proc) ? v.call(*args) : v
|
401
|
+
v = args.shift
|
402
|
+
v.is_a?(Proc) ? v.call(*(args[0, v.arity])) : v
|
296
403
|
end
|
297
404
|
|
298
405
|
protected
|
@@ -320,7 +427,7 @@ module BuildingBlocks
|
|
320
427
|
end
|
321
428
|
|
322
429
|
def initialize(view, options={})
|
323
|
-
self.
|
430
|
+
self.template_folder = options[:template_folder] ? options.delete(:template_folder) : BuildingBlocks.template_folder
|
324
431
|
self.variable = (options[:variable] ? options.delete(:variable) : :blocks).to_sym
|
325
432
|
self.view = view
|
326
433
|
self.global_options = options
|
@@ -328,9 +435,8 @@ module BuildingBlocks
|
|
328
435
|
self.blocks = {}
|
329
436
|
self.anonymous_block_number = 0
|
330
437
|
self.block_groups = {}
|
331
|
-
self.use_partials = options[:use_partials].nil? ? BuildingBlocks
|
332
|
-
self.
|
333
|
-
options[:use_partials_for_before_and_after_hooks] ? options.delete(:use_partials_for_before_and_after_hooks) : BuildingBlocks::USE_PARTIALS_FOR_BEFORE_AND_AFTER_HOOKS
|
438
|
+
self.use_partials = options[:use_partials].nil? ? BuildingBlocks.use_partials : options.delete(:use_partials)
|
439
|
+
self.surrounding_tag_surrounds_before_and_after_blocks = options[:surrounding_tag_surrounds_before_and_after_blocks].nil? ? BuildingBlocks.surrounding_tag_surrounds_before_and_after_blocks : options.delete(:surrounding_tag_surrounds_before_and_after_blocks)
|
334
440
|
end
|
335
441
|
|
336
442
|
# Return a unique name for an anonymously defined block (i.e. a block that has not been given a name)
|
@@ -339,6 +445,23 @@ module BuildingBlocks
|
|
339
445
|
"block_#{anonymous_block_number}"
|
340
446
|
end
|
341
447
|
|
448
|
+
def render_block_with_around_blocks(name_or_container, *args, &block)
|
449
|
+
name = name_or_container.is_a?(BuildingBlocks::Container) ? name_or_container.name.to_sym : name_or_container.to_sym
|
450
|
+
around_name = "around_#{name.to_s}".to_sym
|
451
|
+
|
452
|
+
around_blocks = blocks[around_name].present? ? blocks[around_name].clone : []
|
453
|
+
|
454
|
+
content_block = Proc.new do
|
455
|
+
block_container = around_blocks.shift
|
456
|
+
if block_container
|
457
|
+
view.capture(content_block, *(args[0, block_container.block.arity - 1]), &block_container.block)
|
458
|
+
else
|
459
|
+
render_block(name_or_container, *args, &block)
|
460
|
+
end
|
461
|
+
end
|
462
|
+
content_block.call
|
463
|
+
end
|
464
|
+
|
342
465
|
# Render a block, first trying to find a previously defined block with the same name
|
343
466
|
def render_block(name_or_container, *args, &block)
|
344
467
|
options = args.extract_options!
|
@@ -362,7 +485,7 @@ module BuildingBlocks
|
|
362
485
|
begin
|
363
486
|
buffer << view.render("#{name.to_s}", global_options.merge(block_options).merge(options))
|
364
487
|
rescue ActionView::MissingTemplate
|
365
|
-
buffer << view.render("#{self.
|
488
|
+
buffer << view.render("#{self.template_folder}/#{name.to_s}", global_options.merge(block_options).merge(options))
|
366
489
|
end
|
367
490
|
rescue ActionView::MissingTemplate
|
368
491
|
args.push(global_options.merge(options))
|
@@ -402,22 +525,11 @@ module BuildingBlocks
|
|
402
525
|
before_name = "#{before_or_after}_#{name.to_s}".to_sym
|
403
526
|
buffer = ActiveSupport::SafeBuffer.new
|
404
527
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
end
|
411
|
-
elsif use_partials && use_partials_for_before_and_after_hooks
|
412
|
-
begin
|
413
|
-
begin
|
414
|
-
buffer << view.render("#{before_or_after}_#{name.to_s}", global_options.merge(block_options).merge(options))
|
415
|
-
rescue ActionView::MissingTemplate
|
416
|
-
buffer << view.render("#{self.templates_folder}/#{before_or_after}_#{name.to_s}", global_options.merge(block_options).merge(options))
|
417
|
-
end
|
418
|
-
rescue ActionView::MissingTemplate
|
419
|
-
end
|
420
|
-
end
|
528
|
+
blocks[before_name].each do |block_container|
|
529
|
+
args_clone = args.clone
|
530
|
+
args_clone.push(global_options.merge(block_options).merge(block_container.options).merge(options))
|
531
|
+
buffer << view.capture(*(args_clone[0, block_container.block.arity]), &block_container.block)
|
532
|
+
end if blocks[before_name].present?
|
421
533
|
|
422
534
|
buffer
|
423
535
|
end
|
@@ -451,5 +563,13 @@ module BuildingBlocks
|
|
451
563
|
blocks[block_container.name] = block_container if blocks[block_container.name].nil? && block_given?
|
452
564
|
block_container
|
453
565
|
end
|
566
|
+
|
567
|
+
def content_tag(tag, tag_html, *args, &block)
|
568
|
+
if tag
|
569
|
+
view.content_tag(tag, block.call, evaluated_procs(tag_html, *args))
|
570
|
+
else
|
571
|
+
block.call
|
572
|
+
end
|
573
|
+
end
|
454
574
|
end
|
455
575
|
end
|
@@ -4,10 +4,9 @@ module BuildingBlocks
|
|
4
4
|
def blocks
|
5
5
|
@blocks ||= BuildingBlocks::Base.new(self)
|
6
6
|
end
|
7
|
+
alias bb blocks
|
8
|
+
alias buildingblocks blocks
|
9
|
+
alias building_blocks blocks
|
7
10
|
end
|
8
11
|
end
|
9
|
-
end
|
10
|
-
|
11
|
-
if defined?(ActionView::Base)
|
12
|
-
ActionView::Base.send :include, BuildingBlocks::ViewAdditions::ClassMethods
|
13
12
|
end
|
@@ -7,8 +7,7 @@ describe BuildingBlocks::Base do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should be able change the default global partials directory" do
|
10
|
-
BuildingBlocks.
|
11
|
-
BuildingBlocks.const_set("TEMPLATE_FOLDER", "shared")
|
10
|
+
BuildingBlocks.template_folder = "shared"
|
12
11
|
@builder = BuildingBlocks::Base.new(@view)
|
13
12
|
@builder.expects(:render_before_blocks).at_least_once
|
14
13
|
@builder.expects(:render_after_blocks).at_least_once
|
@@ -16,8 +15,6 @@ describe BuildingBlocks::Base do
|
|
16
15
|
@view.expects(:render).with("some_block", :value1 => 1, :value2 => 2).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
17
16
|
@view.expects(:render).with("shared/some_block", :value1 => 1, :value2 => 2).once
|
18
17
|
@builder.render :some_block, :value1 => 1, :value2 => 2
|
19
|
-
BuildingBlocks.send(:remove_const, "TEMPLATE_FOLDER")
|
20
|
-
BuildingBlocks.const_set("TEMPLATE_FOLDER", "blocks")
|
21
18
|
end
|
22
19
|
|
23
20
|
describe "defined? method" do
|
@@ -185,6 +182,12 @@ describe BuildingBlocks::Base do
|
|
185
182
|
end
|
186
183
|
|
187
184
|
describe "before method" do
|
185
|
+
it "should be aliased with prepend" do
|
186
|
+
block = Proc.new { |options| }
|
187
|
+
@builder.prepend :some_block, &block
|
188
|
+
@builder.blocks[:before_some_block].should be_present
|
189
|
+
end
|
190
|
+
|
188
191
|
it "should defined before blocks as the block name with the word 'before_' prepended to it" do
|
189
192
|
block = Proc.new { |options| }
|
190
193
|
@builder.before :some_block, &block
|
@@ -232,6 +235,16 @@ describe BuildingBlocks::Base do
|
|
232
235
|
end
|
233
236
|
|
234
237
|
describe "after method" do
|
238
|
+
it "should be aliased with append and for" do
|
239
|
+
block = Proc.new { |options| }
|
240
|
+
@builder.append :some_block, &block
|
241
|
+
@builder.blocks[:after_some_block].should be_present
|
242
|
+
|
243
|
+
block = Proc.new { |options| }
|
244
|
+
@builder.for :some_block, &block
|
245
|
+
@builder.blocks[:after_some_block].should be_present
|
246
|
+
end
|
247
|
+
|
235
248
|
it "should defined after blocks as the block name with the word 'after_' prepended to it" do
|
236
249
|
block = Proc.new { |options| }
|
237
250
|
@builder.after :some_block, &block
|
@@ -279,9 +292,10 @@ describe BuildingBlocks::Base do
|
|
279
292
|
end
|
280
293
|
|
281
294
|
describe "render method" do
|
282
|
-
|
283
|
-
|
284
|
-
@builder.
|
295
|
+
it "should alias the render method as use" do
|
296
|
+
block = Proc.new {"output"}
|
297
|
+
@builder.define :some_block, &block
|
298
|
+
@builder.use(:some_block).should eql "output"
|
285
299
|
end
|
286
300
|
|
287
301
|
it "should be able to use a defined block by its name" do
|
@@ -404,6 +418,101 @@ describe BuildingBlocks::Base do
|
|
404
418
|
buffer = @builder.render :some_block
|
405
419
|
buffer.should eql "rendered content"
|
406
420
|
end
|
421
|
+
|
422
|
+
describe "with a collection passed in" do
|
423
|
+
it "should render a block for each element of the collection with the name of the block used as the name of the element passed into the block" do
|
424
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
425
|
+
@builder.define :some_block, &block
|
426
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "output1 output2 output3 "
|
427
|
+
end
|
428
|
+
|
429
|
+
it "should render a block for each element of the collection with the 'as' option specifying the name of the element passed into the block" do
|
430
|
+
block = Proc.new {|item, options| "output#{options[:my_block_name]} "}
|
431
|
+
@builder.define :some_block, &block
|
432
|
+
@builder.render(:some_block, :collection => [1,2,3], :as => "my_block_name").should eql "output1 output2 output3 "
|
433
|
+
end
|
434
|
+
|
435
|
+
it "should render a block for each element of the collection with a surrounding element if that option is specified" do
|
436
|
+
block = Proc.new {|item, options| "output#{options[:my_block_name]} "}
|
437
|
+
@builder.define :some_block, &block
|
438
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "<div>output </div><div>output </div><div>output </div>"
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should render a block for each element of the collection with a surrounding element and specified html options if those options are specified" do
|
442
|
+
block = Proc.new {|item, options| "output#{options[:my_block_name]} "}
|
443
|
+
@builder.define :some_block, &block
|
444
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div", :surrounding_tag_html => {:class => lambda { @view.cycle("even", "odd")}, :style => "color:red"}).should eql "<div class=\"even\" style=\"color:red\">output </div><div class=\"odd\" style=\"color:red\">output </div><div class=\"even\" style=\"color:red\">output </div>"
|
445
|
+
end
|
446
|
+
|
447
|
+
it "should be able to render before blocks before each element of a collection" do
|
448
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
449
|
+
@builder.before :some_block, &before_block
|
450
|
+
|
451
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
452
|
+
@builder.define :some_block, &block
|
453
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "before1 output1 before2 output2 before3 output3 "
|
454
|
+
end
|
455
|
+
|
456
|
+
it "should be able to render after blocks before each element of a collection" do
|
457
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
458
|
+
@builder.after :some_block, &after_block
|
459
|
+
|
460
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
461
|
+
@builder.define :some_block, &block
|
462
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "output1 after1 output2 after2 output3 after3 "
|
463
|
+
end
|
464
|
+
|
465
|
+
it "should be able to render before and after blocks before each element of a collection" do
|
466
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
467
|
+
@builder.before :some_block, &before_block
|
468
|
+
|
469
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
470
|
+
@builder.after :some_block, &after_block
|
471
|
+
|
472
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
473
|
+
@builder.define :some_block, &block
|
474
|
+
@builder.render(:some_block, :collection => [1,2,3]).should eql "before1 output1 after1 before2 output2 after2 before3 output3 after3 "
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should by default put surrounding elements around before and after blocks" do
|
478
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
479
|
+
@builder.before :some_block, &before_block
|
480
|
+
|
481
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
482
|
+
@builder.after :some_block, &after_block
|
483
|
+
|
484
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
485
|
+
@builder.define :some_block, &block
|
486
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "<div>before1 output1 after1 </div><div>before2 output2 after2 </div><div>before3 output3 after3 </div>"
|
487
|
+
end
|
488
|
+
|
489
|
+
it "should allow the global option to be set to render before and after blocks outside of surrounding elements" do
|
490
|
+
BuildingBlocks.surrounding_tag_surrounds_before_and_after_blocks = false
|
491
|
+
@builder = BuildingBlocks::Base.new(@view)
|
492
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
493
|
+
@builder.before :some_block, &before_block
|
494
|
+
|
495
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
496
|
+
@builder.after :some_block, &after_block
|
497
|
+
|
498
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
499
|
+
@builder.define :some_block, &block
|
500
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "before1 <div>output1 </div>after1 before2 <div>output2 </div>after2 before3 <div>output3 </div>after3 "
|
501
|
+
end
|
502
|
+
|
503
|
+
it "should allow the option to be set to render before and after blocks outside of surrounding elements to be specified when BuildingBlocks is initialized" do
|
504
|
+
@builder = BuildingBlocks::Base.new(@view, :surrounding_tag_surrounds_before_and_after_blocks => false)
|
505
|
+
before_block = Proc.new {|item, options| "before#{options[:some_block]} "}
|
506
|
+
@builder.before :some_block, &before_block
|
507
|
+
|
508
|
+
after_block = Proc.new {|item, options| "after#{options[:some_block]} "}
|
509
|
+
@builder.after :some_block, &after_block
|
510
|
+
|
511
|
+
block = Proc.new {|item, options| "output#{options[:some_block]} "}
|
512
|
+
@builder.define :some_block, &block
|
513
|
+
@builder.render(:some_block, :collection => [1,2,3], :surrounding_tag => "div").should eql "before1 <div>output1 </div>after1 before2 <div>output2 </div>after2 before3 <div>output3 </div>after3 "
|
514
|
+
end
|
515
|
+
end
|
407
516
|
end
|
408
517
|
|
409
518
|
describe "render method - before blocks" do
|
@@ -419,42 +528,6 @@ describe BuildingBlocks::Base do
|
|
419
528
|
@builder.render :my_before_block, 1, 2, :value3 => 3, :value4 => 4
|
420
529
|
end
|
421
530
|
|
422
|
-
it "should try and render a before block as a local partial if no before blocks are specified and use_partials_for_before_and_after_hooks is set to true" do
|
423
|
-
@builder.use_partials_for_before_and_after_hooks = true
|
424
|
-
block = Proc.new {}
|
425
|
-
@view.expects(:capture).never
|
426
|
-
@view.expects(:render).with("before_my_before_block", :value1 => 1, :value2 => 2).once
|
427
|
-
@view.expects(:render).with("blocks/before_my_before_block", :value1 => 1, :value2 => 2).never
|
428
|
-
@builder.render :my_before_block, :value1 => 1, :value2 => 2
|
429
|
-
end
|
430
|
-
|
431
|
-
it "should try and render a before block as a global partial if no after blocks are specified and the local partial does not exist and use_partials_for_before_and_after_hooks is set to true" do
|
432
|
-
@builder.use_partials_for_before_and_after_hooks = true
|
433
|
-
block = Proc.new {}
|
434
|
-
@view.expects(:capture).never
|
435
|
-
@view.expects(:render).with("before_my_before_block", :value1 => 1, :value2 => 2).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
436
|
-
@view.expects(:render).with("blocks/before_my_before_block", :value1 => 1, :value2 => 2).once
|
437
|
-
@builder.render :my_before_block, :value1 => 1, :value2 => 2
|
438
|
-
end
|
439
|
-
|
440
|
-
it "should not attempt to render a before block as a partial if use_partials is set to false even if use_partials_for_before_and_after_hooks is set to true" do
|
441
|
-
@builder.use_partials = false
|
442
|
-
@builder.use_partials_for_before_and_after_hooks = true
|
443
|
-
block = Proc.new {}
|
444
|
-
@view.expects(:capture).never
|
445
|
-
@view.expects(:render).with("before_my_before_block", :value1 => 1, :value2 => 2).never
|
446
|
-
@view.expects(:render).with("blocks/before_my_before_block", :value1 => 1, :value2 => 2).never
|
447
|
-
@builder.render :my_before_block, :value1 => 1, :value2 => 2
|
448
|
-
end
|
449
|
-
|
450
|
-
it "should not attempt to render a before block as a partial if use_partials_for_before_and_after_hooks is set to false" do
|
451
|
-
block = Proc.new {}
|
452
|
-
@view.expects(:capture).never
|
453
|
-
@view.expects(:render).with("before_my_before_block", :value1 => 1, :value2 => 2).never
|
454
|
-
@view.expects(:render).with("blocks/before_my_before_block", :value1 => 1, :value2 => 2).never
|
455
|
-
@builder.render :my_before_block, :value1 => 1, :value2 => 2
|
456
|
-
end
|
457
|
-
|
458
531
|
it "should override hash options for before blocks by merging the runtime options into the before block options into the block options into the global options" do
|
459
532
|
block = Proc.new {|options|}
|
460
533
|
@builder.global_options.merge!(:param1 => "global level", :param2 => "global level", :param3 => "global level", :param4 => "global level")
|
@@ -464,7 +537,29 @@ describe BuildingBlocks::Base do
|
|
464
537
|
@builder.render :my_before_block, :param1 => "top level"
|
465
538
|
end
|
466
539
|
end
|
467
|
-
|
540
|
+
|
541
|
+
describe "render method - around blocks" do
|
542
|
+
it "should be able to render code around another block" do
|
543
|
+
my_block = Proc.new { "test" }
|
544
|
+
around_block = Proc.new { |content_block| "<span>#{content_block.call}</span>" }
|
545
|
+
@builder.define(:my_block, &my_block)
|
546
|
+
@builder.around(:my_block, &around_block)
|
547
|
+
@builder.render(:my_block).should eql("<span>test</span>")
|
548
|
+
end
|
549
|
+
|
550
|
+
it "should be able to nest multiple around blocks with the last defined around block on the outside" do
|
551
|
+
my_block = Proc.new { "test" }
|
552
|
+
around_block1 = Proc.new { |content_block| "<h1>#{content_block.call}</h1>" }
|
553
|
+
around_block2 = Proc.new { |content_block| "<span style='font-size: 100px'>#{content_block.call}</span>" }
|
554
|
+
around_block3 = Proc.new { |content_block| "<span style='color:red'>#{content_block.call}</span>" }
|
555
|
+
@builder.define(:my_block, &my_block)
|
556
|
+
@builder.around(:my_block, &around_block1)
|
557
|
+
@builder.around(:my_block, &around_block2)
|
558
|
+
@builder.around(:my_block, &around_block3)
|
559
|
+
@builder.render(:my_block).should eql("<h1>&lt;span style='font-size: 100px'&gt;&amp;lt;span style='color:red'&amp;gt;test&amp;lt;/span&amp;gt;&lt;/span&gt;</h1>")
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
468
563
|
describe "render method - after blocks" do
|
469
564
|
before :each do
|
470
565
|
@builder.expects(:render_block).at_least_once
|
@@ -478,42 +573,6 @@ describe BuildingBlocks::Base do
|
|
478
573
|
@builder.render :my_after_block, 1, 2, :value3 => 3, :value4 => 4
|
479
574
|
end
|
480
575
|
|
481
|
-
it "should try and render a after block as a local partial if no after blocks are specified and use_partials_for_before_and_after_hooks is set to true" do
|
482
|
-
@builder.use_partials_for_before_and_after_hooks = true
|
483
|
-
block = Proc.new {}
|
484
|
-
@view.expects(:capture).never
|
485
|
-
@view.expects(:render).with("after_my_after_block", :value1 => 1, :value2 => 2).once
|
486
|
-
@view.expects(:render).with("blocks/after_my_after_block", :value1 => 1, :value2 => 2).never
|
487
|
-
@builder.render :my_after_block, :value1 => 1, :value2 => 2
|
488
|
-
end
|
489
|
-
|
490
|
-
it "should try and render a after block as a global partial if no after blocks are specified and the local partial does not exist and use_partials_for_before_and_after_hooks is set to true" do
|
491
|
-
@builder.use_partials_for_before_and_after_hooks = true
|
492
|
-
block = Proc.new {}
|
493
|
-
@view.expects(:capture).never
|
494
|
-
@view.expects(:render).with("after_my_after_block", :value1 => 1, :value2 => 2).raises(ActionView::MissingTemplate.new([],[],[],[],[]))
|
495
|
-
@view.expects(:render).with("blocks/after_my_after_block", :value1 => 1, :value2 => 2).once
|
496
|
-
@builder.render :my_after_block, :value1 => 1, :value2 => 2
|
497
|
-
end
|
498
|
-
|
499
|
-
it "should not attempt to render a after block as a partial if use_partials is set to false even if use_partials_for_before_and_after_hooks is set to false" do
|
500
|
-
@builder.use_partials = false
|
501
|
-
@builder.use_partials_for_before_and_after_hooks = true
|
502
|
-
block = Proc.new {}
|
503
|
-
@view.expects(:capture).never
|
504
|
-
@view.expects(:render).with("after_my_after_block", :value1 => 1, :value2 => 2).never
|
505
|
-
@view.expects(:render).with("blocks/after_my_after_block", :value1 => 1, :value2 => 2).never
|
506
|
-
@builder.render :my_after_block, :value1 => 1, :value2 => 2
|
507
|
-
end
|
508
|
-
|
509
|
-
it "should not attempt to render a after block as a partial if use_partials_for_before_and_after_hooks is set to false" do
|
510
|
-
block = Proc.new {}
|
511
|
-
@view.expects(:capture).never
|
512
|
-
@view.expects(:render).with("after_my_after_block", :value1 => 1, :value2 => 2).never
|
513
|
-
@view.expects(:render).with("blocks/after_my_after_block", :value1 => 1, :value2 => 2).never
|
514
|
-
@builder.render :my_after_block, :value1 => 1, :value2 => 2
|
515
|
-
end
|
516
|
-
|
517
576
|
it "should override hash options for after blocks by merging the runtime options into the after block options into the block options into the global options" do
|
518
577
|
block = Proc.new {|options|}
|
519
578
|
@builder.global_options.merge!(:param1 => "global level", :param2 => "global level", :param3 => "global level", :param4 => "global level")
|
@@ -562,32 +621,34 @@ describe BuildingBlocks::Base do
|
|
562
621
|
|
563
622
|
it "should pass any additional arguments to evaluated procs" do
|
564
623
|
proc1 = lambda { |param1, param2| "user_#{param1}_#{param2}"}
|
565
|
-
evaluated_procs = @builder.evaluated_procs(
|
624
|
+
evaluated_procs = @builder.evaluated_procs({:class => proc1}, 1, 2)
|
566
625
|
evaluated_procs[:class].should eql "user_1_2"
|
567
626
|
end
|
627
|
+
end
|
568
628
|
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
629
|
+
describe "evaluated_proc method" do
|
630
|
+
it "should evaluate a proc" do
|
631
|
+
proc = lambda {@view.cycle("even", "odd")}
|
632
|
+
@builder.evaluated_proc(proc).should eql "even"
|
633
|
+
@builder.evaluated_proc(proc).should eql "odd"
|
634
|
+
@builder.evaluated_proc(proc).should eql "even"
|
635
|
+
end
|
574
636
|
|
575
|
-
|
576
|
-
|
577
|
-
|
637
|
+
it "should just return the value if it is not a proc" do
|
638
|
+
@builder.evaluated_proc("1234").should eql "1234"
|
639
|
+
end
|
578
640
|
|
579
|
-
|
580
|
-
|
581
|
-
|
641
|
+
it "should return nil if no arguments are specified" do
|
642
|
+
@builder.evaluated_proc.should be_nil
|
643
|
+
end
|
582
644
|
|
583
|
-
|
584
|
-
|
585
|
-
|
645
|
+
it "should treat the first argument as the potential proc to evaluate" do
|
646
|
+
@builder.evaluated_proc(1, 2, 3).should eql 1
|
647
|
+
end
|
586
648
|
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
end
|
649
|
+
it "should pass any additional arguments to the evaluated proc" do
|
650
|
+
proc1 = lambda { |param1, param2| "user_#{param1}_#{param2}"}
|
651
|
+
@builder.evaluated_proc(proc1, 1, 2).should eql "user_1_2"
|
591
652
|
end
|
592
653
|
end
|
593
654
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BuildingBlocks do
|
4
|
+
it "should provide a util method to render a template" do
|
5
|
+
view = stub
|
6
|
+
options = stub
|
7
|
+
partial = stub
|
8
|
+
block = Proc.new { |options| }
|
9
|
+
base_mock = mock
|
10
|
+
base_mock.expects(:render_template).with(partial)
|
11
|
+
BuildingBlocks::Base.expects(:new).with(view, options).returns(base_mock)
|
12
|
+
|
13
|
+
BuildingBlocks.render_template(view, partial, options, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should provide a setup method that can be called from an initializer" do
|
17
|
+
BuildingBlocks.template_folder.should eql("blocks")
|
18
|
+
BuildingBlocks.setup do |config|
|
19
|
+
config.should eql(BuildingBlocks)
|
20
|
+
config.template_folder = "shared"
|
21
|
+
end
|
22
|
+
BuildingBlocks.template_folder.should eql("shared")
|
23
|
+
end
|
24
|
+
end
|
@@ -18,5 +18,16 @@ describe BuildingBlocks::ViewAdditions do
|
|
18
18
|
@view.blocks.should eql "something"
|
19
19
|
@view.blocks.should eql "something"
|
20
20
|
end
|
21
|
+
|
22
|
+
it "should be aliased as bb, buildingblocks, and building_blocks" do
|
23
|
+
BuildingBlocks::Base.expects(:new).with {|view| view == @view}
|
24
|
+
@view.bb
|
25
|
+
|
26
|
+
BuildingBlocks::Base.expects(:new).with {|view| view == @view}
|
27
|
+
@view.buildingblocks
|
28
|
+
|
29
|
+
BuildingBlocks::Base.expects(:new).with {|view| view == @view}
|
30
|
+
@view.building_blocks
|
31
|
+
end
|
21
32
|
end
|
22
33
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -9,7 +9,10 @@ end
|
|
9
9
|
|
10
10
|
RSpec.configure do |config|
|
11
11
|
config.mock_with :mocha
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
|
13
|
+
config.before :each do
|
14
|
+
BuildingBlocks.template_folder = "blocks"
|
15
|
+
BuildingBlocks.surrounding_tag_surrounds_before_and_after_blocks = true
|
16
|
+
end
|
15
17
|
end
|
18
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: building-blocks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
-
- 1
|
8
7
|
- 2
|
9
|
-
-
|
10
|
-
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 2.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrew Hunter
|
@@ -15,11 +15,9 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
19
|
-
default_executable:
|
18
|
+
date: 2012-10-18 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
name: building-blocks
|
23
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
22
|
none: false
|
25
23
|
requirements:
|
@@ -29,11 +27,11 @@ dependencies:
|
|
29
27
|
segments:
|
30
28
|
- 0
|
31
29
|
version: "0"
|
30
|
+
requirement: *id001
|
32
31
|
prerelease: false
|
32
|
+
name: building-blocks
|
33
33
|
type: :runtime
|
34
|
-
requirement: *id001
|
35
34
|
- !ruby/object:Gem::Dependency
|
36
|
-
name: rails
|
37
35
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
38
36
|
none: false
|
39
37
|
requirements:
|
@@ -45,11 +43,11 @@ dependencies:
|
|
45
43
|
- 0
|
46
44
|
- 0
|
47
45
|
version: 3.0.0
|
46
|
+
requirement: *id002
|
48
47
|
prerelease: false
|
48
|
+
name: rails
|
49
49
|
type: :runtime
|
50
|
-
requirement: *id002
|
51
50
|
- !ruby/object:Gem::Dependency
|
52
|
-
name: jeweler
|
53
51
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
54
52
|
none: false
|
55
53
|
requirements:
|
@@ -59,11 +57,11 @@ dependencies:
|
|
59
57
|
segments:
|
60
58
|
- 0
|
61
59
|
version: "0"
|
60
|
+
requirement: *id003
|
62
61
|
prerelease: false
|
62
|
+
name: jeweler
|
63
63
|
type: :development
|
64
|
-
requirement: *id003
|
65
64
|
- !ruby/object:Gem::Dependency
|
66
|
-
name: jeweler
|
67
65
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
68
66
|
none: false
|
69
67
|
requirements:
|
@@ -73,11 +71,11 @@ dependencies:
|
|
73
71
|
segments:
|
74
72
|
- 0
|
75
73
|
version: "0"
|
74
|
+
requirement: *id004
|
76
75
|
prerelease: false
|
76
|
+
name: jeweler
|
77
77
|
type: :development
|
78
|
-
requirement: *id004
|
79
78
|
- !ruby/object:Gem::Dependency
|
80
|
-
name: jeweler
|
81
79
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
82
80
|
none: false
|
83
81
|
requirements:
|
@@ -87,11 +85,11 @@ dependencies:
|
|
87
85
|
segments:
|
88
86
|
- 0
|
89
87
|
version: "0"
|
88
|
+
requirement: *id005
|
90
89
|
prerelease: false
|
90
|
+
name: jeweler
|
91
91
|
type: :development
|
92
|
-
requirement: *id005
|
93
92
|
- !ruby/object:Gem::Dependency
|
94
|
-
name: jeweler
|
95
93
|
version_requirements: &id006 !ruby/object:Gem::Requirement
|
96
94
|
none: false
|
97
95
|
requirements:
|
@@ -101,11 +99,11 @@ dependencies:
|
|
101
99
|
segments:
|
102
100
|
- 0
|
103
101
|
version: "0"
|
102
|
+
requirement: *id006
|
104
103
|
prerelease: false
|
104
|
+
name: jeweler
|
105
105
|
type: :development
|
106
|
-
requirement: *id006
|
107
106
|
- !ruby/object:Gem::Dependency
|
108
|
-
name: jeweler
|
109
107
|
version_requirements: &id007 !ruby/object:Gem::Requirement
|
110
108
|
none: false
|
111
109
|
requirements:
|
@@ -115,11 +113,11 @@ dependencies:
|
|
115
113
|
segments:
|
116
114
|
- 0
|
117
115
|
version: "0"
|
116
|
+
requirement: *id007
|
118
117
|
prerelease: false
|
118
|
+
name: jeweler
|
119
119
|
type: :development
|
120
|
-
requirement: *id007
|
121
120
|
- !ruby/object:Gem::Dependency
|
122
|
-
name: jeweler
|
123
121
|
version_requirements: &id008 !ruby/object:Gem::Requirement
|
124
122
|
none: false
|
125
123
|
requirements:
|
@@ -129,11 +127,11 @@ dependencies:
|
|
129
127
|
segments:
|
130
128
|
- 0
|
131
129
|
version: "0"
|
130
|
+
requirement: *id008
|
132
131
|
prerelease: false
|
132
|
+
name: jeweler
|
133
133
|
type: :development
|
134
|
-
requirement: *id008
|
135
134
|
- !ruby/object:Gem::Dependency
|
136
|
-
name: jeweler
|
137
135
|
version_requirements: &id009 !ruby/object:Gem::Requirement
|
138
136
|
none: false
|
139
137
|
requirements:
|
@@ -143,11 +141,11 @@ dependencies:
|
|
143
141
|
segments:
|
144
142
|
- 0
|
145
143
|
version: "0"
|
144
|
+
requirement: *id009
|
146
145
|
prerelease: false
|
146
|
+
name: jeweler
|
147
147
|
type: :development
|
148
|
-
requirement: *id009
|
149
148
|
- !ruby/object:Gem::Dependency
|
150
|
-
name: jeweler
|
151
149
|
version_requirements: &id010 !ruby/object:Gem::Requirement
|
152
150
|
none: false
|
153
151
|
requirements:
|
@@ -157,11 +155,11 @@ dependencies:
|
|
157
155
|
segments:
|
158
156
|
- 0
|
159
157
|
version: "0"
|
158
|
+
requirement: *id010
|
160
159
|
prerelease: false
|
160
|
+
name: jeweler
|
161
161
|
type: :development
|
162
|
-
requirement: *id010
|
163
162
|
- !ruby/object:Gem::Dependency
|
164
|
-
name: jeweler
|
165
163
|
version_requirements: &id011 !ruby/object:Gem::Requirement
|
166
164
|
none: false
|
167
165
|
requirements:
|
@@ -171,11 +169,11 @@ dependencies:
|
|
171
169
|
segments:
|
172
170
|
- 0
|
173
171
|
version: "0"
|
172
|
+
requirement: *id011
|
174
173
|
prerelease: false
|
174
|
+
name: jeweler
|
175
175
|
type: :development
|
176
|
-
requirement: *id011
|
177
176
|
- !ruby/object:Gem::Dependency
|
178
|
-
name: jeweler
|
179
177
|
version_requirements: &id012 !ruby/object:Gem::Requirement
|
180
178
|
none: false
|
181
179
|
requirements:
|
@@ -185,11 +183,11 @@ dependencies:
|
|
185
183
|
segments:
|
186
184
|
- 0
|
187
185
|
version: "0"
|
186
|
+
requirement: *id012
|
188
187
|
prerelease: false
|
188
|
+
name: jeweler
|
189
189
|
type: :development
|
190
|
-
requirement: *id012
|
191
190
|
- !ruby/object:Gem::Dependency
|
192
|
-
name: jeweler
|
193
191
|
version_requirements: &id013 !ruby/object:Gem::Requirement
|
194
192
|
none: false
|
195
193
|
requirements:
|
@@ -199,11 +197,11 @@ dependencies:
|
|
199
197
|
segments:
|
200
198
|
- 0
|
201
199
|
version: "0"
|
200
|
+
requirement: *id013
|
202
201
|
prerelease: false
|
202
|
+
name: jeweler
|
203
203
|
type: :development
|
204
|
-
requirement: *id013
|
205
204
|
- !ruby/object:Gem::Dependency
|
206
|
-
name: jeweler
|
207
205
|
version_requirements: &id014 !ruby/object:Gem::Requirement
|
208
206
|
none: false
|
209
207
|
requirements:
|
@@ -213,11 +211,11 @@ dependencies:
|
|
213
211
|
segments:
|
214
212
|
- 0
|
215
213
|
version: "0"
|
214
|
+
requirement: *id014
|
216
215
|
prerelease: false
|
216
|
+
name: jeweler
|
217
217
|
type: :development
|
218
|
-
requirement: *id014
|
219
218
|
- !ruby/object:Gem::Dependency
|
220
|
-
name: jeweler
|
221
219
|
version_requirements: &id015 !ruby/object:Gem::Requirement
|
222
220
|
none: false
|
223
221
|
requirements:
|
@@ -227,11 +225,11 @@ dependencies:
|
|
227
225
|
segments:
|
228
226
|
- 0
|
229
227
|
version: "0"
|
228
|
+
requirement: *id015
|
230
229
|
prerelease: false
|
230
|
+
name: jeweler
|
231
231
|
type: :development
|
232
|
-
requirement: *id015
|
233
232
|
- !ruby/object:Gem::Dependency
|
234
|
-
name: jeweler
|
235
233
|
version_requirements: &id016 !ruby/object:Gem::Requirement
|
236
234
|
none: false
|
237
235
|
requirements:
|
@@ -241,10 +239,25 @@ dependencies:
|
|
241
239
|
segments:
|
242
240
|
- 0
|
243
241
|
version: "0"
|
242
|
+
requirement: *id016
|
244
243
|
prerelease: false
|
244
|
+
name: jeweler
|
245
245
|
type: :development
|
246
|
-
|
247
|
-
|
246
|
+
- !ruby/object:Gem::Dependency
|
247
|
+
version_requirements: &id017 !ruby/object:Gem::Requirement
|
248
|
+
none: false
|
249
|
+
requirements:
|
250
|
+
- - ">="
|
251
|
+
- !ruby/object:Gem::Version
|
252
|
+
hash: 3
|
253
|
+
segments:
|
254
|
+
- 0
|
255
|
+
version: "0"
|
256
|
+
requirement: *id017
|
257
|
+
prerelease: false
|
258
|
+
name: jeweler
|
259
|
+
type: :development
|
260
|
+
description: BuildingBlocks goes beyond blocks and partials
|
248
261
|
email: hunterae@gmail.com
|
249
262
|
executables: []
|
250
263
|
|
@@ -258,14 +271,15 @@ files:
|
|
258
271
|
- Rakefile
|
259
272
|
- VERSION
|
260
273
|
- lib/building-blocks.rb
|
274
|
+
- lib/building_blocks.rb
|
261
275
|
- lib/building_blocks/base.rb
|
262
276
|
- lib/building_blocks/container.rb
|
263
277
|
- lib/building_blocks/view_additions.rb
|
264
278
|
- rails/init.rb
|
265
279
|
- spec/building-blocks/base_spec.rb
|
280
|
+
- spec/building-blocks/building_blocks_spec.rb
|
266
281
|
- spec/building-blocks/view_additions_spec.rb
|
267
282
|
- spec/spec_helper.rb
|
268
|
-
has_rdoc: true
|
269
283
|
homepage: http://github.com/hunterae/building-blocks
|
270
284
|
licenses: []
|
271
285
|
|
@@ -295,9 +309,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
295
309
|
requirements: []
|
296
310
|
|
297
311
|
rubyforge_project:
|
298
|
-
rubygems_version: 1.
|
312
|
+
rubygems_version: 1.8.24
|
299
313
|
signing_key:
|
300
314
|
specification_version: 3
|
301
|
-
summary:
|
315
|
+
summary: BuildingBlocks is an intricate way of rendering blocks of code, while combining some of the best features of content blocks and partials, and adding several new features that go above and beyond what a simple content_for with yield or a render :partial is capable of doing.
|
302
316
|
test_files: []
|
303
317
|
|