nestive_rendering 1.0.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.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +274 -0
  4. data/lib/nestive_rendering/layout_helper.rb +262 -0
  5. data/lib/nestive_rendering/railtie.rb +11 -0
  6. data/lib/nestive_rendering/version.rb +3 -0
  7. data/lib/nestive_rendering.rb +6 -0
  8. data/spec/controllers/nestive_spec.rb +122 -0
  9. data/spec/internal/app/controllers/application_controller.rb +2 -0
  10. data/spec/internal/app/controllers/nestive_controller.rb +17 -0
  11. data/spec/internal/app/views/layouts/extend_one.html.erb +5 -0
  12. data/spec/internal/app/views/layouts/extend_two.html.erb +6 -0
  13. data/spec/internal/app/views/layouts/locals.html.erb +6 -0
  14. data/spec/internal/app/views/layouts/needs_options.html.erb +5 -0
  15. data/spec/internal/app/views/layouts/nestive.html.erb +15 -0
  16. data/spec/internal/app/views/nestive/_extended_features.html.erb +5 -0
  17. data/spec/internal/app/views/nestive/_extended_features_options.html.haml +3 -0
  18. data/spec/internal/app/views/nestive/_features.html.erb +4 -0
  19. data/spec/internal/app/views/nestive/_features_options.html.erb +9 -0
  20. data/spec/internal/app/views/nestive/append.html.erb +6 -0
  21. data/spec/internal/app/views/nestive/extended_one.html.erb +1 -0
  22. data/spec/internal/app/views/nestive/extended_partial.html.erb +1 -0
  23. data/spec/internal/app/views/nestive/extended_partial_options.html.haml +1 -0
  24. data/spec/internal/app/views/nestive/extended_three.html.erb +1 -0
  25. data/spec/internal/app/views/nestive/extended_two.html.erb +1 -0
  26. data/spec/internal/app/views/nestive/index.html.erb +1 -0
  27. data/spec/internal/app/views/nestive/locals.html.erb +1 -0
  28. data/spec/internal/app/views/nestive/prepend.html.erb +6 -0
  29. data/spec/internal/app/views/nestive/purge_multiple.html.erb +3 -0
  30. data/spec/internal/app/views/nestive/purge_single.html.erb +3 -0
  31. data/spec/internal/app/views/nestive/replace.html.erb +7 -0
  32. data/spec/internal/config/routes.rb +3 -0
  33. data/spec/internal/log/test.log +43 -0
  34. data/spec/spec_helper.rb +15 -0
  35. metadata +122 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 099ff10f13d97d6e59b72959b44445ebc9919d52
4
+ data.tar.gz: d3c8a453d1c30dfb6131f50ef7e51b7cf5735fde
5
+ SHA512:
6
+ metadata.gz: 463152fc1c35aac30f7d01b57495ce50315d5a0394056563c7799c31022353da41445a38bed1fc04e0489a3a8ce6755c6537691fa50bde160cecaefe0e5883b7
7
+ data.tar.gz: ed95fd4b280fecbd6721834bb2340f2c3db1dd8446a2b73fcd2fe464fdd0e69abefc4a15cc504f036b27388ec6b28e03c2a07bc2c37e1d5886f8349e7da89032
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Justin French
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,274 @@
1
+ # Nestive Rendering [![Build Status](https://travis-ci.org/mdeering/nestive_rendering.png)](https://travis-ci.org/mdeering/nestive_rendering) [![Code Climate](https://codeclimate.com/github/mdeering/nestive_rendering.png)](https://codeclimate.com/github/mdeering/nestive_rendering)
2
+ ## A Nested Inheritable Layouts and Partial Helpers for Rails
3
+
4
+ ## Forked from [Nestive](https://github.com/rwz/nestive) to add option passing and the ability to extend partials.
5
+
6
+ Nestive Rendering adds powerful layout, template and partial view helpers to your Rails app. It's similar
7
+ to the nested layout technique [already documented in the Rails
8
+ guides](http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts)
9
+ and found in many other nested layout plugins (a technique using `content_for`
10
+ and rendering the parent layout at the end of the child layout). There's a
11
+ bunch of problems with this technique, including:
12
+
13
+ * you can only *append* content to the content buffer with `content_for` (you
14
+ can't prepend to content, you can't replace it)
15
+ * when combined with this nested layout technique, `content_for` actually
16
+ *prepends* new content to the buffer, because each parent layout is rendered
17
+ *after* it's child
18
+
19
+ Nestive Rendering is *better* because it addresses these problems.
20
+
21
+ ## Just seven methods (so far)
22
+
23
+ ### Declaring an area of content with `area`:
24
+
25
+ The `area` helper is a lot like Rails' own `<%= yield :foo %>`, and is used in
26
+ layouts to define and render a chunk of content in your layout:
27
+
28
+ ```erb
29
+ <%= area :sidebar %>
30
+ ```
31
+
32
+ Unlike `yield`, `area` will allow your parent layouts to add content to the
33
+ area at the same time using either a String or a block:
34
+
35
+ ```erb
36
+ <%= area :sidebar, "Some Content Here" %>
37
+
38
+ <%= area :sidebar do %>
39
+ Some Content Here
40
+ <% end %>
41
+ ```
42
+
43
+ It's important to note that this isn't *default* content, it *is* the content
44
+ (unless a child changes it).
45
+
46
+ ### Appending content to an area with `append`:
47
+
48
+ The implementation details are quite different, but the `append` helper works
49
+ much like Rails' built-in `content_for`. It will work with either a String or
50
+ block, adding the new content onto the end of any content previously provided
51
+ by parent layouts:
52
+
53
+ ```erb
54
+ <%= extends :application do %>
55
+ <% append :sidebar, "More content." %>
56
+ <% append :sidebar do %>
57
+ More content.
58
+ <% end %>
59
+ <% end %>
60
+ ```
61
+
62
+ ### Prepending content to an area with `prepend`:
63
+
64
+ Exactly what you think it is. The reverse of `append` (duh), adding the new
65
+ content at the start of any content previously provided by parent layouts:
66
+
67
+ ``` erb
68
+ <%= extends :application do %>
69
+ <%= prepend :sidebar, "Content." %>
70
+ <%= prepend :sidebar do %>
71
+ Content.
72
+ <% end %>
73
+ <% end %>
74
+ ```
75
+
76
+ ### Replacing content with `replace`
77
+
78
+ You can also replace any content provided by parent layouts:
79
+
80
+ ``` erb
81
+ <%= extends :application do %>
82
+ <%= replace :sidebar, "New content." %>
83
+ <%= replace :sidebar do %>
84
+ New content.
85
+ <% end %>
86
+ <% end %>
87
+ ```
88
+
89
+ ### Removing content with `purge`
90
+
91
+ You can remove the content in the single or in multiple areas
92
+
93
+ ``` erb
94
+ <% purge :sidebar %>
95
+ <% purge :sidebar, :banner %>
96
+ ```
97
+
98
+ ... which is equal to:
99
+
100
+ ``` erb
101
+ <% replace :sidebar, nil %>
102
+ ```
103
+
104
+ ### Extending a layout in a child layout (or view) with `extends`
105
+
106
+ Any layout (or view) can declare that it wants to inherit from and extend a
107
+ parent layout, in this case we're extending
108
+ `app/views/layouts/application.html.erb`:
109
+
110
+ ``` erb
111
+ <%= extends :application do %>
112
+ ...
113
+ <% end %>
114
+ ```
115
+
116
+ You can nest many levels deep:
117
+
118
+ `app/views/layouts/application.html.erb`:
119
+
120
+ ``` erb
121
+ <!DOCTYPE html>
122
+ <html>
123
+ <head>
124
+ <%= area :head do %>
125
+ <title><%= area :title, 'Nestive' %></title>
126
+ <% end %>
127
+ </head>
128
+ <body>
129
+ <%= yield %>
130
+ </body>
131
+ </html>
132
+ ```
133
+
134
+ `app/views/layouts/with_sidebar.html.erb`:
135
+
136
+ ``` erb
137
+ <%= extends :application do %>
138
+ <div class="sidebar"><%= area(:sidebar) do %>
139
+ here goes sidebar
140
+ <% end %></div>
141
+ <%= yield -%>
142
+ <% end %>
143
+ ```
144
+
145
+ `app/views/layouts/blog_posts.html.erb`:
146
+
147
+ ``` erb
148
+ <%= extends :with_sidebar do %>
149
+ <% append :sidebar do %>
150
+ Blog archive:
151
+ <%= render_blog_archive %>
152
+ <% end %>
153
+
154
+ <% append :head do %>
155
+ <%= javascript_include_tag 'fancy_blog_archive_tag_cloud' %>
156
+ <% end %>
157
+
158
+ <%= yield %>
159
+ <% end %>
160
+ ```
161
+
162
+ ## The token blog example
163
+
164
+ Set-up a global layout defining some content areas.
165
+
166
+ `app/views/layouts/application.html.erb`:
167
+
168
+ ``` erb
169
+ <!DOCTYPE html>
170
+ <html>
171
+ <head>
172
+ <meta charset="utf-8">
173
+ <title><%= area :title, "JustinFrench.com" %></title>
174
+ <meta name="description" content="<%= area :description, "This is my website." %>">
175
+ <meta name="keywords" content="<%= area :keywords, "justin, french, ruby, design" %>">
176
+ </head>
177
+ <body>
178
+ <div id="wrapper">
179
+ <div id="content">
180
+ <%= area :content do %>
181
+ <p>Default content goes here.</p>
182
+ <% end %>
183
+ </div>
184
+ <div id="sidebar">
185
+ <%= area :sidebar do %>
186
+ <h2>About Me</h2>
187
+ <p>...</p>
188
+ <% end %>
189
+ </div>
190
+ </div>
191
+ <%= yield %>
192
+ </body>
193
+ </html>
194
+ ```
195
+
196
+ Next, we set-up a `blog` layout that extends `application`, replacing,
197
+ appending & prepending content to the areas we defined earlier.
198
+
199
+ `app/views/layouts/blog.html.erb`:
200
+
201
+ ``` erb
202
+ <%= extends :application do %>
203
+ <% replace :title, "My Blog – " %>
204
+ <% replace :description, "Justin French blogs here on Ruby, Rails, Design, Formtastic, etc" %>
205
+ <% prepend :keywords, "blog, weblog, design links, ruby links, formtastic release notes, " %>
206
+ <%= yield %>
207
+ <% end %>
208
+ ```
209
+
210
+ Now in our blog index view we can use `blog` layout and fill in the areas with
211
+ content specific to the index action.
212
+
213
+
214
+ `app/views/posts/index.html.erb`:
215
+
216
+ ``` erb
217
+ <% replace :content do %>
218
+ <h1>My Blog</h1>
219
+ <%= render @articles %>
220
+ <% end %>
221
+
222
+ <% append :sidebar do %>
223
+ <h2>Blog Roll</h2>
224
+ <%= render @links %>
225
+ <% end %>
226
+ ```
227
+
228
+ We also need to instruct the `PostsController` to use this `blog` layout:
229
+
230
+ `app/controllers/posts_controller.rb`:
231
+
232
+ ``` ruby
233
+ class PostsController < ApplicationController
234
+ layout 'blog'
235
+ end
236
+ ```
237
+
238
+ ### Extending a parital in a child partial (or view) with `extends_partial`
239
+
240
+ Any partial (or view) can declare that it wants to inherit from and extend a
241
+ parent partial.
242
+
243
+
244
+ ## Caching
245
+ Nestive works the same way `content_for` does and has the same caching
246
+ drawbacks. That means that nestive helpers are completely ignored when called
247
+ from within cached block. You probably don't want to use fragment caching
248
+ around dynamic nestive areas and have to be extra careful what and how you
249
+ cache to avoid unpleasant surprises.
250
+
251
+ ## Installation
252
+
253
+ * add `gem 'nestive', '~> 0.5'` to your Gemfile
254
+ * run `bundle`
255
+
256
+ ## Compatibility
257
+
258
+ Nestive should work properly with any Rails 3 and 4. Since version 0.5 only
259
+ Ruby 1.9.3 and newer are supported. For 1.8 compatibility use version 0.4.
260
+
261
+
262
+ *Nestive doesn't monkey patch or fiddle with any default behaviors in Rails.* Use it when you want to, don't when you don't.
263
+
264
+ ## You can help with...
265
+
266
+ * feedback
267
+ * reporting issues
268
+ * fixing issues with pull requests
269
+ * performance testing
270
+
271
+ ## Twitter
272
+
273
+ * [@rwz](https://twitter.com/rwz) — current maintainer
274
+ * [@justinfrench](http://twitter.com/justinfrench) — author
@@ -0,0 +1,262 @@
1
+ module NestiveRendering
2
+
3
+ # The Nestive Rendering LayoutHelper provides a handful of helper methods for use in your layouts and views.
4
+ #
5
+ # See the documentation for each individual method for detailed information, but at a high level,
6
+ # your parent layouts define `area`s of content. You can define an area and optionally add content
7
+ # to it at the same time using either a String, or a block:
8
+ #
9
+ # # app/views/layouts/global.html.erb
10
+ # <html>
11
+ # <head>
12
+ # <title><%= area :title, "MySite.com" %></title>
13
+ # </head>
14
+ # <body>
15
+ # <div id="content">
16
+ # <%= area :content %>
17
+ # </div>
18
+ # <div id="sidebar">
19
+ # <%= area :sidebar do %>
20
+ # <h2>About MySite.com</h2>
21
+ # <p>...</p>
22
+ # <% end %>
23
+ # </div>
24
+ # </body>
25
+ # </html>
26
+ #
27
+ # Your child layouts (or views) inherit and modify the parent by wrapping in an `extends` block
28
+ # helper. You can then either `append`, `prepend` or `replace` the content that has previously
29
+ # been assigned to each area by parent layouts.
30
+ #
31
+ # The `append`, `prepend` or `replace` helpers are *similar* to Rails' own `content_for`, which
32
+ # accepts content for the named area with either a String or with a block). They're different to
33
+ # `content_for` because they're only used modify the content assigned to the area, not retrieve it:
34
+ #
35
+ # # app/views/layouts/admin.html.erb
36
+ # <%= extends :global do %>
37
+ # <% prepend :title, "Admin :: " %>
38
+ # <% replace :sidebar do %>
39
+ # <h2>Quick Links</h2>
40
+ # <ul>
41
+ # <li>...</li>
42
+ # </ul>
43
+ # <% end %>
44
+ # <% end %>
45
+ #
46
+ # # app/views/admin/posts/index.html.erb
47
+ # <%= extends :admin do %>
48
+ # <% prepend :title, "Posts ::" %>
49
+ # <% replace :content do %>
50
+ # Normal view stuff goes here.
51
+ # <% end %>
52
+ # <% end %>
53
+ module LayoutHelper
54
+
55
+ # Declares that the current layour (or view) is inheriting from and extending another layout.
56
+ #
57
+ # @param [String] layout
58
+ # The base name of the file in `layouts/` that you wish to extend (eg `application` for `layouts/application.html.erb`)
59
+ # @param [Hash] options
60
+ # Any options such as locals that you want to pass through to the layout rendering
61
+ #
62
+ # @example Extending the `application` layout to create an `admin` layout
63
+ #
64
+ # # app/views/layouts/admin.html.erb
65
+ # <%= extends :application do %>
66
+ # ...
67
+ # <% end %>
68
+ #
69
+ # @example Extending the `admin` layout in a view (you'll need to render the view with `layout: nil`)
70
+ #
71
+ # # app/controllers/admin/posts_controller.rb
72
+ # class Admin::PostsController < ApplicationController
73
+ # # You can disable Rails' layout rendering for all actions
74
+ # layout nil
75
+ #
76
+ # # Or disable Rails' layout rendering per-controller
77
+ # def index
78
+ # render layout: nil
79
+ # end
80
+ # end
81
+ #
82
+ # # app/views/admin/posts/index.html.erb
83
+ # <%= extends :admin do %>
84
+ # ...
85
+ # <% end %>
86
+ def extends(layout, options = {}, &block)
87
+ # Make sure it's a string
88
+ layout = layout.to_s
89
+
90
+ # If there's no directory component, presume a plain layout name
91
+ layout = "layouts/#{layout}" unless layout.include?('/')
92
+
93
+ # Capture the content to be placed inside the extended layout
94
+ @view_flow.get(:layout).replace capture(&block)
95
+
96
+ render options.merge(file: layout)
97
+ end
98
+
99
+ # Works exactly the same as extends but is targeted at extending partials not
100
+ # layouts.
101
+ #
102
+ # @param [String] partial
103
+ # The base name of the partial that you wish to extend (eg `header` for `application/_header.html.erb`)
104
+ # @param [Hash] options
105
+ # Any options such as the object or locals that you want to pass through to the parital rendering
106
+ #
107
+ def extends_partial(partial, options = {}, &block)
108
+ # Make sure it's a string
109
+ partial = partial.to_s
110
+ block.call if block_given?
111
+ render options.merge(partial: partial)
112
+ end
113
+
114
+ # Defines an area of content in your layout that can be modified or replaced by child layouts
115
+ # that extend it. You can optionally add content to an area using either a String, or a block.
116
+ #
117
+ # Areas are declared in a parent layout and modified by a child layout, but since Nestive Rendering
118
+ # allows for multiple levels of inheritance, a child layout can also declare an area for it's
119
+ # children to modify.
120
+ #
121
+ # @example Define an area without adding content to it:
122
+ # <%= area :sidebar %>
123
+ #
124
+ # @example Define an area and add a String of content to it:
125
+ # <%= area :sidebar, "Some content." %>
126
+ #
127
+ # @example Define an area and add content to it with a block:
128
+ # <%= area :sidebar do %>
129
+ # Some content.
130
+ # <% end %>
131
+ #
132
+ # @example Define an area in a child layout:
133
+ # <%= extends :global do %>
134
+ # <%= area :sidebar do %>
135
+ # Some content.
136
+ # <% end %>
137
+ # <% end %>
138
+ #
139
+ # @param [Symbol] name
140
+ # A unique name to identify this area of content.
141
+ #
142
+ # @param [String] content
143
+ # An optional String of content to add to the area as you declare it.
144
+ def area(name, content=nil, &block)
145
+ content = capture(&block) if block_given?
146
+ append name, content
147
+ render_area name
148
+ end
149
+
150
+ # Appends content to an area previously defined or modified in parent layout(s). You can provide
151
+ # the content using either a String, or a block.
152
+ #
153
+ # @example Appending content with a String
154
+ # <% append :sidebar, "Some content." %>
155
+ #
156
+ # @example Appending content with a block:
157
+ # <% append :sidebar do %>
158
+ # Some content.
159
+ # <% end %>
160
+ #
161
+ # @param [Symbol] name
162
+ # A name to identify the area of content you wish to append to
163
+ #
164
+ # @param [String] content
165
+ # Optionally provide a String of content, instead of a block. A block will take precedence.
166
+ def append(name, content=nil, &block)
167
+ content = capture(&block) if block_given?
168
+ add_instruction_to_area name, :push, content
169
+ end
170
+
171
+ # Prepends content to an area previously declared or modified in parent layout(s). You can
172
+ # provide the content using either a String, or a block.
173
+ #
174
+ # @example Prepending content with a String
175
+ # <% prepend :sidebar, "Some content." %>
176
+ #
177
+ # @example Prepending content with a block:
178
+ # <% prepend :sidebar do %>
179
+ # Some content.
180
+ # <% end %>
181
+ #
182
+ # @param [Symbol] name
183
+ # A name to identify the area of content you wish to prepend to
184
+ #
185
+ # @param [String] content
186
+ # Optionally provide a String of content, instead of a block. A block will take precedence.
187
+ def prepend(name, content=nil, &block)
188
+ content = capture(&block) if block_given?
189
+ add_instruction_to_area name, :unshift, content
190
+ end
191
+
192
+ # Replaces the content of an area previously declared or modified in parent layout(s). You can
193
+ # provide the content using either a String, or a block.
194
+ #
195
+ # @example Replacing content with a String
196
+ # <% replace :sidebar, "New content." %>
197
+ #
198
+ # @example Replacing content with a block:
199
+ # <% replace :sidebar do %>
200
+ # New content.
201
+ # <% end %>
202
+ #
203
+ # @param [Symbol] name
204
+ # A name to identify the area of content you wish to replace
205
+ #
206
+ # @param [String] content
207
+ # Optionally provide a String of content, instead of a block. A block will take precedence.
208
+ def replace(name, content=nil, &block)
209
+ content = capture(&block) if block_given?
210
+ add_instruction_to_area name, :replace, [content]
211
+ end
212
+
213
+ # Purge the content of an area previously declared or modified in parent layout(s).
214
+ #
215
+ # @example Purge content
216
+ # <% purge :sidebar %>
217
+ #
218
+ # @param names
219
+ # A list of area names to purge
220
+ def purge(*names)
221
+ names.each{ |name| replace(name, nil)}
222
+ end
223
+
224
+ private
225
+
226
+ # We record the instructions (declaring, appending, prepending and replacing) for an area of
227
+ # content into an array that we can later retrieve and replay. Instructions are stored in an
228
+ # instance variable Hash `@_area_for`, with each key representing an area name, and each value
229
+ # an Array of instructions. Each instruction is a two element array containing a instruction
230
+ # method (eg `:push`, `:unshift`, `:replace`) and a value (content String).
231
+ #
232
+ # @_area_for[:sidebar] # => [ [:push,"World"], [:unshift,"Hello"] ]
233
+ #
234
+ # Due to the way we extend layouts (render the parent layout after the child), the instructions
235
+ # are captured in reverse order. `render_area` reversed them and plays them back at rendering
236
+ # time.
237
+ #
238
+ # @example
239
+ # add_instruction_to_area(:sidebar, :push, "More content.")
240
+ def add_instruction_to_area(name, instruction, value)
241
+ @_area_for ||= {}
242
+ @_area_for[name] ||= []
243
+ @_area_for[name] << [instruction, value]
244
+ nil
245
+ end
246
+
247
+ # Take the instructions we've gathered for the area and replay them one after the other on
248
+ # an empty array. These instructions will push, unshift or replace items into our output array,
249
+ # which we then join and mark as html_safe.
250
+ #
251
+ # These instructions are reversed and replayed when we render the block (rather than as they
252
+ # happen) due to the way they are gathered by the layout extension process (in reverse).
253
+ def render_area(name)
254
+ [].tap do |output|
255
+ @_area_for.fetch(name, []).reverse_each do |method_name, content|
256
+ output.public_send method_name, content
257
+ end
258
+ end.join.html_safe
259
+ end
260
+
261
+ end
262
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module NestiveRendering
4
+ class Railtie < Rails::Railtie
5
+ initializer 'nestive_rendering.initialize' do
6
+ ActiveSupport.on_load(:action_view) do
7
+ include NestiveRendering::LayoutHelper
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module NestiveRendering
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,6 @@
1
+ require 'nestive_rendering/version'
2
+ require 'nestive_rendering/layout_helper'
3
+ require 'nestive_rendering/railtie'
4
+
5
+ module NestiveRendering
6
+ end
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+
3
+ describe NestiveController do
4
+ render_views
5
+
6
+ context '#area' do
7
+ it 'is empty by default' do
8
+ get :index
9
+ assert_select '#empty-area', ''
10
+ end
11
+
12
+ it 'shows initial value if any' do
13
+ get :index
14
+ assert_select 'title', 'Nestive'
15
+ end
16
+
17
+ it 'can accept blocks as initial value' do
18
+ get :index
19
+ assert_select '#some-area', 'Some content'
20
+ end
21
+ end
22
+
23
+ context '#append' do
24
+ it 'appends content to area as a string' do
25
+ get :append
26
+ assert_select 'title', 'Nestive is awesome'
27
+ end
28
+
29
+ it 'appends content to area as a block' do
30
+ get :append
31
+ assert_select '#some-area', "Some content\n Another content"
32
+ end
33
+ end
34
+
35
+ context '#prepend' do
36
+ it 'prepends content to area as a string' do
37
+ get :prepend
38
+ assert_select 'title', 'Awesome Nestive'
39
+ end
40
+
41
+ it 'prepends content to area as a block' do
42
+ get :prepend
43
+ assert_select '#some-area', "Prepended\n Some content"
44
+ end
45
+ end
46
+
47
+ context '#replace' do
48
+ it 'replaces area content with string' do
49
+ get :replace
50
+ assert_select 'title', 'Lolwut'
51
+ end
52
+
53
+ it 'replaces area content with block' do
54
+ get :replace
55
+ assert_select '#some-area', 'replaced'
56
+ end
57
+ end
58
+
59
+ context '#purge' do
60
+ it 'purge single area content' do
61
+ get :purge_single
62
+ assert_select 'title'
63
+ end
64
+
65
+ it 'purge few areas content' do
66
+ get :purge_multiple
67
+ assert_select 'title'
68
+ assert_select '#some-area'
69
+ end
70
+ end
71
+
72
+ context '#extends' do
73
+ it 'extends layouts' do
74
+ get :extended_one
75
+ assert_select 'p', 'extended: one'
76
+ assert_select 'title', 'extended: one'
77
+ assert_select 'h2', 'extended: one'
78
+ end
79
+
80
+ it 'can extend already extended layouts' do
81
+ get :extended_two
82
+ assert_select 'p', 'extended: two'
83
+ assert_select 'title', 'extended: one'
84
+ assert_select '#some-area', 'extended: two'
85
+ assert_select 'h2', 'extended: one'
86
+ end
87
+
88
+ it 'extends empty layout' do
89
+ get :extended_three
90
+ end
91
+ end
92
+
93
+ context '#locals' do
94
+ it 'allows for options to be passed through to the file render' do
95
+ get :locals
96
+ assert_select 'title', 'Passed in as a local'
97
+ assert_select '#some-area', 'locals: title'
98
+ end
99
+ end
100
+
101
+ context '#extends_partial' do
102
+ it 'nestive works great with partials also!' do
103
+ get :extended_partial
104
+ assert_select 'h1', 'Features'
105
+ assert_select '#basic-features', 'Basic Features'
106
+ assert_select '#extended-features', 'Extended Features'
107
+ end
108
+
109
+ it 'partials are a lot more fun with options' do
110
+ get :extended_partial_options
111
+ assert_select 'h1', 'Features'
112
+ assert_select '#basic-feature-1', 'Basic Features 1'
113
+ assert_select '#basic-feature-2', 'Basic Features 2'
114
+ assert_select '#extended-features', 'Extended Features'
115
+ end
116
+
117
+ it 'should only render the extensions on the partial a single time!' do
118
+ get :extended_partial_options
119
+ assert_select '.feature', 3
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::Base
2
+ end
@@ -0,0 +1,17 @@
1
+ class NestiveController < ApplicationController
2
+ def extended_one
3
+ render layout: 'extend_one'
4
+ end
5
+
6
+ def extended_two
7
+ render layout: 'extend_two'
8
+ end
9
+
10
+ def extended_three
11
+ render layout: 'extend_one'
12
+ end
13
+
14
+ def locals
15
+ render layout: 'locals'
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ <%= extends :nestive do %>
2
+ <% replace :title, 'extended: one' %>
3
+ <h2>extended: one</h2>
4
+ <%= yield %>
5
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%= extends :extend_one do %>
2
+ <%= replace :some_area do %>
3
+ extended: two
4
+ <% end %>
5
+ <%= yield %>
6
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%= extends :needs_options, locals: { title: 'Passed in as a local' } do %>
2
+ <%= replace :some_area do %>
3
+ locals: title
4
+ <% end %>
5
+ <%= yield %>
6
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <%= extends :nestive do %>
2
+ <% replace :title, title %>
3
+ <h2>options: pass throuth</h2>
4
+ <%= yield %>
5
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= area :title, 'Nestive' %></title>
5
+ </head>
6
+ <body>
7
+ <%= yield %>
8
+ <div id="some-area">
9
+ <%= area :some_area do -%>
10
+ Some content
11
+ <%- end -%>
12
+ </div>
13
+ <div id="empty-area"><%= area :empty_area %></div>
14
+ </body>
15
+ </html>
@@ -0,0 +1,5 @@
1
+ <%= extends_partial 'features' do %>
2
+ <%= append :features_list do %>
3
+ <div id='extended-features'>Extended Features</div>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,3 @@
1
+ = extends_partial 'features_options', as: :features, object: [1, 2] do
2
+ = append :features_list do
3
+ #extended-features.feature Extended Features
@@ -0,0 +1,4 @@
1
+ <h1>Features</h1>
2
+ <%= area :features_list do %>
3
+ <div id='basic-features'>Basic Features</div>
4
+ <% end %>
@@ -0,0 +1,9 @@
1
+ <h1>Features</h1>
2
+ <%= area :features_list do %>
3
+ <%- features.each do |feature| %>
4
+ <div class='feature' id='basic-feature-<%= feature %>'>Basic Features <%= feature %></div>
5
+ <%- end %>
6
+ <% end %>
7
+ <%= area :features_summary do %>
8
+ <p>Here is a summary or something like that...</p>
9
+ <%- end %>
@@ -0,0 +1,6 @@
1
+ <h1>here we'll be appending to areas</h1>
2
+
3
+ <% append :title, ' is awesome' %>
4
+ <% append :some_area do %>
5
+ Another content
6
+ <% end %>
@@ -0,0 +1 @@
1
+ <p>extended: one</p>
@@ -0,0 +1 @@
1
+ <%= render 'extended_features' %>
@@ -0,0 +1 @@
1
+ = render 'extended_features_options'
@@ -0,0 +1 @@
1
+ <% append :title, 'lol' %>
@@ -0,0 +1 @@
1
+ <p>extended: two</p>
@@ -0,0 +1 @@
1
+ <h1>Hello World</h1>
@@ -0,0 +1 @@
1
+ <h1>Locals</h1>
@@ -0,0 +1,6 @@
1
+ <h1>here we'll be prepending stuff to areas</h1>
2
+
3
+ <% prepend :title, 'Awesome ' %>
4
+ <% prepend :some_area do %>
5
+ Prepended
6
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <h1>multiple purge area</h1>
2
+
3
+ <% purge :title, :some_area %>
@@ -0,0 +1,3 @@
1
+ <h1>single purge area</h1>
2
+
3
+ <% purge :title %>
@@ -0,0 +1,7 @@
1
+ <h1>replacing areas</h1>
2
+
3
+ <% replace :title, 'Lolwut' %>
4
+
5
+ <%= replace :some_area do %>
6
+ replaced
7
+ <% end %>
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ get ':controller/:action'
3
+ end
@@ -0,0 +1,43 @@
1
+ Processing by NestiveController#index as HTML
2
+ Rendered nestive/index.html.erb within layouts/nestive (0.6ms)
3
+ Completed 200 OK in 3.6ms (Views: 3.5ms)
4
+ Processing by NestiveController#index as HTML
5
+ Completed 200 OK in 0.3ms (Views: 0.2ms)
6
+ Processing by NestiveController#index as HTML
7
+ Completed 200 OK in 0.2ms (Views: 0.2ms)
8
+ Processing by NestiveController#append as HTML
9
+ Completed 200 OK in 0.8ms (Views: 0.7ms)
10
+ Processing by NestiveController#append as HTML
11
+ Completed 200 OK in 0.3ms (Views: 0.2ms)
12
+ Processing by NestiveController#prepend as HTML
13
+ Completed 200 OK in 0.7ms (Views: 0.6ms)
14
+ Processing by NestiveController#prepend as HTML
15
+ Completed 200 OK in 0.2ms (Views: 0.2ms)
16
+ Processing by NestiveController#replace as HTML
17
+ Completed 200 OK in 0.8ms (Views: 0.7ms)
18
+ Processing by NestiveController#replace as HTML
19
+ Completed 200 OK in 0.2ms (Views: 0.2ms)
20
+ Processing by NestiveController#purge_single as HTML
21
+ Completed 200 OK in 0.7ms (Views: 0.6ms)
22
+ Processing by NestiveController#purge_multiple as HTML
23
+ Completed 200 OK in 0.9ms (Views: 0.7ms)
24
+ Processing by NestiveController#extended_one as HTML
25
+ Completed 200 OK in 1.2ms (Views: 1.1ms)
26
+ Processing by NestiveController#extended_two as HTML
27
+ Completed 200 OK in 1.2ms (Views: 1.1ms)
28
+ Processing by NestiveController#extended_three as HTML
29
+ Completed 200 OK in 1.1ms (Views: 0.9ms)
30
+ Processing by NestiveController#locals as HTML
31
+ Completed 200 OK in 1.7ms (Views: 1.6ms)
32
+ Processing by NestiveController#extended_partial as HTML
33
+ Rendered nestive/_features.html.erb (0.3ms)
34
+ Rendered nestive/_extended_features.html.erb (1.0ms)
35
+ Completed 200 OK in 3.1ms (Views: 3.0ms)
36
+ Processing by NestiveController#extended_partial_options as HTML
37
+ Rendered nestive/_features_options.html.erb (0.4ms)
38
+ Rendered nestive/_extended_features_options.html.haml (1.5ms)
39
+ Completed 200 OK in 3.0ms (Views: 2.9ms)
40
+ Processing by NestiveController#extended_partial_options as HTML
41
+ Rendered nestive/_features_options.html.erb (0.1ms)
42
+ Rendered nestive/_extended_features_options.html.haml (0.3ms)
43
+ Completed 200 OK in 0.7ms (Views: 0.7ms)
@@ -0,0 +1,15 @@
1
+ require 'bundler'
2
+
3
+ Bundler.setup
4
+
5
+ require 'rails'
6
+ require 'combustion'
7
+ require 'nestive_rendering'
8
+
9
+ Combustion.initialize! :action_controller
10
+
11
+ require 'rspec/rails'
12
+
13
+ RSpec.configure do |config|
14
+ config.infer_spec_type_from_file_location!
15
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nestive_rendering
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Justin French
8
+ - Pavel Pravosud
9
+ - Michael Deering
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-12-08 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 3.0.0
29
+ description: A Rails gem for awesome nested templates, layouts and paritals
30
+ email:
31
+ - justin@indent.com.au
32
+ - pavel@pravosud.com
33
+ - mdeering@mdeering.com
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - MIT-LICENSE
39
+ - README.md
40
+ - lib/nestive_rendering.rb
41
+ - lib/nestive_rendering/layout_helper.rb
42
+ - lib/nestive_rendering/railtie.rb
43
+ - lib/nestive_rendering/version.rb
44
+ - spec/controllers/nestive_spec.rb
45
+ - spec/internal/app/controllers/application_controller.rb
46
+ - spec/internal/app/controllers/nestive_controller.rb
47
+ - spec/internal/app/views/layouts/extend_one.html.erb
48
+ - spec/internal/app/views/layouts/extend_two.html.erb
49
+ - spec/internal/app/views/layouts/locals.html.erb
50
+ - spec/internal/app/views/layouts/needs_options.html.erb
51
+ - spec/internal/app/views/layouts/nestive.html.erb
52
+ - spec/internal/app/views/nestive/_extended_features.html.erb
53
+ - spec/internal/app/views/nestive/_extended_features_options.html.haml
54
+ - spec/internal/app/views/nestive/_features.html.erb
55
+ - spec/internal/app/views/nestive/_features_options.html.erb
56
+ - spec/internal/app/views/nestive/append.html.erb
57
+ - spec/internal/app/views/nestive/extended_one.html.erb
58
+ - spec/internal/app/views/nestive/extended_partial.html.erb
59
+ - spec/internal/app/views/nestive/extended_partial_options.html.haml
60
+ - spec/internal/app/views/nestive/extended_three.html.erb
61
+ - spec/internal/app/views/nestive/extended_two.html.erb
62
+ - spec/internal/app/views/nestive/index.html.erb
63
+ - spec/internal/app/views/nestive/locals.html.erb
64
+ - spec/internal/app/views/nestive/prepend.html.erb
65
+ - spec/internal/app/views/nestive/purge_multiple.html.erb
66
+ - spec/internal/app/views/nestive/purge_single.html.erb
67
+ - spec/internal/app/views/nestive/replace.html.erb
68
+ - spec/internal/config/routes.rb
69
+ - spec/internal/log/test.log
70
+ - spec/spec_helper.rb
71
+ homepage: https://github.com/mdeering/nestive_rendering
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.9.3
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.4.2
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: A Rails gem for awesome nested templates, layouts and paritals
95
+ test_files:
96
+ - spec/spec_helper.rb
97
+ - spec/controllers/nestive_spec.rb
98
+ - spec/internal/config/routes.rb
99
+ - spec/internal/app/controllers/nestive_controller.rb
100
+ - spec/internal/app/controllers/application_controller.rb
101
+ - spec/internal/app/views/nestive/_features.html.erb
102
+ - spec/internal/app/views/nestive/extended_partial_options.html.haml
103
+ - spec/internal/app/views/nestive/replace.html.erb
104
+ - spec/internal/app/views/nestive/extended_one.html.erb
105
+ - spec/internal/app/views/nestive/_features_options.html.erb
106
+ - spec/internal/app/views/nestive/extended_partial.html.erb
107
+ - spec/internal/app/views/nestive/extended_three.html.erb
108
+ - spec/internal/app/views/nestive/_extended_features_options.html.haml
109
+ - spec/internal/app/views/nestive/prepend.html.erb
110
+ - spec/internal/app/views/nestive/index.html.erb
111
+ - spec/internal/app/views/nestive/purge_single.html.erb
112
+ - spec/internal/app/views/nestive/locals.html.erb
113
+ - spec/internal/app/views/nestive/purge_multiple.html.erb
114
+ - spec/internal/app/views/nestive/_extended_features.html.erb
115
+ - spec/internal/app/views/nestive/extended_two.html.erb
116
+ - spec/internal/app/views/nestive/append.html.erb
117
+ - spec/internal/app/views/layouts/nestive.html.erb
118
+ - spec/internal/app/views/layouts/needs_options.html.erb
119
+ - spec/internal/app/views/layouts/locals.html.erb
120
+ - spec/internal/app/views/layouts/extend_one.html.erb
121
+ - spec/internal/app/views/layouts/extend_two.html.erb
122
+ - spec/internal/log/test.log