roda 2.28.0 → 2.29.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.
- checksums.yaml +4 -4
- data/CHANGELOG +46 -0
- data/README.rdoc +25 -7
- data/doc/release_notes/2.29.0.txt +156 -0
- data/lib/roda.rb +25 -3
- data/lib/roda/plugins/_erubis_escaping.rb +2 -0
- data/lib/roda/plugins/_symbol_regexp_matchers.rb +22 -0
- data/lib/roda/plugins/assets.rb +3 -2
- data/lib/roda/plugins/branch_locals.rb +74 -0
- data/lib/roda/plugins/caching.rb +15 -7
- data/lib/roda/plugins/chunked.rb +10 -7
- data/lib/roda/plugins/content_for.rb +4 -1
- data/lib/roda/plugins/drop_body.rb +3 -2
- data/lib/roda/plugins/error_email.rb +3 -2
- data/lib/roda/plugins/error_mail.rb +3 -2
- data/lib/roda/plugins/head.rb +2 -1
- data/lib/roda/plugins/header_matchers.rb +3 -0
- data/lib/roda/plugins/heartbeat.rb +3 -2
- data/lib/roda/plugins/json.rb +5 -3
- data/lib/roda/plugins/json_parser.rb +3 -2
- data/lib/roda/plugins/mailer.rb +3 -3
- data/lib/roda/plugins/match_affix.rb +6 -0
- data/lib/roda/plugins/multi_route.rb +3 -1
- data/lib/roda/plugins/padrino_render.rb +3 -2
- data/lib/roda/plugins/params_capturing.rb +3 -3
- data/lib/roda/plugins/partials.rb +3 -3
- data/lib/roda/plugins/path.rb +4 -2
- data/lib/roda/plugins/path_rewriter.rb +2 -2
- data/lib/roda/plugins/per_thread_caching.rb +2 -0
- data/lib/roda/plugins/placeholder_string_matchers.rb +42 -0
- data/lib/roda/plugins/precompile_templates.rb +3 -2
- data/lib/roda/plugins/render.rb +86 -37
- data/lib/roda/plugins/render_each.rb +2 -1
- data/lib/roda/plugins/render_locals.rb +102 -0
- data/lib/roda/plugins/run_append_slash.rb +2 -1
- data/lib/roda/plugins/run_handler.rb +2 -1
- data/lib/roda/plugins/sinatra_helpers.rb +4 -4
- data/lib/roda/plugins/static_path_info.rb +2 -0
- data/lib/roda/plugins/static_routing.rb +1 -1
- data/lib/roda/plugins/streaming.rb +9 -4
- data/lib/roda/plugins/symbol_matchers.rb +23 -20
- data/lib/roda/plugins/view_options.rb +63 -28
- data/lib/roda/plugins/view_subdirs.rb +1 -0
- data/lib/roda/plugins/websockets.rb +2 -0
- data/lib/roda/version.rb +1 -1
- data/spec/composition_spec.rb +2 -2
- data/spec/matchers_spec.rb +6 -5
- data/spec/plugin/_erubis_escaping_spec.rb +5 -5
- data/spec/plugin/backtracking_array_spec.rb +0 -2
- data/spec/plugin/branch_locals_spec.rb +88 -0
- data/spec/plugin/content_for_spec.rb +8 -2
- data/spec/plugin/halt_spec.rb +8 -0
- data/spec/plugin/header_matchers_spec.rb +20 -5
- data/spec/plugin/multi_route_spec.rb +1 -1
- data/spec/plugin/named_templates_spec.rb +2 -2
- data/spec/plugin/params_capturing_spec.rb +1 -1
- data/spec/plugin/per_thread_caching_spec.rb +1 -1
- data/spec/plugin/placeholder_string_matchers_spec.rb +159 -0
- data/spec/plugin/render_locals_spec.rb +114 -0
- data/spec/plugin/render_spec.rb +83 -8
- data/spec/plugin/streaming_spec.rb +104 -4
- data/spec/plugin/symbol_matchers_spec.rb +1 -1
- data/spec/plugin/view_options_spec.rb +83 -7
- data/spec/plugin/websockets_spec.rb +7 -8
- data/spec/spec_helper.rb +22 -2
- metadata +11 -2
|
@@ -46,7 +46,7 @@ class Roda
|
|
|
46
46
|
# processed before remaining_path rewrites.
|
|
47
47
|
module PathRewriter
|
|
48
48
|
OPTS={}.freeze
|
|
49
|
-
|
|
49
|
+
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
50
50
|
PATH_INFO = 'PATH_INFO'.freeze
|
|
51
51
|
RodaPlugins.deprecate_constant(self, :PATH_INFO)
|
|
52
52
|
|
|
@@ -67,7 +67,7 @@ class Roda
|
|
|
67
67
|
|
|
68
68
|
# Record a path rewrite from path +was+ to path +is+. Options:
|
|
69
69
|
# :path_info :: Modify PATH_INFO, not just remaining path.
|
|
70
|
-
def rewrite_path(was, is = nil, opts=OPTS, &block)
|
|
70
|
+
def rewrite_path(was, is = nil, opts=RodaPlugins::OPTS, &block)
|
|
71
71
|
if is.is_a? Hash
|
|
72
72
|
raise RodaError, "cannot provide two hashes to rewrite_path" unless opts.empty?
|
|
73
73
|
opts = is
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
#
|
|
4
4
|
class Roda
|
|
5
5
|
module RodaPlugins
|
|
6
|
+
warn "The per_thread_caching plugin is deprecated and will be removed in Roda 3. Consider maintaining the plugin as a separate gem if you would like to keep using it."
|
|
7
|
+
|
|
6
8
|
# The per_thread_caching plugin changes the default cache
|
|
7
9
|
# from being a shared thread safe cache to a separate cache per
|
|
8
10
|
# thread. This means getting or setting values no longer
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
class Roda
|
|
5
|
+
module RodaPlugins
|
|
6
|
+
# The placeholder_string_matcher plugin exists for backwards compatibility
|
|
7
|
+
# with previous versions of Roda that allowed placeholders inside strings
|
|
8
|
+
# if they were prefixed by colons:
|
|
9
|
+
#
|
|
10
|
+
# plugin :placeholder_string_matchers
|
|
11
|
+
#
|
|
12
|
+
# route do |r|
|
|
13
|
+
# r.is("foo/:bar") |v|
|
|
14
|
+
# # matches foo/baz, yielding "baz"
|
|
15
|
+
# # does not match foo, foo/, or foo/baz/
|
|
16
|
+
# end
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# It is not recommended to use this in new applications, and it is encouraged
|
|
20
|
+
# to use separate symbol or string class matchers instead:
|
|
21
|
+
#
|
|
22
|
+
# r.is "foo", String
|
|
23
|
+
# r.is "foo", :bar
|
|
24
|
+
module PlaceholderStringMatchers
|
|
25
|
+
def self.load_dependencies(app)
|
|
26
|
+
app.plugin :_symbol_regexp_matchers
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module RequestMethods
|
|
30
|
+
def _match_string(str)
|
|
31
|
+
if str.index(":")
|
|
32
|
+
consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:(\w+)/){|m| _match_symbol_regexp($1)}})
|
|
33
|
+
else
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
register_plugin(:placeholder_string_matchers, PlaceholderStringMatchers)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -47,10 +47,11 @@ class Roda
|
|
|
47
47
|
# precompile_templates :inline=>some_template_string
|
|
48
48
|
module PrecompileTemplates
|
|
49
49
|
OPTS = {}.freeze
|
|
50
|
+
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
50
51
|
|
|
51
52
|
# Load the render plugin as precompile_templates depends on it.
|
|
52
53
|
# Default to sorting the locals if the Tilt version is greater than 2.0.1.
|
|
53
|
-
def self.load_dependencies(app, opts=OPTS)
|
|
54
|
+
def self.load_dependencies(app, opts=RodaPlugins::OPTS)
|
|
54
55
|
app.plugin :render
|
|
55
56
|
app.opts[:precompile_templates_sort] = opts.fetch(:sort_locals, Tilt::VERSION > '2.0.1')
|
|
56
57
|
end
|
|
@@ -58,7 +59,7 @@ class Roda
|
|
|
58
59
|
module ClassMethods
|
|
59
60
|
# Precompile the templates using the given options. See PrecompileTemplates
|
|
60
61
|
# for details.
|
|
61
|
-
def precompile_templates(pattern, opts=OPTS)
|
|
62
|
+
def precompile_templates(pattern, opts=RodaPlugins::OPTS)
|
|
62
63
|
if pattern.is_a?(Hash)
|
|
63
64
|
opts = pattern.merge(opts)
|
|
64
65
|
end
|
data/lib/roda/plugins/render.rb
CHANGED
|
@@ -57,11 +57,6 @@ class Roda
|
|
|
57
57
|
# :escape :: Use Roda's Erubis escaping support, which makes <tt><%= %></tt> escape output,
|
|
58
58
|
# <tt><%== %></tt> not escape output, and handles postfix conditions inside
|
|
59
59
|
# <tt><%= %></tt> tags. Can have a value of :erubi to use Erubi escaping support.
|
|
60
|
-
# :escape_safe_classes :: String subclasses that should not be HTML escaped when used in
|
|
61
|
-
# <tt><%= %></tt> tags, when :escape=>true is used. Can be an array for multiple classes.
|
|
62
|
-
# :escaper :: Object used for escaping output of <tt><%= %></tt>, when :escape=>true is used,
|
|
63
|
-
# overriding the default. If given, object should respond to +escape_xml+ with
|
|
64
|
-
# a single argument and return an output string.
|
|
65
60
|
# :explicit_cache :: Only use the template cache if the :cache option is provided when rendering
|
|
66
61
|
# (useful for development). Defaults to true if RACK_ENV is development, allowing explicit
|
|
67
62
|
# caching of specific templates, but not caching by default.
|
|
@@ -69,10 +64,7 @@ class Roda
|
|
|
69
64
|
# starts subclasses with an empty cache.
|
|
70
65
|
# :layout :: The base name of the layout file, defaults to 'layout'. This can be provided as a hash
|
|
71
66
|
# with the :template or :inline options.
|
|
72
|
-
# :layout_opts :: The options to use when rendering the layout, if different
|
|
73
|
-
# from the default options. To pass local variables to the layout, include a :locals
|
|
74
|
-
# option inside :layout_opts. To automatically merge the view template locals into
|
|
75
|
-
# the layout template locals, include a :merge_locals option inside :layout_opts.
|
|
67
|
+
# :layout_opts :: The options to use when rendering the layout, if different from the default options.
|
|
76
68
|
# :template_opts :: The tilt options used when rendering all templates. defaults to:
|
|
77
69
|
# <tt>{:outvar=>'@_out_buf', :default_encoding=>Encoding.default_external}</tt>.
|
|
78
70
|
# :engine_opts :: The tilt options to use per template engine. Keys are
|
|
@@ -147,15 +139,17 @@ class Roda
|
|
|
147
139
|
# plugin option.
|
|
148
140
|
module Render
|
|
149
141
|
OPTS={}.freeze
|
|
142
|
+
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
150
143
|
|
|
151
|
-
|
|
144
|
+
# RODA3: Remove
|
|
145
|
+
def self.load_dependencies(app, opts=RodaPlugins::OPTS)
|
|
152
146
|
if opts[:escape] && opts[:escape] != :erubi
|
|
153
147
|
app.plugin :_erubis_escaping
|
|
154
148
|
end
|
|
155
149
|
end
|
|
156
150
|
|
|
157
151
|
# Setup default rendering options. See Render for details.
|
|
158
|
-
def self.configure(app, opts=OPTS)
|
|
152
|
+
def self.configure(app, opts=RodaPlugins::OPTS)
|
|
159
153
|
if app.opts[:render]
|
|
160
154
|
orig_cache = app.opts[:render][:cache]
|
|
161
155
|
opts = app.opts[:render][:orig_opts].merge(opts)
|
|
@@ -164,6 +158,9 @@ class Roda
|
|
|
164
158
|
app.opts[:render][:orig_opts] = opts
|
|
165
159
|
|
|
166
160
|
opts = app.opts[:render]
|
|
161
|
+
if opts[:ext] && !opts[:engine]
|
|
162
|
+
RodaPlugins.warn "The :ext render plugin option is deprecated and will be removed in Roda 3. Switch to using the :engine option."
|
|
163
|
+
end
|
|
167
164
|
opts[:engine] = (opts[:engine] || opts[:ext] || "erb").dup.freeze
|
|
168
165
|
opts[:views] = app.expand_path(opts[:views]||"views").freeze
|
|
169
166
|
opts[:allowed_paths] ||= [opts[:views]].freeze
|
|
@@ -182,8 +179,25 @@ class Roda
|
|
|
182
179
|
opts[:explicit_cache] = ENV['RACK_ENV'] == 'development' unless opts.has_key?(:explicit_cache)
|
|
183
180
|
|
|
184
181
|
opts[:layout_opts] = (opts[:layout_opts] || {}).dup
|
|
182
|
+
if opts[:layout_opts][:views]
|
|
183
|
+
opts[:layout_opts][:views] = app.expand_path(opts[:layout_opts][:views]).freeze
|
|
184
|
+
end
|
|
185
|
+
# RODA3: Remove
|
|
185
186
|
opts[:layout_opts][:_is_layout] = true
|
|
186
187
|
|
|
188
|
+
if opts[:locals]
|
|
189
|
+
RodaPlugins.warn "The :locals render plugin option is deprecated and will be removed in Roda 3. Locals should now be specified on a per-call basis, or you can use the render_locals plugin."
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
if opts[:layout_opts][:locals]
|
|
193
|
+
RodaPlugins.warn "The :layout_opts=>:locals render plugin option is deprecated and will be removed in Roda 3. Locals should now be specified on a per-call basis, or you can use the render_locals plugin."
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
if opts[:layout_opts][:merge_locals]
|
|
197
|
+
RodaPlugins.warn "The :layout_opts=>:merge_locals render plugin option is deprecated and will be removed in Roda 3. You can use the render_locals plugin for merging locals."
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# RODA3: Remove
|
|
187
201
|
if opts[:layout_opts][:merge_locals] && opts[:locals]
|
|
188
202
|
opts[:layout_opts][:locals] = opts[:locals].merge(opts[:layout_opts][:locals] || {})
|
|
189
203
|
end
|
|
@@ -207,6 +221,7 @@ class Roda
|
|
|
207
221
|
if RUBY_VERSION >= "1.9" && !template_opts.has_key?(:default_encoding)
|
|
208
222
|
template_opts[:default_encoding] = Encoding.default_external
|
|
209
223
|
end
|
|
224
|
+
# RODA3: Make :escape assume erubi, remove erubis support
|
|
210
225
|
if opts[:escape] == :erubi
|
|
211
226
|
require 'tilt/erubi'
|
|
212
227
|
template_opts[:escape] = true
|
|
@@ -259,10 +274,9 @@ class Roda
|
|
|
259
274
|
|
|
260
275
|
module InstanceMethods
|
|
261
276
|
# Render the given template. See Render for details.
|
|
262
|
-
def render(template, opts = OPTS, &block)
|
|
263
|
-
opts =
|
|
264
|
-
|
|
265
|
-
retrieve_template(opts).render((opts[:scope]||self), (opts[:locals]||OPTS), &block)
|
|
277
|
+
def render(template, opts = RodaPlugins::OPTS, &block)
|
|
278
|
+
opts = render_template_opts(template, opts)
|
|
279
|
+
retrieve_template(opts).render((opts[:scope]||self), (opts[:locals]||RodaPlugins::OPTS), &block)
|
|
266
280
|
end
|
|
267
281
|
|
|
268
282
|
# Return the render options for the instance's class. While this
|
|
@@ -275,7 +289,7 @@ class Roda
|
|
|
275
289
|
# Render the given template. If there is a default layout
|
|
276
290
|
# for the class, take the result of the template rendering
|
|
277
291
|
# and render it inside the layout. See Render for details.
|
|
278
|
-
def view(template, opts=OPTS)
|
|
292
|
+
def view(template, opts=RodaPlugins::OPTS)
|
|
279
293
|
opts = parse_template_opts(template, opts)
|
|
280
294
|
content = opts[:content] || render_template(opts)
|
|
281
295
|
|
|
@@ -288,6 +302,16 @@ class Roda
|
|
|
288
302
|
|
|
289
303
|
private
|
|
290
304
|
|
|
305
|
+
# Convert template options to single hash when rendering templates using render.
|
|
306
|
+
def render_template_opts(template, opts)
|
|
307
|
+
opts = parse_template_opts(template, opts)
|
|
308
|
+
|
|
309
|
+
# RODA3: Remove
|
|
310
|
+
merge_render_locals(opts) if render_plugin_handle_locals?
|
|
311
|
+
|
|
312
|
+
opts
|
|
313
|
+
end
|
|
314
|
+
|
|
291
315
|
# Private alias for render. Should be used by other plugins when they want to render a template
|
|
292
316
|
# without a layout, as plugins can override render to use a layout.
|
|
293
317
|
alias render_template render
|
|
@@ -309,6 +333,9 @@ class Roda
|
|
|
309
333
|
# template block, and locals to use for the render in the passed options.
|
|
310
334
|
def find_template(opts)
|
|
311
335
|
render_opts = render_opts()
|
|
336
|
+
if opts[:ext] && !opts[:engine]
|
|
337
|
+
RodaPlugins.warn "The :ext render plugin option is deprecated and will be removed in Roda 3. Switch to using the :engine option."
|
|
338
|
+
end
|
|
312
339
|
engine_override = opts[:engine] ||= opts[:ext]
|
|
313
340
|
engine = opts[:engine] ||= render_opts[:engine]
|
|
314
341
|
if content = opts[:inline]
|
|
@@ -339,12 +366,14 @@ class Roda
|
|
|
339
366
|
else
|
|
340
367
|
opts.delete(:cache_key)
|
|
341
368
|
end
|
|
369
|
+
elsif opts[:cache]
|
|
370
|
+
RodaPlugins.warn ":cache render/view method option used when caching explicitly disabled via :cache=>nil/false plugin option. Caching this template will be skipped for backwards compatibility. Starting in Roda 3, the :cache render/view method option will force caching even if the plugin defaults to not caching."
|
|
342
371
|
end
|
|
343
372
|
|
|
344
373
|
opts
|
|
345
374
|
end
|
|
346
375
|
|
|
347
|
-
#
|
|
376
|
+
# RODA3: Remove
|
|
348
377
|
def merge_render_locals(opts)
|
|
349
378
|
if !opts[:_is_layout] && (r_locals = render_opts[:locals])
|
|
350
379
|
opts[:locals] = if locals = opts[:locals]
|
|
@@ -398,45 +427,65 @@ class Roda
|
|
|
398
427
|
# The template path for the given options.
|
|
399
428
|
def template_path(opts)
|
|
400
429
|
path = "#{opts[:views]}/#{template_name(opts)}.#{opts[:engine]}"
|
|
430
|
+
full_path = self.class.expand_path(path)
|
|
401
431
|
if opts.fetch(:check_paths){render_opts[:check_paths]}
|
|
402
|
-
full_path = self.class.expand_path(path)
|
|
403
432
|
unless render_opts[:allowed_paths].any?{|f| full_path.start_with?(f)}
|
|
404
|
-
raise RodaError, "attempt to render path not in allowed_paths: #{
|
|
433
|
+
raise RodaError, "attempt to render path not in allowed_paths: #{full_path} (allowed: #{render_opts[:allowed_paths].join(', ')})"
|
|
434
|
+
end
|
|
435
|
+
elsif !opts.has_key?(:check_paths) && !render_opts.has_key?(:check_paths)
|
|
436
|
+
unless render_opts[:allowed_paths].any?{|f| full_path.start_with?(f)}
|
|
437
|
+
RodaPlugins.warn "The :check_paths render/view method option and :check_paths render plugin option were not specified, and the path used for the template (#{full_path.inspect}) is not in the allowed paths (#{render_opts[:allowed_paths].inspect}). Allowing the template render anyway for backwards compatibility, but an error will be raised starting in Roda 3. Specify the :allowed_paths render plugin option to include the path, or use the :check_paths=>false render plugin option to explicitly disable path checking."
|
|
405
438
|
end
|
|
406
439
|
end
|
|
407
440
|
path
|
|
408
441
|
end
|
|
409
442
|
|
|
443
|
+
# RODA3: Remove
|
|
444
|
+
def render_plugin_handle_locals?
|
|
445
|
+
true
|
|
446
|
+
end
|
|
447
|
+
|
|
410
448
|
# If a layout should be used, return a hash of options for
|
|
411
449
|
# rendering the layout template. If a layout should not be
|
|
412
450
|
# used, return nil.
|
|
413
451
|
def view_layout_opts(opts)
|
|
414
452
|
if layout = opts.fetch(:layout, render_opts[:layout])
|
|
415
|
-
|
|
416
453
|
layout_opts = render_layout_opts
|
|
454
|
+
|
|
455
|
+
# RODA3: Remove
|
|
417
456
|
merge_locals = layout_opts[:merge_locals]
|
|
418
457
|
|
|
419
|
-
|
|
420
|
-
method_layout_locals = method_layout_opts[:locals]
|
|
421
|
-
merge_locals = method_layout_opts[:merge_locals] if method_layout_opts.has_key?(:merge_locals)
|
|
422
|
-
end
|
|
458
|
+
method_layout_opts = opts[:layout_opts]
|
|
423
459
|
|
|
424
|
-
|
|
425
|
-
if
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
locals
|
|
460
|
+
# RODA3: Remove
|
|
461
|
+
if render_plugin_handle_locals?
|
|
462
|
+
if method_layout_opts
|
|
463
|
+
method_layout_locals = method_layout_opts[:locals]
|
|
464
|
+
if method_layout_opts.has_key?(:merge_locals)
|
|
465
|
+
RodaPlugins.warn "The :layout_opts=>:merge_locals view option is deprecated and will be removed in Roda 3. You can use the render_locals plugin for merging locals."
|
|
466
|
+
merge_locals = method_layout_opts[:merge_locals]
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
locals = {}
|
|
471
|
+
if merge_locals && (plugin_locals = render_opts[:locals])
|
|
472
|
+
locals.merge!(plugin_locals)
|
|
473
|
+
end
|
|
474
|
+
if layout_locals = layout_opts[:locals]
|
|
475
|
+
locals.merge!(layout_locals)
|
|
476
|
+
end
|
|
477
|
+
if merge_locals && (method_locals = opts[:locals])
|
|
478
|
+
locals.merge!(method_locals)
|
|
479
|
+
end
|
|
480
|
+
if method_layout_locals
|
|
481
|
+
locals.merge!(method_layout_locals)
|
|
482
|
+
end
|
|
436
483
|
end
|
|
437
484
|
|
|
438
485
|
layout_opts.merge!(method_layout_opts) if method_layout_opts
|
|
439
|
-
|
|
486
|
+
|
|
487
|
+
# RODA3: Remove
|
|
488
|
+
layout_opts[:locals] = locals if render_plugin_handle_locals? && !locals.empty?
|
|
440
489
|
|
|
441
490
|
case layout
|
|
442
491
|
when Hash
|
|
@@ -27,6 +27,7 @@ class Roda
|
|
|
27
27
|
# not set a local variable inside the template.
|
|
28
28
|
module RenderEach
|
|
29
29
|
OPTS = {}.freeze
|
|
30
|
+
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
30
31
|
|
|
31
32
|
# Load the render plugin before this plugin, since this plugin
|
|
32
33
|
# calls the render method.
|
|
@@ -41,7 +42,7 @@ class Roda
|
|
|
41
42
|
# :local :: The local variable to use for the current enum value
|
|
42
43
|
# inside the template. An explicit +nil+ value does not
|
|
43
44
|
# set a local variable. If not set, uses the template name.
|
|
44
|
-
def render_each(enum, template, opts=OPTS)
|
|
45
|
+
def render_each(enum, template, opts=RodaPlugins::OPTS)
|
|
45
46
|
if as = opts.has_key?(:local)
|
|
46
47
|
as = opts[:local]
|
|
47
48
|
else
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
class Roda
|
|
5
|
+
module RodaPlugins
|
|
6
|
+
# The render_locals plugin allows setting default locals for rendering templates.
|
|
7
|
+
#
|
|
8
|
+
# plugin :render_locals, :render=>{:heading=>'Hello'}
|
|
9
|
+
#
|
|
10
|
+
# route do |r|
|
|
11
|
+
# r.get "foo" do
|
|
12
|
+
# view 'foo', :locals=>{:name=>'Foo'} # locals: {:heading=>'Hello', :name=>'Foo'}
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# r.get "bar" do
|
|
16
|
+
# view 'foo', :locals=>{:heading=>'Bar'} # locals: {:heading=>'Bar'}
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# view "default" # locals: {:heading=>'Hello'}
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# The render_locals plugin accepts the following options:
|
|
23
|
+
#
|
|
24
|
+
# render :: The default locals to use for template rendering
|
|
25
|
+
# layout :: The default locals to use for layout rendering
|
|
26
|
+
# merge :: Whether to merge template locals into layout locals
|
|
27
|
+
module RenderLocals
|
|
28
|
+
OPTS = {}.freeze
|
|
29
|
+
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
30
|
+
|
|
31
|
+
def self.load_dependencies(app, opts=RodaPlugins::OPTS)
|
|
32
|
+
app.plugin :render
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.configure(app, opts=RodaPlugins::OPTS)
|
|
36
|
+
app.opts[:render_locals] = (app.opts[:render_locals] || {}).merge(opts[:render]||{}).freeze
|
|
37
|
+
app.opts[:layout_locals] = (app.opts[:layout_locals] || {}).merge(opts[:layout]||{}).freeze
|
|
38
|
+
if opts.has_key?(:merge)
|
|
39
|
+
app.opts[:merge_locals] = opts[:merge]
|
|
40
|
+
app.opts[:layout_locals] = app.opts[:render_locals].merge(app.opts[:layout_locals]).freeze
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
module InstanceMethods
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def render_locals
|
|
48
|
+
opts[:render_locals]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def layout_locals
|
|
52
|
+
opts[:layout_locals]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# RODA3: Remove
|
|
56
|
+
def render_plugin_handle_locals?
|
|
57
|
+
false
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# If this isn't the layout template, then use the plugin's render locals as the default locals.
|
|
61
|
+
def render_template_opts(template, opts)
|
|
62
|
+
opts = super
|
|
63
|
+
return opts if opts[:_is_layout]
|
|
64
|
+
|
|
65
|
+
plugin_locals = render_locals
|
|
66
|
+
if locals = opts[:locals]
|
|
67
|
+
plugin_locals = Hash[plugin_locals].merge!(locals)
|
|
68
|
+
end
|
|
69
|
+
opts[:locals] = plugin_locals
|
|
70
|
+
opts
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# If using a layout, then use the plugin's layout locals as the default locals.
|
|
74
|
+
def view_layout_opts(opts)
|
|
75
|
+
if layout_opts = super
|
|
76
|
+
merge_locals = layout_opts.has_key?(:merge_locals) ? layout_opts[:merge_locals] : self.opts[:merge_locals]
|
|
77
|
+
|
|
78
|
+
locals = {}
|
|
79
|
+
if merge_locals && (plugin_locals = render_locals)
|
|
80
|
+
locals.merge!(plugin_locals)
|
|
81
|
+
end
|
|
82
|
+
if layout_locals = layout_locals()
|
|
83
|
+
locals.merge!(layout_locals)
|
|
84
|
+
end
|
|
85
|
+
if merge_locals && (method_locals = opts[:locals])
|
|
86
|
+
locals.merge!(method_locals)
|
|
87
|
+
end
|
|
88
|
+
if method_layout_locals = layout_opts[:locals]
|
|
89
|
+
locals.merge!(method_layout_locals)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
layout_opts[:locals] = locals
|
|
93
|
+
layout_opts[:_is_layout] = true
|
|
94
|
+
layout_opts
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
register_plugin(:render_locals, RenderLocals)
|
|
101
|
+
end
|
|
102
|
+
end
|