nestive-rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b4a82114bbbc89e6e3b29c18629748cde19b554a0c42391e58c0230c0888381b
4
+ data.tar.gz: 309726bde20f1a3aa14dd14df75bbea17a31b6bb9fb3403041655d456f4f6406
5
+ SHA512:
6
+ metadata.gz: 52fc007847a4b51691d07120b18d4e97843beb4118a554071dca4a034b2c2f4059cb3a737ffc84d4f4ee2c2a43aa932135b2e4c27e319511d9e55dc12a4a8acb
7
+ data.tar.gz: ddc33bfb5e9cc66631fd967170f1009cd89ada2060529cf52270244fc3f099d96448f92f2d6ec6dc13c254a545991c8a1c00954a492f3c2a171f1d68f155012b
@@ -0,0 +1,14 @@
1
+ ### Expected behavior
2
+ Tell us what should happen
3
+
4
+ ### Actual behavior
5
+ Tell us what happens instead
6
+
7
+ ### Steps to reproduce
8
+ Show a way to reproduce
9
+
10
+ ### System configuration
11
+
12
+ **Ruby version**:
13
+
14
+ **Rails version**:
@@ -0,0 +1,21 @@
1
+ ### Summary
2
+
3
+ Provide a general description of the code changes in your pull
4
+ request... were there any bugs you had fixed? If so, mention them. If
5
+ these bugs have open GitHub issues, be sure to tag them here as well,
6
+ to keep the conversation linked together.
7
+
8
+ ### Other Information
9
+
10
+ If there's anything else that's important and relevant to your pull
11
+ request, mention that information here. This could include
12
+ benchmarks, or other information.
13
+
14
+ If you are updating any of the CHANGELOG files or are asked to update the
15
+ CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file.
16
+
17
+ Finally, if your pull request affects documentation or any non-code
18
+ changes, guidelines for those changes are [available
19
+ here](https://github.com/jonhue/nestive-rails/blob/master/CONTRIBUTING.md)
20
+
21
+ Thanks for contributing to `nestive-rails`!
@@ -0,0 +1,8 @@
1
+ test/debug.log
2
+ coverage
3
+ rdoc
4
+ memory
5
+ *.gem
6
+ .rvmrc
7
+ Gemfile.lock
8
+ log
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.3
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ### master
4
+
5
+ * nothing yet
6
+
7
+ ### 1.0.0 - 2017-12-19
8
+
9
+ * initial release
@@ -0,0 +1,46 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to creating a positive environment include:
10
+
11
+ * Using welcoming and inclusive language
12
+ * Being respectful of differing viewpoints and experiences
13
+ * Gracefully accepting constructive criticism
14
+ * Focusing on what is best for the community
15
+ * Showing empathy towards other community members
16
+
17
+ Examples of unacceptable behavior by participants include:
18
+
19
+ * The use of sexualized language or imagery and unwelcome sexual attention or advances
20
+ * Trolling, insulting/derogatory comments, and personal or political attacks
21
+ * Public or private harassment
22
+ * Publishing others' private information, such as a physical or electronic address, without explicit permission
23
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
24
+
25
+ ## Our Responsibilities
26
+
27
+ Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28
+
29
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at help@slooob.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38
+
39
+ Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40
+
41
+ ## Attribution
42
+
43
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44
+
45
+ [homepage]: http://contributor-covenant.org
46
+ [version]: http://contributor-covenant.org/version/1/4/
@@ -0,0 +1 @@
1
+ # Contributing
@@ -0,0 +1,3 @@
1
+ # Deprecations
2
+
3
+ No deprecations
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ git_source :github do |repo_name|
4
+ "https://github.com/#{repo_name}"
5
+ end
6
+
7
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Jonas Hübotter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,308 @@
1
+ # nestive-rails
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/nestive-rails.svg)](https://badge.fury.io/rb/nestive-rails) <img src="https://travis-ci.org/jonhue/nestive-rails.svg?branch=master" />
4
+
5
+ This gem is a continuation for Rails 5 of the [nestive](https://github.com/rwz/nestive) gem originally created by Justin French and Pavel Pravosud.
6
+
7
+ nestive-rails adds powerful layout and view helpers to your Rails app. It's similar to the nested layout technique [already documented in the Rails guides](http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts) and found in many other nested layout plugins (a technique using `content_for` and rendering the parent layout at the end of the child layout). There's a bunch of problems with this technique, including:
8
+
9
+ * you can only *append* content to the content buffer with `content_for` (you can't prepend to content, you can't replace it)
10
+ * when combined with this nested layout technique, `content_for` actually *prepends* new content to the buffer, because each parent layout is rendered *after* it's child
11
+
12
+ nestive-rails is *better* because it addresses these problems.
13
+
14
+ ---
15
+
16
+ ## Table of Contents
17
+
18
+ * [Installation](#installation)
19
+ * [Usage](#usage)
20
+ * [Caching](#caching)
21
+ * [To Do](#to-do)
22
+ * [Contributing](#contributing)
23
+ * [Contributors](#contributors)
24
+ * [License](#license)
25
+
26
+ ---
27
+
28
+ ## Installation
29
+
30
+ `nestive-rails` works with Rails 5.0 onwards. You can add it to your `Gemfile` with:
31
+
32
+ ```ruby
33
+ gem 'nestive-rails'
34
+ ```
35
+
36
+ And then execute:
37
+
38
+ $ bundle
39
+
40
+ Or install it yourself as:
41
+
42
+ $ gem install nestive-rails
43
+
44
+ If you always want to be up to date fetch the latest from GitHub in your `Gemfile`:
45
+
46
+ ```ruby
47
+ gem 'nestive-rails', github: 'jonhue/nestive-rails'
48
+ ```
49
+
50
+ ## Usage
51
+
52
+ ### Declaring an area of content with `area`:
53
+
54
+ The `area` helper is a lot like Rails' own `<%= yield :foo %>`, and is used in layouts to define and render a chunk of content in your layout:
55
+
56
+ ```erb
57
+ <%= area :sidebar %>
58
+ ```
59
+
60
+ Unlike `yield`, `area` will allow your parent layouts to add content to the area at the same time using either a String or a block:
61
+
62
+ ```erb
63
+ <%= area :sidebar, "Some Content Here" %>
64
+
65
+ <%= area :sidebar do %>
66
+ Some Content Here
67
+ <% end %>
68
+ ```
69
+
70
+ It's important to note that this isn't *default* content, it *is* the content (unless a child changes it).
71
+
72
+ ### Appending content to an area with `append`:
73
+
74
+ The implementation details are quite different, but the `append` helper works much like Rails' built-in `content_for`. It will work with either a String or block, adding the new content onto the end of any content previously provided by parent layouts:
75
+
76
+ ```erb
77
+ <%= extends :application do %>
78
+ <% append :sidebar, "More content." %>
79
+ <% append :sidebar do %>
80
+ More content.
81
+ <% end %>
82
+ <% end %>
83
+ ```
84
+
85
+ ### Prepending content to an area with `prepend`:
86
+
87
+ Exactly what you think it is. The reverse of `append` (duh), adding the new content at the start of any content previously provided by parent layouts:
88
+
89
+ ``` erb
90
+ <%= extends :application do %>
91
+ <%= prepend :sidebar, "Content." %>
92
+ <%= prepend :sidebar do %>
93
+ Content.
94
+ <% end %>
95
+ <% end %>
96
+ ```
97
+
98
+ ### Replacing content with `replace`
99
+
100
+ You can also replace any content provided by parent layouts:
101
+
102
+ ``` erb
103
+ <%= extends :application do %>
104
+ <%= replace :sidebar, "New content." %>
105
+ <%= replace :sidebar do %>
106
+ New content.
107
+ <% end %>
108
+ <% end %>
109
+ ```
110
+
111
+ ### Removing content with `purge`
112
+
113
+ You can remove the content in the single or in multiple areas
114
+
115
+ ``` erb
116
+ <% purge :sidebar %>
117
+ <% purge :sidebar, :banner %>
118
+ ```
119
+
120
+ ... which is equal to:
121
+
122
+ ``` erb
123
+ <% replace :sidebar, nil %>
124
+ ```
125
+
126
+ ### Extending a layout in a child layout (or view) with `extends`
127
+
128
+ Any layout (or view) can declare that it wants to inherit from and extend a parent layout, in this case we're extending `app/views/layouts/application.html.erb`:
129
+
130
+ ``` erb
131
+ <%= extends :application do %>
132
+ ...
133
+ <% end %>
134
+ ```
135
+
136
+ You can nest many levels deep:
137
+
138
+ `app/views/layouts/application.html.erb`:
139
+
140
+ ``` erb
141
+ <!DOCTYPE html>
142
+ <html>
143
+ <head>
144
+ <%= area :head do %>
145
+ <title><%= area :title, 'Nestive' %></title>
146
+ <% end %>
147
+ </head>
148
+ <body>
149
+ <%= yield %>
150
+ </body>
151
+ </html>
152
+ ```
153
+
154
+ `app/views/layouts/with_sidebar.html.erb`:
155
+
156
+ ``` erb
157
+ <%= extends :application do %>
158
+ <div class="sidebar"><%= area(:sidebar) do %>
159
+ here goes sidebar
160
+ <% end %></div>
161
+ <%= yield -%>
162
+ <% end %>
163
+ ```
164
+
165
+ `app/views/layouts/blog_posts.html.erb`:
166
+
167
+ ``` erb
168
+ <%= extends :with_sidebar do %>
169
+ <% append :sidebar do %>
170
+ Blog archive:
171
+ <%= render_blog_archive %>
172
+ <% end %>
173
+
174
+ <% append :head do %>
175
+ <%= javascript_include_tag 'fancy_blog_archive_tag_cloud' %>
176
+ <% end %>
177
+
178
+ <%= yield %>
179
+ <% end %>
180
+ ```
181
+
182
+ ## The token blog example
183
+
184
+ Set-up a global layout defining some content areas.
185
+
186
+ `app/views/layouts/application.html.erb`:
187
+
188
+ ``` erb
189
+ <!DOCTYPE html>
190
+ <html>
191
+ <head>
192
+ <meta charset="utf-8">
193
+ <title><%= area :title, "JustinFrench.com" %></title>
194
+ <meta name="description" content="<%= area :description, "This is my website." %>">
195
+ <meta name="keywords" content="<%= area :keywords, "justin, french, ruby, design" %>">
196
+ </head>
197
+ <body>
198
+ <div id="wrapper">
199
+ <div id="content">
200
+ <%= area :content do %>
201
+ <p>Default content goes here.</p>
202
+ <% end %>
203
+ </div>
204
+ <div id="sidebar">
205
+ <%= area :sidebar do %>
206
+ <h2>About Me</h2>
207
+ <p>...</p>
208
+ <% end %>
209
+ </div>
210
+ </div>
211
+ <%= yield %>
212
+ </body>
213
+ </html>
214
+ ```
215
+
216
+ Next, we set-up a `blog` layout that extends `application`, replacing,
217
+ appending & prepending content to the areas we defined earlier.
218
+
219
+ `app/views/layouts/blog.html.erb`:
220
+
221
+ ``` erb
222
+ <%= extends :application do %>
223
+ <% replace :title, "My Blog – " %>
224
+ <% replace :description, "Justin French blogs here on Ruby, Rails, Design, Formtastic, etc" %>
225
+ <% prepend :keywords, "blog, weblog, design links, ruby links, formtastic release notes, " %>
226
+ <%= yield %>
227
+ <% end %>
228
+ ```
229
+
230
+ Now in our blog index view we can use `blog` layout and fill in the areas with
231
+ content specific to the index action.
232
+
233
+
234
+ `app/views/posts/index.html.erb`:
235
+
236
+ ``` erb
237
+ <% replace :content do %>
238
+ <h1>My Blog</h1>
239
+ <%= render @articles %>
240
+ <% end %>
241
+
242
+ <% append :sidebar do %>
243
+ <h2>Blog Roll</h2>
244
+ <%= render @links %>
245
+ <% end %>
246
+ ```
247
+
248
+ We also need to instruct the `PostsController` to use this `blog` layout:
249
+
250
+ `app/controllers/posts_controller.rb`:
251
+
252
+ ``` ruby
253
+ class PostsController < ApplicationController
254
+ layout 'blog'
255
+ end
256
+ ```
257
+
258
+ ---
259
+
260
+ ## Caching
261
+
262
+ nestive-rails works the same way `content_for` does and has the same caching drawbacks. That means that nestive-rails helpers are completely ignored when called from within cached block. You probably don't want to use fragment caching around dynamic nestive-rails areas and have to be extra careful what and how you cache to avoid unpleasant surprises.
263
+
264
+ ---
265
+
266
+ ## To Do
267
+
268
+ [Here](https://github.com/jonhue/nestive-rails/projects/1) is the full list of current projects.
269
+
270
+ To propose your ideas, initiate the discussion by adding a [new issue](https://github.com/jonhue/nestive-rails/issues/new).
271
+
272
+ ---
273
+
274
+ ## Contributing
275
+
276
+ We hope that you will consider contributing to `nestive-rails`. Please read this short overview for some information about how to get started:
277
+
278
+ [Learn more about contributing to this repository](https://github.com/jonhue/nestive-rails/blob/master/CONTRIBUTING.md), [Code of Conduct](https://github.com/jonhue/nestive-rails/blob/master/CODE_OF_CONDUCT.md)
279
+
280
+ ### Contributors
281
+
282
+ Give the people some :heart: who are working on this project. See them all at:
283
+
284
+ https://github.com/jonhue/nestive-rails/graphs/contributors
285
+
286
+ ## License
287
+
288
+ MIT License
289
+
290
+ Copyright (c) 2017 Jonas Hübotter
291
+
292
+ Permission is hereby granted, free of charge, to any person obtaining a copy
293
+ of this software and associated documentation files (the "Software"), to deal
294
+ in the Software without restriction, including without limitation the rights
295
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
296
+ copies of the Software, and to permit persons to whom the Software is
297
+ furnished to do so, subject to the following conditions:
298
+
299
+ The above copyright notice and this permission notice shall be included in all
300
+ copies or substantial portions of the Software.
301
+
302
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
303
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
304
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
305
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
306
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
307
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
308
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+ task default: :spec
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'nestive-rails'
@@ -0,0 +1,9 @@
1
+ require 'nestive-rails/version'
2
+
3
+ module NestiveRails
4
+
5
+ autoload :LayoutHelper, 'nestive-rails/layout_helper'
6
+
7
+ require 'nestive-rails/railtie'
8
+
9
+ end
@@ -0,0 +1,245 @@
1
+ module NestiveRails
2
+
3
+ # The Nestive 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
+ #
60
+ # @example Extending the `application` layout to create an `admin` layout
61
+ #
62
+ # # app/views/layouts/admin.html.erb
63
+ # <%= extends :application do %>
64
+ # ...
65
+ # <% end %>
66
+ #
67
+ # @example Extending the `admin` layout in a view (you'll need to render the view with `layout: nil`)
68
+ #
69
+ # # app/controllers/admin/posts_controller.rb
70
+ # class Admin::PostsController < ApplicationController
71
+ # # You can disable Rails' layout rendering for all actions
72
+ # layout nil
73
+ #
74
+ # # Or disable Rails' layout rendering per-controller
75
+ # def index
76
+ # render layout: nil
77
+ # end
78
+ # end
79
+ #
80
+ # # app/views/admin/posts/index.html.erb
81
+ # <%= extends :admin do %>
82
+ # ...
83
+ # <% end %>
84
+ def extends layout, &block
85
+ # Make sure it's a string
86
+ layout = layout.to_s
87
+
88
+ # If there's no directory component, presume a plain layout name
89
+ layout = "layouts/#{layout}" unless layout.include?('/')
90
+
91
+ # Capture the content to be placed inside the extended layout
92
+ @view_flow.get(:layout).replace capture(&block).to_s
93
+
94
+ render file: layout
95
+ end
96
+
97
+ # Defines an area of content in your layout that can be modified or replaced by child layouts
98
+ # that extend it. You can optionally add content to an area using either a String, or a block.
99
+ #
100
+ # Areas are declared in a parent layout and modified by a child layout, but since Nestive
101
+ # allows for multiple levels of inheritance, a child layout can also declare an area for it's
102
+ # children to modify.
103
+ #
104
+ # @example Define an area without adding content to it:
105
+ # <%= area :sidebar %>
106
+ #
107
+ # @example Define an area and add a String of content to it:
108
+ # <%= area :sidebar, "Some content." %>
109
+ #
110
+ # @example Define an area and add content to it with a block:
111
+ # <%= area :sidebar do %>
112
+ # Some content.
113
+ # <% end %>
114
+ #
115
+ # @example Define an area in a child layout:
116
+ # <%= extends :global do %>
117
+ # <%= area :sidebar do %>
118
+ # Some content.
119
+ # <% end %>
120
+ # <% end %>
121
+ #
122
+ # @param [Symbol] name
123
+ # A unique name to identify this area of content.
124
+ #
125
+ # @param [String] content
126
+ # An optional String of content to add to the area as you declare it.
127
+ def area name, content=nil, &block
128
+ content = capture(&block) if block_given?
129
+ append name, content
130
+ render_area name
131
+ end
132
+
133
+ # Appends content to an area previously defined or modified in parent layout(s). You can provide
134
+ # the content using either a String, or a block.
135
+ #
136
+ # @example Appending content with a String
137
+ # <% append :sidebar, "Some content." %>
138
+ #
139
+ # @example Appending content with a block:
140
+ # <% append :sidebar do %>
141
+ # Some content.
142
+ # <% end %>
143
+ #
144
+ # @param [Symbol] name
145
+ # A name to identify the area of content you wish to append to
146
+ #
147
+ # @param [String] content
148
+ # Optionally provide a String of content, instead of a block. A block will take precedence.
149
+ def append name, content=nil, &block
150
+ content = capture(&block) if block_given?
151
+ add_instruction_to_area name, :push, content
152
+ end
153
+
154
+ # Prepends content to an area previously declared or modified in parent layout(s). You can
155
+ # provide the content using either a String, or a block.
156
+ #
157
+ # @example Prepending content with a String
158
+ # <% prepend :sidebar, "Some content." %>
159
+ #
160
+ # @example Prepending content with a block:
161
+ # <% prepend :sidebar do %>
162
+ # Some content.
163
+ # <% end %>
164
+ #
165
+ # @param [Symbol] name
166
+ # A name to identify the area of content you wish to prepend to
167
+ #
168
+ # @param [String] content
169
+ # Optionally provide a String of content, instead of a block. A block will take precedence.
170
+ def prepend name, content=nil, &block
171
+ content = capture(&block) if block_given?
172
+ add_instruction_to_area name, :unshift, content
173
+ end
174
+
175
+ # Replaces the content of an area previously declared or modified in parent layout(s). You can
176
+ # provide the content using either a String, or a block.
177
+ #
178
+ # @example Replacing content with a String
179
+ # <% replace :sidebar, "New content." %>
180
+ #
181
+ # @example Replacing content with a block:
182
+ # <% replace :sidebar do %>
183
+ # New content.
184
+ # <% end %>
185
+ #
186
+ # @param [Symbol] name
187
+ # A name to identify the area of content you wish to replace
188
+ #
189
+ # @param [String] content
190
+ # Optionally provide a String of content, instead of a block. A block will take precedence.
191
+ def replace name, content=nil, &block
192
+ content = capture(&block) if block_given?
193
+ add_instruction_to_area name, :replace, [content]
194
+ end
195
+
196
+ # Purge the content of an area previously declared or modified in parent layout(s).
197
+ #
198
+ # @example Purge content
199
+ # <% purge :sidebar %>
200
+ #
201
+ # @param names
202
+ # A list of area names to purge
203
+ def purge *names
204
+ names.each{ |name| replace(name, nil) }
205
+ end
206
+
207
+ private
208
+
209
+ # We record the instructions (declaring, appending, prepending and replacing) for an area of
210
+ # content into an array that we can later retrieve and replay. Instructions are stored in an
211
+ # instance variable Hash `@_area_for`, with each key representing an area name, and each value
212
+ # an Array of instructions. Each instruction is a two element array containing a instruction
213
+ # method (eg `:push`, `:unshift`, `:replace`) and a value (content String).
214
+ #
215
+ # @_area_for[:sidebar] # => [ [:push,"World"], [:unshift,"Hello"] ]
216
+ #
217
+ # Due to the way we extend layouts (render the parent layout after the child), the instructions
218
+ # are captured in reverse order. `render_area` reversed them and plays them back at rendering
219
+ # time.
220
+ #
221
+ # @example
222
+ # add_instruction_to_area(:sidebar, :push, "More content.")
223
+ def add_instruction_to_area name, instruction, value
224
+ @_area_for ||= {}
225
+ @_area_for[name] ||= []
226
+ @_area_for[name] << [instruction, value]
227
+ nil
228
+ end
229
+
230
+ # Take the instructions we've gathered for the area and replay them one after the other on
231
+ # an empty array. These instructions will push, unshift or replace items into our output array,
232
+ # which we then join and mark as html_safe.
233
+ #
234
+ # These instructions are reversed and replayed when we render the block (rather than as they
235
+ # happen) due to the way they are gathered by the layout extension process (in reverse).
236
+ def render_area name
237
+ [].tap do |output|
238
+ @_area_for.fetch(name, []).reverse_each do |method_name, content|
239
+ output.public_send method_name, content
240
+ end
241
+ end.join.html_safe
242
+ end
243
+
244
+ end
245
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails'
2
+
3
+ module NestiveRails
4
+ class Railtie < Rails::Railtie
5
+
6
+ initializer 'nestive-rails.action_view' do
7
+ ActiveSupport.on_load :action_view do
8
+ include NestiveRails::LayoutHelper
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module NestiveRails
2
+
3
+ VERSION = '1.0.0'
4
+
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path(File.join('..', 'lib', 'nestive-rails', 'version'), __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'nestive-rails'
6
+ gem.version = NestiveRails::VERSION
7
+ gem.platform = Gem::Platform::RUBY
8
+ gem.summary = 'A Better Nested Inheritable Layouts Plugin for Rails 5'
9
+ gem.description = 'A Better Nested Inheritable Layouts Plugin for Rails 5'
10
+ gem.authors = ['Jonas Hübotter', 'Justin French', 'Pavel Pravosud']
11
+ gem.email = ['jonas.huebotter@gmail.com', 'justin@indent.com.au', 'pavel@pravosud.com']
12
+ gem.homepage = 'https://github.com/jonhue/nestive-rails'
13
+ gem.license = 'MIT'
14
+
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.require_paths = ['lib']
17
+
18
+ gem.required_ruby_version = '>= 2.3'
19
+
20
+ gem.add_development_dependency 'bundler', '~> 1.16'
21
+ gem.add_development_dependency 'rake', '~> 10.0'
22
+ gem.add_dependency 'rails', '>= 5.0'
23
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nestive-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonas Hübotter
8
+ - Justin French
9
+ - Pavel Pravosud
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2017-12-19 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.16'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '1.16'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '10.0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '10.0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rails
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '5.0'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '5.0'
57
+ description: A Better Nested Inheritable Layouts Plugin for Rails 5
58
+ email:
59
+ - jonas.huebotter@gmail.com
60
+ - justin@indent.com.au
61
+ - pavel@pravosud.com
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - ".github/issue_template.md"
67
+ - ".github/pull_request_template.md"
68
+ - ".gitignore"
69
+ - ".travis.yml"
70
+ - CHANGELOG.md
71
+ - CODE_OF_CONDUCT.md
72
+ - CONTRIBUTING.md
73
+ - DEPRECATIONS.md
74
+ - Gemfile
75
+ - LICENSE
76
+ - README.md
77
+ - Rakefile
78
+ - init.rb
79
+ - lib/nestive-rails.rb
80
+ - lib/nestive-rails/layout_helper.rb
81
+ - lib/nestive-rails/railtie.rb
82
+ - lib/nestive-rails/version.rb
83
+ - nestive-rails.gemspec
84
+ homepage: https://github.com/jonhue/nestive-rails
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '2.3'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.7.3
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: A Better Nested Inheritable Layouts Plugin for Rails 5
108
+ test_files: []