blocks 3.0.0.rc4 → 3.0.0.rc5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -2
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +3 -0
  5. data/CHANGELOG.rdoc +7 -0
  6. data/Gemfile +10 -3
  7. data/README.md +25 -9
  8. data/_config.yml +20 -0
  9. data/bin/deploy_docs +2 -0
  10. data/docs/.gitignore +4 -0
  11. data/docs/404.html +23 -0
  12. data/docs/_includes/acknowledgements.md +13 -0
  13. data/docs/_includes/caller-id.md +3 -0
  14. data/docs/_includes/configuration.md +3 -0
  15. data/docs/_includes/custom-builders.md +3 -0
  16. data/docs/_includes/defining.md +615 -0
  17. data/docs/_includes/demos/hooks-and-wrappers-output.html +109 -0
  18. data/docs/_includes/hooks.md +1156 -0
  19. data/docs/_includes/installation.md +25 -0
  20. data/docs/_includes/introduction.md +18 -0
  21. data/docs/_includes/option-merging.md +5 -0
  22. data/docs/_includes/rendering.md +622 -0
  23. data/docs/_includes/reserved-keywords.md +59 -0
  24. data/docs/_includes/skipping.md +403 -0
  25. data/docs/_includes/slate/assets.html +34 -0
  26. data/docs/_includes/slate/language-tabs.html +11 -0
  27. data/docs/_includes/templating.md +48 -0
  28. data/docs/_includes/templating/bootstrap_4_cards.md +753 -0
  29. data/docs/_includes/use-cases.md +23 -0
  30. data/docs/_includes/wip.md +34 -0
  31. data/docs/_includes/wrappers.md +629 -0
  32. data/docs/_layouts/slate.html +75 -0
  33. data/docs/_plugins/gem_version.rb +11 -0
  34. data/docs/_plugins/highlight_with_div.rb +25 -0
  35. data/docs/_sass/_default_styling.scss +627 -0
  36. data/docs/_sass/_icon-font.scss +26 -0
  37. data/docs/_sass/_normalize.scss +427 -0
  38. data/docs/_sass/_styling_overrides.scss +31 -0
  39. data/docs/_sass/_syntax.scss +78 -0
  40. data/docs/_sass/_variable_overrides.scss +10 -0
  41. data/docs/_sass/_variables.scss +105 -0
  42. data/docs/assets/javascripts/script.js +18 -0
  43. data/docs/assets/stylesheets/formChanges.less +106 -0
  44. data/docs/assets/stylesheets/style.css +46 -0
  45. data/docs/fonts/slate.eot +0 -0
  46. data/docs/fonts/slate.svg +14 -0
  47. data/docs/fonts/slate.ttf +0 -0
  48. data/docs/fonts/slate.woff +0 -0
  49. data/docs/fonts/slate.woff2 +0 -0
  50. data/docs/hooks.html +149 -0
  51. data/docs/hooks_and_wrappers_demo.html +313 -0
  52. data/docs/images/favicon.ico +0 -0
  53. data/docs/images/logo.png +0 -0
  54. data/docs/images/navbar.png +0 -0
  55. data/docs/images/placeholder.jpg +0 -0
  56. data/docs/images/render_strategies.png +0 -0
  57. data/docs/images/templating.png +0 -0
  58. data/docs/index.md +32 -0
  59. data/docs/javascripts/all.js +4 -0
  60. data/docs/javascripts/all_nosearch.js +3 -0
  61. data/docs/javascripts/app/lang.js +166 -0
  62. data/docs/javascripts/app/search.js +75 -0
  63. data/docs/javascripts/app/toc.js +57 -0
  64. data/docs/javascripts/demos/hooks_and_wrappers.js +9 -0
  65. data/docs/javascripts/lib/energize.js +169 -0
  66. data/docs/javascripts/lib/imagesloaded.min.js +7 -0
  67. data/docs/javascripts/lib/jquery.highlight.js +108 -0
  68. data/docs/javascripts/lib/jquery.js +9831 -0
  69. data/docs/javascripts/lib/jquery.tocify.js +1042 -0
  70. data/docs/javascripts/lib/jquery_ui.js +566 -0
  71. data/docs/javascripts/lib/lunr.js +1910 -0
  72. data/docs/stylesheets/demos/hooks_and_wrappers.scss +32 -0
  73. data/docs/stylesheets/print.scss +150 -0
  74. data/docs/stylesheets/screen.scss +10 -0
  75. data/lib/blocks/action_view_extensions/view_extensions.rb +1 -0
  76. data/lib/blocks/renderers/renderer.rb +1 -0
  77. data/lib/blocks/renderers/runtime_context.rb +30 -17
  78. data/lib/blocks/utilities/hash_with_render_strategy.rb +3 -0
  79. data/lib/blocks/version.rb +1 -1
  80. metadata +70 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e022666ec160d8b6eee526393d150b0b84c6af8
4
- data.tar.gz: 41b615d2770f0e0a065a9a86db133b9bc89c5f97
3
+ metadata.gz: f3181343926f563e7c9ae1a5a7d4754a3e2a32fb
4
+ data.tar.gz: f88aa1db3c2078d5dacbea759fca59c7d9b4a1d8
5
5
  SHA512:
6
- metadata.gz: a37e882249043b9651fda7c422eb3e9af4714d205ad71bdf7377d368744508e342b60829434c47471ab08be0e7d62922b9b5e7767e40f5031d2a1da2f5d65f2b
7
- data.tar.gz: 39da51207e66968d0e1d4df45ce8de3f2a483fb5b59a6689b93b0d7e84d43d2fb3277463d2d79bd31577de04a821bcaa24b0d281279d496d235d46839f886c08
6
+ metadata.gz: 1720042c59c57226a0a44785b9ea646a0b79e6ff90948414d801609a3cb52253342d22772c58ec4df3a2de6959e5911c17c2e057e9fb608f2f65c5a05f344dd3
7
+ data.tar.gz: 975c4e0b9ee87b4a6b35d293c2006ed84941033ce97bcf92bd690a847ec97a69785df215fa33418370995a0be79637b39ab7d549b8a090d00f5d643488d70b47
data/.gitignore CHANGED
@@ -1,7 +1,9 @@
1
1
  /pkg/*
2
2
  .bundle
3
- .ruby-version
4
3
  .ruby-gemset
5
4
  Gemfile.lock
6
5
  .byebug_history
7
- coverage/
6
+ coverage/
7
+ _site/
8
+ .sass-cache/
9
+ .idea/
@@ -0,0 +1 @@
1
+ 2.4
@@ -1,6 +1,9 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
 
4
+ before_install:
5
+ - gem update bundler
6
+
4
7
  rvm:
5
8
  - 1.9.3
6
9
  - 2.0.0
@@ -1,3 +1,10 @@
1
+ 3.0.0 ()
2
+ * Complete rewrite of the blocks gem
3
+ * Extensive test coverage added
4
+ * Jenkins CI integration
5
+ * Extensive documentation added: http://hunterae.github.io/blocks/
6
+ * Blocks branding and documentation styling applied: Thanks [Alexis Gormley](https://github.com/n2diving)
7
+
1
8
  2.8.0 (January 21, 2016)
2
9
  * When rendering a collection of blocks through blocks.render BLOCK_NAME, collection: COLLECTION,
3
10
  current_index will now be passed as a param for the options hash passed to the block. Example:
data/Gemfile CHANGED
@@ -7,13 +7,20 @@ gem "capybara"
7
7
  gem "rspec", "~> 3.6.0"
8
8
  gem "arel", github: "rails/arel"
9
9
  gem "rails", github: "rails/rails"
10
- gem 'rack'
10
+ gem "rack"
11
11
  gem "shoulda-matchers", "~> 2.0"
12
12
  gem "haml"
13
13
 
14
14
  # Extra development utilities
15
- gem 'ruby_dep'
16
- gem 'guard-rspec', '~> 4.7'
15
+ gem "ruby_dep"
16
+ gem "guard-rspec", "~> 4.7"
17
17
  gem "terminal-notifier-guard"
18
18
  gem "byebug"
19
19
  gem "codeclimate-test-reporter", "~> 1.0.8"
20
+
21
+ group :development, :test do
22
+ gem "jekyll"
23
+ gem "jgd"
24
+ gem "jekyll-feed", "~> 0.6"
25
+ gem "jekyll-coffeescript"
26
+ end
data/README.md CHANGED
@@ -1,8 +1,23 @@
1
1
  # Blocks
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/blocks`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ The Blocks gem is many things.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ It acts as:
6
+
7
+ * a container for reusable blocks of code and options
8
+ * a common interface for rendering code, whether the code was defined previously in Ruby blocks, Rails partials, or proxies to other blocks of code
9
+ * a series of hooks and wrappers that can be utilized to render code before, after, and around other blocks of code, as well as before each, after each, and around each item in a collection
10
+ * a templating utility for easily building reusable and highly customizable UI components
11
+ * a means for DRYing up oft-repeated code in your layouts and views
12
+ * a simple mechanism for changing or skipping the rendering behavior for particular blocks of code
13
+
14
+ Essentially, this all boils down to the following: Blocks makes it easy to define blocks of code that can be rendered either verbatim or with replacements and modifications at some later point in time.
15
+
16
+ [![Build Status](https://travis-ci.org/hunterae/blocks.svg?branch=3-0-stable)](https://travis-ci.org/hunterae/blocks)
17
+
18
+ ## Usage
19
+
20
+ Please checkout the documentation for the Blocks gem here: http://hunterae.github.io/blocks/.
6
21
 
7
22
  ## Installation
8
23
 
@@ -20,20 +35,21 @@ Or install it yourself as:
20
35
 
21
36
  $ gem install blocks
22
37
 
23
- ## Usage
38
+ ## Development
24
39
 
25
- TODO: Write usage instructions here
40
+ After checking out the repo, run `bundle install` (and possibly `gem install bundler` if you don't already have bundler installed) to install dependencies. Then, run `rake` to run the tests. You can also run `bundle console` for an interactive prompt that will allow you to experiment.
26
41
 
27
- ## Development
42
+ ## Documentation
28
43
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
44
+ The documentation is generated using [Jekyll](https://jekyllrb.com/) and hosted on the [Blocks gh-pages branch](https://github.com/hunterae/blocks/tree/gh-pages).
30
45
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
46
+ The static content is generated based on the source code within the [docs directory](https://github.com/hunterae/blocks/tree/3-0-stable/docs).
32
47
 
33
- ## Contributing
48
+ To run the documentation locally or make changes for a corresponding pull request, follow the steps in the [Development Section above](#development). Then run `jekyll serve` and visit http://127.0.0.1:4000/blocks/.
34
49
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/blocks.
50
+ ## Contributing
36
51
 
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hunterae/blocks.
37
53
 
38
54
  ## License
39
55
 
@@ -0,0 +1,20 @@
1
+ title: Blocks Docs
2
+ email: hunterae@gmail.com
3
+ description: Blocks gives you total control over how your blocks of code render.
4
+ baseurl: "/blocks" # the subpath of your site, e.g. /blog
5
+ url: "" # the base hostname & protocol for your site, e.g. http://example.com
6
+ github_username: hunterae
7
+ google_analytics: "UA-104699666-1"
8
+ markdown: kramdown
9
+ source: docs
10
+ destination: _site
11
+ plugins:
12
+ - jekyll-feed
13
+ - jekyll-coffeescript
14
+ sass:
15
+ sass_dir: _sass
16
+ style: compressed
17
+ css_dir: blocks/stylesheets
18
+ js_dir: blocks/javascripts
19
+ images_dir: blocks/images
20
+ fonts_dir: blocks/fonts
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bash
2
+ jgd -r 3-0-stable
@@ -0,0 +1,4 @@
1
+ _site
2
+ .sass-cache
3
+ .jekyll-metadata
4
+ .asset-cache
@@ -0,0 +1,23 @@
1
+ ---
2
+ ---
3
+
4
+ <style type="text/css" media="screen">
5
+ .container {
6
+ margin: 10px auto;
7
+ max-width: 600px;
8
+ text-align: center;
9
+ }
10
+ h1 {
11
+ margin: 30px 0;
12
+ font-size: 4em;
13
+ line-height: 1;
14
+ letter-spacing: -1px;
15
+ }
16
+ </style>
17
+
18
+ <div class="container">
19
+ <h1>404</h1>
20
+
21
+ <p><strong>Page not found :(</strong></p>
22
+ <p>The requested page could not be found.</p>
23
+ </div>
@@ -0,0 +1,13 @@
1
+ # Acknowledgements
2
+
3
+ The [blocks gem](http://github.com/hunterae/blocks) was written and is maintained by [Andrew Hunter](http://github.com/hunterae).
4
+
5
+ If you think this looks somewhat familiar, there's good reason for that. Any similarities you may notice with [Rails's content_for with yield](http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-content_for) and [rendering partials in Rails](https://apidock.com/rails/ActionController/Base/render) are intentional (the proxying feature may even remind you of [Ruby's Forwardable Module](http://ruby-doc.org/stdlib-2.0.0/libdoc/forwardable/rdoc/Forwardable.html)). Part of the original reasoning for the creating this gem was to provide a common interface for rendering both Ruby blocks and Rails' partials.
6
+
7
+ Special thanks to the following people for helping advance this gem and its corresponding documentation forward:
8
+
9
+ * [Todd Fisher](https://github.com/taf2) - For helping me visualize and create the initial inception of this gem back in 2011 and understand how Ruby blocks work
10
+ * [Jon Phillips](https://github.com/elguapo1611) - For helping me work out syntax and use cases for the Blocks gem
11
+ * [Various people and teams at LivingSocial](https://www.livingsocial.com/) - For allowing and believing in me to run with an experimental and unproven technology to help my gem start to take shape into what it is today.
12
+ * [Various people at MobileCause](https://www.mobilecause.com/) - For helping me to advance my vision for this gem into what it is today and what is being documented here.
13
+ * [Alexis Gormley](https://github.com/n2diving) - For suggesting the [Slate theme](https://github.com/lord/slate) for the documentation, designing the gem's branding, and proofing the documentation.
@@ -0,0 +1,3 @@
1
+ # Caller ID
2
+
3
+ TODO
@@ -0,0 +1,3 @@
1
+ # Configuration
2
+
3
+ TODO
@@ -0,0 +1,3 @@
1
+ # Custom Builders
2
+
3
+ TODO
@@ -0,0 +1,615 @@
1
+ # Defining Blocks
2
+
3
+ ```erb
4
+ <% blocks.define :my_block %>
5
+ <!-- OR -->
6
+ <% blocks.define "my_block" %>
7
+ ```
8
+
9
+ ```haml
10
+ - blocks.define :my_block
11
+ #- OR
12
+ - blocks.define "my_block"
13
+ ```
14
+
15
+ ```ruby
16
+ # where builder is an instance
17
+ # of Blocks::Builder
18
+ builder.define :my_block
19
+ # OR
20
+ builder.define "my_block"
21
+ ```
22
+
23
+ With Blocks, you can define a block of code for later rendering using Ruby blocks, Rails partials, and proxies to other blocks.
24
+
25
+ A block consists of a name, a hash of options, and a rendering strategy (also called its definition).
26
+
27
+ A block's name can be a symbol or a string. The underlying system treats symbols and strings the same. Therefore, any block that is defined with a String name can be accessed with its corresponding symbol name and vice-versa.
28
+
29
+ ## With a Ruby Block
30
+
31
+ ```erb
32
+ <% blocks.define :my_block do %>
33
+ content
34
+ <% end %>
35
+ ```
36
+
37
+ ```haml
38
+ - blocks.define :my_block do
39
+ content
40
+ ```
41
+
42
+ ```ruby
43
+ # where builder is an instance
44
+ # of Blocks::Builder
45
+ builder.define :my_block do
46
+ "content"
47
+ end
48
+ ```
49
+
50
+ A Block may be defined as a standard Ruby block.
51
+
52
+ ### With a Proc
53
+
54
+ ```erb
55
+ <% my_block =
56
+ Proc.new { "content" } %>
57
+ <% blocks.define :my_block,
58
+ block: my_block %>
59
+ <!-- OR -->
60
+ <% blocks.define :my_block,
61
+ &my_block %>
62
+ ```
63
+
64
+ ```haml
65
+ - my_block = Proc.new { "content" }
66
+ - blocks.define :my_block,
67
+ block: my_block
68
+ -# OR
69
+ - blocks.define :my_block, &my_block
70
+ ```
71
+
72
+ ```ruby
73
+ # where builder is an instance
74
+ # of Blocks::Builder
75
+ my_block = Proc.new { "content" }
76
+ builder.define :my_block,
77
+ block: my_block
78
+ #OR...
79
+ builder.define :my_block, &my_block
80
+ ```
81
+
82
+ It may also be defined with a Proc
83
+
84
+ ### With a Lambda
85
+
86
+ ```erb
87
+ <% my_block = lambda { "content" } %>
88
+ <% blocks.define :my_block,
89
+ block: my_block %>
90
+ <!-- OR -->
91
+ <% blocks.define :my_block, &my_block %>
92
+ ```
93
+
94
+ ```haml
95
+ Lambdas are kind of a pain in Haml
96
+ and Procs should be used instead
97
+ ```
98
+
99
+ ```ruby
100
+ # where builder is an instance
101
+ # of Blocks::Builder
102
+ my_block = lambda { "content" }
103
+ builder.define :my_block,
104
+ block: my_block
105
+ # OR...
106
+ builder.define :my_block, &my_block
107
+ ```
108
+
109
+ It may also be defined with a Lambda
110
+
111
+ ## With a Rails Partial
112
+
113
+ ```erb
114
+ <%= blocks.define :my_block,
115
+ partial: "my_partial" %>
116
+ ```
117
+
118
+ ```haml
119
+ - blocks.define :my_block,
120
+ partial: "my_partial"
121
+ ```
122
+
123
+ ```ruby
124
+ # where builder is an instance
125
+ # of Blocks::Builder
126
+ - builder.define :my_block,
127
+ partial: "my_partial"
128
+ ```
129
+
130
+ A Block may be defined as a Rails partial using the "partial" keyword in the parameters. Whenever the Block gets rendered, the partial actually gets rendered.
131
+
132
+ ## With a Proxy to Another Block
133
+
134
+ ```erb
135
+ <% blocks.define :my_block,
136
+ with: :some_proxy_block %>
137
+ ```
138
+
139
+ ```haml
140
+ - blocks.define :my_block,
141
+ with: :some_proxy_block
142
+ ```
143
+
144
+ ```ruby
145
+ # where builder is an instance
146
+ # of Blocks::Builder
147
+ - builder.define :my_block,
148
+ with: :some_proxy_block
149
+ ```
150
+
151
+ A Block may be defined as a proxy to another block using the "with" keyword in the parameters.
152
+
153
+ ### Proxying to a method
154
+
155
+ ```erb
156
+ <% builder.define :my_block,
157
+ with: :column %>
158
+ ```
159
+
160
+ ```haml
161
+ - builder.define :my_block,
162
+ with: :column
163
+ ```
164
+
165
+ ```ruby
166
+ builder.define :my_block,
167
+ with: :column
168
+ ```
169
+
170
+ > Where "builder" is an instance of a class that extends Blocks::Builder and has a method called "column".
171
+
172
+ The "with" keyword may also specify the name of a method that will be called on the builder instance when the block is rendered. By default, this will be an instance of Blocks::Builder.
173
+
174
+ Also, a Proxy block can point to a method on the builder instance (by default, this is an instance of Blocks::Builder).
175
+
176
+ ### Proxying to a Proxy
177
+
178
+ ```erb
179
+ <% blocks.define :my_block,
180
+ with: :proxy_1 %>
181
+ <% blocks.define :proxy_1,
182
+ with: :proxy_2 %>
183
+ <% blocks.define :proxy_2 do %>
184
+ My proxied proxied content
185
+ <% end %>
186
+ ```
187
+
188
+ ```haml
189
+ - blocks.define :my_block,
190
+ with: :proxy_1
191
+ - blocks.define :proxy_1,
192
+ with: :proxy_2
193
+ - blocks.define :proxy_2 do
194
+ My proxied proxied content
195
+ ```
196
+
197
+ ```ruby
198
+ # where builder is an instance
199
+ # of Blocks::Builder
200
+ builder.define :my_block,
201
+ with: :proxy_1
202
+ builder.define :proxy_1,
203
+ with: :proxy_2
204
+ builder.define :proxy_2 do
205
+ "My proxied proxied content"
206
+ end
207
+ ```
208
+
209
+ Proxy Blocks can also be chained together though separate definitions. The order of Block definitions is irrelevant - with two caveats:
210
+
211
+ 1. Proxies must be setup before attempting to render them
212
+ 2. If the same block name is defined multiple times with different proxy names, the first one defined will be used
213
+
214
+ ## With Multiple Definitions
215
+
216
+ ```erb
217
+ <% blocks.define :my_block,
218
+ partial: "my_partial" %>
219
+ <% blocks.define :my_block,
220
+ with: :my_proxy %>
221
+ <% blocks.define :my_block do %>
222
+ My Block Definition
223
+ <% end %>
224
+ ```
225
+
226
+ ```haml
227
+ - blocks.define :my_block,
228
+ partial: "my_partial"
229
+ - blocks.define :my_block,
230
+ with: :my_proxy
231
+ - blocks.define :my_block do
232
+ My Block Definition
233
+ ```
234
+
235
+ ```ruby
236
+ # where builder is an instance
237
+ # of Blocks::Builder
238
+ builder.define :my_block,
239
+ partial: "my_partial"
240
+ builder.define :my_block,
241
+ with: :my_proxy
242
+ builder.define :my_block do
243
+ "My Block Definition"
244
+ end
245
+ ```
246
+
247
+ > :my_block will use the partial: "my_partial" when rendered
248
+
249
+ When multiple definitions for the same block name are provided, Blocks will utilize the first definition to occur, whether it's a Ruby block, a Rails partial, or a Proxy to another block.
250
+
251
+ ## Without a Definition
252
+
253
+ ```erb
254
+ <% blocks.define :my_block %>
255
+ ```
256
+
257
+ ```haml
258
+ - blocks.define :my_block
259
+ ```
260
+
261
+ ```ruby
262
+ # where builder is an instance
263
+ # of Blocks::Builder
264
+ builder.define :my_block
265
+ ```
266
+
267
+ Blocks do not need to have a definition provided. When they are rendered, no output is generated.
268
+
269
+ This, in itself, is not particularly useful, but can become more and more useful when block options and hooks and wrappers are combined.
270
+
271
+ ## With a Collection
272
+
273
+ ```erb
274
+ <% blocks.define :my_block,
275
+ collection: [1, 2, 3, 4] do |item| %>
276
+ <li>Item: <%= item %></li>
277
+ <% end %>
278
+ ```
279
+
280
+ ```haml
281
+ - blocks.define :my_block,
282
+ collection: [1, 2, 3, 4] do |item|
283
+ %li= "Item: #{item}"
284
+ ```
285
+
286
+ ```ruby
287
+ # where builder is an instance
288
+ # of Blocks::Builder
289
+ builder.define :my_block,
290
+ collection: [1, 2, 3, 4] do |item|
291
+ builder.content_tag :li,
292
+ "Item #{item}"
293
+ end
294
+ ```
295
+
296
+ A collection may be defined for a block, in which case, when that block is rendered, it will actually render the block multiple times, once for each item in the collection.
297
+
298
+ <aside class="warning">
299
+ When the block definition is a Ruby block, the block should be prepared to take each item from the collection as a parameter.
300
+ </aside>
301
+
302
+
303
+ ### With an Alias
304
+
305
+ ```erb
306
+ <% blocks.define :my_block,
307
+ collection: [1, 2, 3, 4],
308
+ as: :item,
309
+ partial: "my_partial" %>
310
+ ```
311
+
312
+ ```haml
313
+ - blocks.define :my_block,
314
+ collection: [1, 2, 3, 4],
315
+ as: :item,
316
+ partial: "my_partial"
317
+ ```
318
+
319
+ ```ruby
320
+ # where builder is an instance
321
+ # of Blocks::Builder
322
+ builder.define :my_block,
323
+ collection: [1, 2, 3, 4],
324
+ as: :item,
325
+ partial: "my_partial"
326
+ ```
327
+
328
+ Additionally, you can set an alias for each item in the collection as the collection is iterated over. This is done using the "as" option.
329
+
330
+ If the block being rendered is a partial, it will alias each item in the collection with the specified option (i.e. the value of the "as" option will become the name of the variable available in the partial being rendered and will contain each item in the collection being rendered). Additionally, "current_index" will also be a variable that can be accessed within the partial, and will correspond to the item's index in the collection.
331
+
332
+ If the block being rendered is not a partial, it will store the alias name as a key in an options hash that will be optionally passed to the block when it is rendered. Additionally, "current_index" will store the item's current index within the collection.
333
+
334
+ ### Without an Alias
335
+
336
+ When no alias is specified and the block being rendered is a partial, it will alias each item in the collection as "object" (i.e. "object" will become the name of the variable available in the partial being rendered and will contain each item in the collection being rendered).
337
+ Additionally, "current_index" will also be a variable that can be accessed within the partial, and will correspond to the item's index in the collection.
338
+
339
+ If the block being rendered is not a partial, it will store "object" as a key in an options hash that will be optionally passed to the block when it is rendered. Additionally, "current_index" will store the item's current index within the collection.
340
+
341
+ ## With Options
342
+
343
+ ```erb
344
+ <% blocks.define :my_block,
345
+ a: "First setting of a" %>
346
+ <% blocks.define :my_block,
347
+ a: "Second setting of a",
348
+ b: "First setting of b" %>
349
+ <% blocks.define :my_block,
350
+ a: "Third setting of a",
351
+ b: "Second setting setting of b",
352
+ c: "First setting of c" %>
353
+ ```
354
+
355
+ ```haml
356
+ - blocks.define :my_block,
357
+ a: "First setting of a"
358
+ - blocks.define :my_block,
359
+ a: "Second setting of a",
360
+ b: "First setting of b"
361
+ - blocks.define :my_block,
362
+ a: "Third setting of a",
363
+ b: "Second setting setting of b",
364
+ c: "First setting of c"
365
+ ```
366
+
367
+ ```ruby
368
+ # where builder is an instance
369
+ # of Blocks::Builder
370
+ builder.define :my_block,
371
+ a: "First setting of a"
372
+ builder.define :my_block,
373
+ a: "Second setting of a",
374
+ b: "First setting of b"
375
+ builder.define :my_block,
376
+ a: "Third setting of a",
377
+ b: "Second setting setting of b",
378
+ c: "First setting of c"
379
+ ```
380
+
381
+ > After running the above code, the options for :my_block will look like this:
382
+
383
+ ```JavaScript
384
+ {
385
+ a: "First setting of a",
386
+ b: "First setting of b",
387
+ c: "First setting of c"
388
+ }
389
+ ```
390
+
391
+ Blocks are maintaining a merged, mutable options hash. This set is mutated with repeated calls to "define".
392
+
393
+ When the same option key is used in successive "define" calls, the first call to define a key's value is given priority.
394
+
395
+ ### Indifferent Access
396
+
397
+ ```erb
398
+ <% blocks.define :my_block,
399
+ a: "First setting of a",
400
+ "b" => "First setting of b" %>
401
+ <% blocks.define :my_block,
402
+ "a" => "Second setting of a",
403
+ b: "Second setting of b" %>
404
+ ```
405
+
406
+ ```haml
407
+ - blocks.define :my_block,
408
+ a: "First setting of a",
409
+ "b" => "First setting of b"
410
+ - blocks.define :my_block,
411
+ "a" => "Second setting of a",
412
+ b: "Second setting of b"
413
+ ```
414
+
415
+ ```ruby
416
+ # where builder is an instance of
417
+ # Blocks::Builder
418
+ builder.define :my_block,
419
+ a: "First setting of a",
420
+ "b" => "First setting of b"
421
+ builder.define :my_block,
422
+ "a" => "Second setting of a",
423
+ b: "First setting of b"
424
+ ```
425
+
426
+ > After running the above code, the options for :my_block will look like this:
427
+
428
+ ```JavaScript
429
+ {
430
+ a: "First setting of a",
431
+ b: "First setting of b"
432
+ }
433
+ ```
434
+
435
+ Like the name of the block itself, the options hash does not care whether a symbol or a string is provided as a hash key; they are treated the same.
436
+
437
+ ### Deep Merging of Options
438
+
439
+ ```erb
440
+ <% blocks.define :my_block,
441
+ a: 1,
442
+ shared_key: {
443
+ a: "a1"
444
+ } %>
445
+ <% blocks.define :my_block,
446
+ b: 1,
447
+ shared_key: {
448
+ a: "a2",
449
+ b: "b1"
450
+ } %>
451
+ ```
452
+
453
+ ```haml
454
+ - blocks.define :my_block,
455
+ a: 1,
456
+ shared_key: { a: "a1" }
457
+ - blocks.define :my_block,
458
+ b: 1,
459
+ shared_key: { a: "a2",
460
+ b: "b1" }
461
+ ```
462
+
463
+ ```ruby
464
+ # where builder is an instance of
465
+ # Blocks::Builder
466
+ builder.define :my_block,
467
+ a: 1,
468
+ shared_key: {
469
+ a: "a1"
470
+ }
471
+ builder.define :my_block,
472
+ b: 1,
473
+ shared_key: {
474
+ a: "a2",
475
+ b: "b1"
476
+ }
477
+ ```
478
+
479
+ > After running the above code, the options for :my_block will look like this:
480
+
481
+ ```JavaScript
482
+ {
483
+ a: 1,
484
+ shared_key: {
485
+ a: "a1",
486
+ b: "b1"
487
+ },
488
+ b: 1
489
+ }
490
+ ```
491
+
492
+ When the same option key is used in successive "define" calls and the values for the duplicate key are both hashes, they are deep merged, giving precedence for duplicate nested keys to whatever key was defined first.
493
+
494
+ ### Runtime and Default Options
495
+
496
+ ```erb
497
+ <% blocks.define :my_block,
498
+ a: "standard",
499
+ b: "standard",
500
+ runtime: {
501
+ a: "runtime",
502
+ c: "runtime"
503
+ },
504
+ defaults: {
505
+ a: "default",
506
+ d: "default"
507
+ } %>
508
+ ```
509
+
510
+ ```haml
511
+ - blocks.define :my_block,
512
+ a: "standard",
513
+ b: "standard",
514
+ runtime: { a: "runtime",
515
+ c: "runtime" },
516
+ defaults: { a: "default",
517
+ d: "default" }
518
+ ```
519
+
520
+ ```ruby
521
+ # where builder is an instance of
522
+ # Blocks::Builder
523
+ builder.define :my_block,
524
+ a: "standard",
525
+ b: "standard",
526
+ runtime: {
527
+ a: "runtime",
528
+ c: "runtime"
529
+ },
530
+ defaults: {
531
+ a: "default",
532
+ d: "default"
533
+ }
534
+ ```
535
+
536
+ > After running the above code, the options for :my_block will look like this:
537
+
538
+ ```JavaScript
539
+ {
540
+ a: "runtime",
541
+ c: "runtime",
542
+ b: "standard",
543
+ d: "default"
544
+ }
545
+ ```
546
+
547
+ There are three levels of options: runtime, standard, and default. They are given merge precedence in that order.
548
+
549
+ Runtime options are specified as a nested hash with "runtime" as the key.
550
+
551
+ Default options are specified as a nested hash with "defaults" as the key.
552
+
553
+ All other keys in the hash are considered standard options.
554
+
555
+ ## With Parameters
556
+
557
+ ```erb
558
+ <% blocks.define :my_block,
559
+ a: 1 do |options| %>
560
+ My options are <%= options.inspect %>
561
+ <% end %>
562
+ ```
563
+
564
+ ```haml
565
+ - blocks.define :my_block,
566
+ a: 1 do |options|
567
+ My options are
568
+ = options.inspect
569
+ ```
570
+
571
+ ```ruby
572
+ # where builder is an instance of
573
+ # Blocks::Builder
574
+ builder.define :my_block,
575
+ a: 1 do |options|
576
+ "My options are #{options.inspect}"
577
+ end
578
+ ```
579
+ > If this block were rendered, the output would be:
580
+
581
+ ```
582
+ My options are { a: 1 }
583
+ ```
584
+
585
+ Every block that are defined with a Ruby block or a proxy to a Block that is defined with a Ruby block (or a proxy to a proxy to ... to a block that is defined with a Ruby block) can optionally receive the merged options as a parameter.
586
+
587
+ ## Without a Name
588
+
589
+ ```erb
590
+ See Ruby tab
591
+ ```
592
+
593
+ ```haml
594
+ See Ruby tab
595
+ ```
596
+
597
+ ```ruby
598
+ # where builder is an instance of
599
+ # Blocks::Builder
600
+ anonymous_block = builder.define do
601
+ "hello"
602
+ end
603
+
604
+ puts anonymous_block.name
605
+ # Outputs "anonymous_block_1"
606
+
607
+ puts anonymous_block.anonymous
608
+ # Outputs true
609
+ ```
610
+
611
+ Blocks may be defined without a name. When no block name is provided, an anonymous name will be generated.
612
+
613
+ <aside class="notice">
614
+ This is really only useful directly within the Ruby code or when extending the Blocks::Builder class.
615
+ </aside>