roda 3.49.0 → 3.50.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d3b9688bae8b0013acedfc6a5bcb45c374e0a73fd30e56985f0ebeee942ef8c
4
- data.tar.gz: acb8215250d1615f007a2ec01d2b6546376414d2fea23a4f2341af9efd951110
3
+ metadata.gz: b9da24f38f427b9256f05e92f40d67fe98bbdefb86419e5b8c13243f88418f8a
4
+ data.tar.gz: 3acabff7d8879126d6fdf2199e0935c96d0ea1c975feef874122d67d2afe7315
5
5
  SHA512:
6
- metadata.gz: 3a5434bdcb6926d6c5e656c25b46e16b035ad54d74ed16bdc1cf46005b8ef605b3371a628cae52d65803064aa3d2eac8a56c2e8e1e55b6f3a82c04a74c636855
7
- data.tar.gz: 9dc3773fae04325373adb8a7a57d52166bb65c238b959999adf6f6f17a3be29fcdedcea677eeeaaa84f6a01b5accb4aff2594817165b8a77a45106a3d4a9dea3
6
+ metadata.gz: 7535b67bed981d52d337643c24f13b206163392594b3f969e611b79020a8578994b934a34abc186cf07850725c1ce8a99fbcb859b58cce289b8138b329ca4c68
7
+ data.tar.gz: 3fdbb4aa63d1cd82a7f6cbdfe01a9804388ab8b4461f9dda825332f030a1179737a21be4ea59c9e52fa856f6952d77578e972263397c62de4c42680340472313
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ = 3.50.0 (2021-11-12)
2
+
3
+ * Add capture_erb plugin for capturing ERB template blocks, instead of injecting them into the template output (jeremyevans)
4
+
5
+ * Add inject_erb plugin for injecting content directly into ERB template output (jeremyevans)
6
+
7
+ * Allow hash_branch and hash_path in hash_routes plugin to be called without a block to remove existing handler (jeremyevans)
8
+
1
9
  = 3.49.0 (2021-10-13)
2
10
 
3
11
  * Switch block_given? to defined?(yield) (jeremyevans)
@@ -0,0 +1,21 @@
1
+ = New Features
2
+
3
+ * An inject_erb plugin has been added, adding an inject_erb method
4
+ that allows for injecting content directly into the template output
5
+ for the template currently being rendered. This allows you to more
6
+ easily wrap blocks in templates, by calling methods that accept
7
+ template blocks and injecting content before and after the block.
8
+
9
+ * A capture_erb plugin has been added, adding a capture_erb method
10
+ for capturing a template block in an erb template and returning
11
+ the content appended during the block as a string, instead of
12
+ having the content of the template block be included directly into
13
+ the template output. This can be combined with the inject_erb
14
+ plugin to inject modified versions of captured blocks into template
15
+ output.
16
+
17
+ * The hash_routes plugin now allows calling hash_branch and hash_path
18
+ without a block in order to remove the existing route handler. This
19
+ is designed to be used with code reloading libraries, so that if a
20
+ route file is deleted, the related hash branches/paths are also
21
+ removed, without having to reload all route files.
@@ -0,0 +1,41 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The capture_erb plugin allows you to capture the content of a block
7
+ # in an ERB template, and return it as a value, instead of
8
+ # injecting the template block into the template output.
9
+ #
10
+ # <% value = capture_erb do %>
11
+ # Some content here.
12
+ # <% end %>
13
+ #
14
+ # +capture_erb+ can be used inside other methods that are called
15
+ # inside templates. It can be combined with the inject_erb plugin
16
+ # to wrap template blocks with arbitrary output and then inject the
17
+ # wrapped output into the template.
18
+ module CaptureERB
19
+ def self.load_dependencies(app)
20
+ app.plugin :render
21
+ end
22
+
23
+ module InstanceMethods
24
+ # Temporarily replace the ERB output buffer
25
+ # with an empty string, and then yield to the block.
26
+ # Return the value of the block, converted to a string.
27
+ # Restore the previous ERB output buffer before returning.
28
+ def capture_erb
29
+ outvar = render_opts[:template_opts][:outvar]
30
+ buf_was = instance_variable_get(outvar)
31
+ instance_variable_set(outvar, String.new)
32
+ yield.to_s
33
+ ensure
34
+ instance_variable_set(outvar, buf_was) if outvar && buf_was
35
+ end
36
+ end
37
+ end
38
+
39
+ register_plugin(:capture_erb, CaptureERB)
40
+ end
41
+ end
@@ -55,10 +55,10 @@ class Roda
55
55
  #
56
56
  # plugin :content_for, append: false
57
57
  module ContentFor
58
- # Depend on the render plugin, since this plugin only makes
59
- # sense when the render plugin is used.
58
+ # Depend on the capture_erb plugin, since it uses capture_erb
59
+ # to capture the content.
60
60
  def self.load_dependencies(app, _opts = OPTS)
61
- app.plugin :render
61
+ app.plugin :capture_erb
62
62
  end
63
63
 
64
64
  # Configure whether to append or overwrite if content_for
@@ -72,18 +72,12 @@ class Roda
72
72
  # under the given key. If called without a block, retrieve
73
73
  # stored content with the given key, or return nil if there
74
74
  # is no content stored with that key.
75
- def content_for(key, value=nil)
75
+ def content_for(key, value=nil, &block)
76
76
  append = opts[:append_content_for]
77
77
 
78
- if defined?(yield) || value
79
- if defined?(yield)
80
- outvar = render_opts[:template_opts][:outvar]
81
- buf_was = instance_variable_get(outvar)
82
-
83
- # Use temporary output buffer for ERB-based rendering systems
84
- instance_variable_set(outvar, String.new)
85
- value = yield.to_s
86
- instance_variable_set(outvar, buf_was)
78
+ if block || value
79
+ if block
80
+ value = capture_erb(&block)
87
81
  end
88
82
 
89
83
  @_content_for ||= {}
@@ -394,20 +394,32 @@ class Roda
394
394
  dsl
395
395
  end
396
396
 
397
- # Add branch handler for the given namespace and segment.
397
+ # Add branch handler for the given namespace and segment. If called without
398
+ # a block, removes the existing branch handler if it exists.
398
399
  def hash_branch(namespace='', segment, &block)
399
400
  segment = "/#{segment}"
400
401
  routes = opts[:hash_branches][namespace] ||= {}
401
- routes[segment] = define_roda_method(routes[segment] || "hash_branch_#{namespace}_#{segment}", 1, &convert_route_block(block))
402
+ if block
403
+ routes[segment] = define_roda_method(routes[segment] || "hash_branch_#{namespace}_#{segment}", 1, &convert_route_block(block))
404
+ elsif meth = routes[segment]
405
+ routes.delete(segment)
406
+ remove_method(meth)
407
+ end
402
408
  end
403
409
 
404
410
  # Add path handler for the given namespace and path. When the
405
411
  # r.hash_paths method is called, checks the matching namespace
406
412
  # for the full remaining path, and dispatch to that block if
407
- # there is one.
413
+ # there is one. If called without a block, removes the existing
414
+ # path handler if it exists.
408
415
  def hash_path(namespace='', path, &block)
409
416
  routes = opts[:hash_paths][namespace] ||= {}
410
- routes[path] = define_roda_method(routes[path] || "hash_path_#{namespace}_#{path}", 1, &convert_route_block(block))
417
+ if block
418
+ routes[path] = define_roda_method(routes[path] || "hash_path_#{namespace}_#{path}", 1, &convert_route_block(block))
419
+ elsif meth = routes[path]
420
+ routes.delete(path)
421
+ remove_method(meth)
422
+ end
411
423
  end
412
424
  end
413
425
 
@@ -0,0 +1,33 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The inject_erb plugin allows you to inject content directly
7
+ # into the template output:
8
+ #
9
+ # <% inject_erb("Some HTML Here") %>
10
+ #
11
+ # This will inject <tt>Some HTML Here</tt> into the template output,
12
+ # even though the tag being used is <tt><%</tt> and not <tt><%=</tt>.
13
+ #
14
+ # This method can be used inside methods, such as to wrap calls to
15
+ # methods that accept template blocks, to inject code before and after
16
+ # the template blocks.
17
+ module InjectERB
18
+ def self.load_dependencies(app)
19
+ app.plugin :render
20
+ end
21
+
22
+ module InstanceMethods
23
+ # Inject into the template output for the template currently being
24
+ # rendered.
25
+ def inject_erb(value)
26
+ instance_variable_get(render_opts[:template_opts][:outvar]) << value.to_s
27
+ end
28
+ end
29
+ end
30
+
31
+ register_plugin(:inject_erb, InjectERB)
32
+ end
33
+ end
@@ -47,7 +47,7 @@ class Roda
47
47
  # The following plugin options are supported:
48
48
  #
49
49
  # :allowed_paths :: Set the template paths to allow. Attempts to render paths outside
50
- # of this directory will raise an error. Defaults to the +:views+ directory.
50
+ # of these paths will raise an error. Defaults to the +:views+ directory.
51
51
  # :cache :: nil/false to explicitly disable premanent template caching. By default, permanent
52
52
  # template caching is disabled by default if RACK_ENV is development. When permanent
53
53
  # template caching is disabled, for templates with paths in the file system, the
@@ -59,9 +59,9 @@ class Roda
59
59
  # templates, defaults to 'erb'.
60
60
  # :escape :: Use Erubi as the ERB template engine, and enable escaping by default,
61
61
  # which makes <tt><%= %></tt> escape output and <tt><%== %></tt> not escape output.
62
- # If given, sets the <tt>:escape=>true</tt> option for all template engines, which
62
+ # If given, sets the <tt>escape: true</tt> option for all template engines, which
63
63
  # can break some non-ERB template engines. You can use a string or array of strings
64
- # as the value for this option to only set the <tt>:escape=>true</tt> option for those
64
+ # as the value for this option to only set the <tt>escape: true</tt> option for those
65
65
  # specific template engines.
66
66
  # :layout :: The base name of the layout file, defaults to 'layout'. This can be provided as a hash
67
67
  # with the :template or :inline options.
@@ -130,6 +130,84 @@ class Roda
130
130
  # only argument, you can speed things up by specifying a +:cache_key+ option in
131
131
  # the hash, making sure the +:cache_key+ is unique to the template you are
132
132
  # rendering.
133
+ #
134
+ # = Accepting Template Blocks in Methods
135
+ #
136
+ # If you are used to Rails, you may be surprised that this type of template code
137
+ # doesn't work in Roda:
138
+ #
139
+ # <%= some_method do %>
140
+ # Some HTML
141
+ # <% end %>
142
+ #
143
+ # The reason this doesn't work is that this is not valid ERB syntax, it is Rails syntax,
144
+ # and requires attempting to parse the <tt>some_method do</tt> Ruby code with a regular
145
+ # expression. Since Roda uses ERB syntax, it does not support this.
146
+ #
147
+ # In general, these methods are used to wrap the content of the block and
148
+ # inject the content into the output. To get similar behavior with Roda, you have
149
+ # a few different options you can use.
150
+ #
151
+ # == Directly Inject Template Output
152
+ #
153
+ # You can switch from a <tt><%=</tt> tag to using a <tt><%</tt> tag:
154
+ #
155
+ # <% some_method do %>
156
+ # Some HTML
157
+ # <% end %>
158
+ #
159
+ # While this would output <tt>Some HTML</tt> into the template, it would not be able
160
+ # to inject content before or after the block. However, you can use the inject_erb_plugin
161
+ # to handle the injection:
162
+ #
163
+ # def some_method
164
+ # inject_erb "content before block"
165
+ # yield
166
+ # inject_erb "content after block"
167
+ # end
168
+ #
169
+ # If you need to modify the captured block before injecting it, you can use the
170
+ # capture_erb plugin to capture content from the template block, and modify that content,
171
+ # then use inject_erb to inject it into the template output:
172
+ #
173
+ # def some_method(&block)
174
+ # inject_erb "content before block"
175
+ # inject_erb capture_erb(&block).upcase
176
+ # inject_erb "content after block"
177
+ # end
178
+ #
179
+ # This is the recommended approach for handling this type of method, if you want to keep
180
+ # the template block in the same template.
181
+ #
182
+ # == Separate Block Output Into Separate Template
183
+ #
184
+ # By moving the <tt>Some HTML</tt> into a separate template, you can render that
185
+ # template inside the block:
186
+ #
187
+ # <%= some_method{render('template_name')} %>
188
+ #
189
+ # It's also possible to use an inline template:
190
+ #
191
+ # <%= some_method do render(:inline=><<-END)
192
+ # Some HTML
193
+ # END
194
+ # end %>
195
+ #
196
+ # This approach is useful if it makes sense to separate the template block into its
197
+ # own template. You lose the ability to use local variable from outside the
198
+ # template block inside the template block with this approach.
199
+ #
200
+ # == Separate Header and Footer
201
+ #
202
+ # You can define two separate methods, one that outputs the content before the block,
203
+ # and one that outputs the content after the block, and use those instead of a single
204
+ # call:
205
+ #
206
+ # <%= some_method_before %>
207
+ # Some HTML
208
+ # <%= some_method_after %>
209
+ #
210
+ # This is the simplest option to setup, but it is fairly tedious to use.
133
211
  module Render
134
212
  # Support for using compiled methods directly requires Ruby 2.3 for the
135
213
  # method binding to work, and Tilt 1.2 for Tilt::Template#compiled_method.
@@ -6,8 +6,7 @@ class Roda
6
6
  # The status_303 plugin sets the default redirect status to be 303
7
7
  # rather than 302 when the request is not a GET and the
8
8
  # redirection occurs on an HTTP 1.1 connection as per RFC 7231.
9
- # The author knows of no cases where this actually matters in
10
- # practice.
9
+ # There are some frontend frameworks that require this behavior.
11
10
  #
12
11
  # Example:
13
12
  #
data/lib/roda/version.rb CHANGED
@@ -4,7 +4,7 @@ class Roda
4
4
  RodaMajorVersion = 3
5
5
 
6
6
  # The minor version of Roda, updated for new feature releases of Roda.
7
- RodaMinorVersion = 49
7
+ RodaMinorVersion = 50
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.49.0
4
+ version: 3.50.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-13 00:00:00.000000000 Z
11
+ date: 2021-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -221,6 +221,7 @@ extra_rdoc_files:
221
221
  - doc/release_notes/3.48.0.txt
222
222
  - doc/release_notes/3.49.0.txt
223
223
  - doc/release_notes/3.5.0.txt
224
+ - doc/release_notes/3.50.0.txt
224
225
  - doc/release_notes/3.6.0.txt
225
226
  - doc/release_notes/3.7.0.txt
226
227
  - doc/release_notes/3.8.0.txt
@@ -277,6 +278,7 @@ files:
277
278
  - doc/release_notes/3.48.0.txt
278
279
  - doc/release_notes/3.49.0.txt
279
280
  - doc/release_notes/3.5.0.txt
281
+ - doc/release_notes/3.50.0.txt
280
282
  - doc/release_notes/3.6.0.txt
281
283
  - doc/release_notes/3.7.0.txt
282
284
  - doc/release_notes/3.8.0.txt
@@ -294,6 +296,7 @@ files:
294
296
  - lib/roda/plugins/backtracking_array.rb
295
297
  - lib/roda/plugins/branch_locals.rb
296
298
  - lib/roda/plugins/caching.rb
299
+ - lib/roda/plugins/capture_erb.rb
297
300
  - lib/roda/plugins/chunked.rb
298
301
  - lib/roda/plugins/class_level_routing.rb
299
302
  - lib/roda/plugins/class_matchers.rb
@@ -329,6 +332,7 @@ files:
329
332
  - lib/roda/plugins/hooks.rb
330
333
  - lib/roda/plugins/host_authorization.rb
331
334
  - lib/roda/plugins/indifferent_params.rb
335
+ - lib/roda/plugins/inject_erb.rb
332
336
  - lib/roda/plugins/json.rb
333
337
  - lib/roda/plugins/json_parser.rb
334
338
  - lib/roda/plugins/mail_processor.rb