nestive_rendering 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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