roda 3.89.0 → 3.91.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/lib/roda/plugins/capture_erb.rb +43 -3
- data/lib/roda/plugins/common_logger.rb +4 -3
- data/lib/roda/plugins/middleware.rb +1 -3
- data/lib/roda/plugins/module_include.rb +1 -0
- data/lib/roda/plugins/render_each.rb +60 -12
- data/lib/roda/plugins/sinatra_helpers.rb +1 -3
- data/lib/roda/plugins.rb +15 -0
- data/lib/roda/session_middleware.rb +1 -0
- data/lib/roda/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e89aa3dd4e7c27d33d8b989c87a661a42e28c771aa8c96109279cc8131a4c5f5
|
4
|
+
data.tar.gz: e54282de7adf4827dcda2e29c82bbec6d8d76bbbefe29185d3d35b92f3390a50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a403baf3ca83c6e636c59c1a598319aa41254ad8bffb6e18ba0f81eebf1260674c30f3954b471da60be605d397496d0c2bb96ff286d5e094ea17a4745dc67f82
|
7
|
+
data.tar.gz: 2caeb451da13d935c1e14e7009304a16e256942926237704cd80baf32f9fa9d534b58830d8d4092cefec4940cc40fe90e01b33152183d43877900d479135e710
|
@@ -21,26 +21,66 @@ class Roda
|
|
21
21
|
# used as the template engine), this will call +capture+ on the
|
22
22
|
# output buffer object, instead of setting the output buffer object
|
23
23
|
# temporarily to a new object.
|
24
|
+
#
|
25
|
+
# By default, capture_erb returns the value of the block, converted
|
26
|
+
# to a string. However, that can cause issues with code such as:
|
27
|
+
#
|
28
|
+
# <% value = capture_erb do %>
|
29
|
+
# Some content here.
|
30
|
+
# <% if something %>
|
31
|
+
# Some more content here.
|
32
|
+
# <% end %>
|
33
|
+
# <% end %>
|
34
|
+
#
|
35
|
+
# In this case, the block may return nil, instead of the content of
|
36
|
+
# the template. To handle this case, you can provide the
|
37
|
+
# <tt>returns: :buffer</tt> option when calling the method (to handle
|
38
|
+
# that specific call, or when loading the plugin (to default to that
|
39
|
+
# behavior). Note that if the output buffer object responds to
|
40
|
+
# +capture+ and is not an instance of String, the <tt>returns: :buffer</tt>
|
41
|
+
# behavior is the default and cannot be changed.
|
24
42
|
module CaptureERB
|
25
|
-
def self.load_dependencies(app)
|
43
|
+
def self.load_dependencies(app, opts=OPTS)
|
26
44
|
app.plugin :render
|
27
45
|
end
|
28
46
|
|
47
|
+
# Support <tt>returns: :buffer</tt> to default to returning buffer
|
48
|
+
# object.
|
49
|
+
def self.configure(app, opts=OPTS)
|
50
|
+
# RODA4: make returns: :buffer the default behavior
|
51
|
+
app.opts[:capture_erb_returns] = opts[:returns] if opts.has_key?(:returns)
|
52
|
+
end
|
53
|
+
|
29
54
|
module InstanceMethods
|
30
55
|
# Temporarily replace the ERB output buffer
|
31
56
|
# with an empty string, and then yield to the block.
|
32
57
|
# Return the value of the block, converted to a string.
|
33
58
|
# Restore the previous ERB output buffer before returning.
|
34
|
-
|
59
|
+
#
|
60
|
+
# Options:
|
61
|
+
# :returns :: If set to :buffer, returns the value of the
|
62
|
+
# template output variable, instead of the return
|
63
|
+
# value of the block converted to a string. This
|
64
|
+
# is the default behavior if the template output
|
65
|
+
# variable supports the +capture+ method and is not
|
66
|
+
# a String instance.
|
67
|
+
def capture_erb(opts=OPTS, &block)
|
35
68
|
outvar = render_opts[:template_opts][:outvar]
|
36
69
|
buf_was = instance_variable_get(outvar)
|
37
70
|
|
38
71
|
if buf_was.respond_to?(:capture) && !buf_was.instance_of?(String)
|
39
72
|
buf_was.capture(&block)
|
40
73
|
else
|
74
|
+
returns = opts.fetch(:returns) { self.opts[:capture_erb_returns] }
|
75
|
+
|
41
76
|
begin
|
42
77
|
instance_variable_set(outvar, String.new)
|
43
|
-
|
78
|
+
if returns == :buffer
|
79
|
+
yield
|
80
|
+
instance_variable_get(outvar).to_s
|
81
|
+
else
|
82
|
+
yield.to_s
|
83
|
+
end
|
44
84
|
ensure
|
45
85
|
instance_variable_set(outvar, buf_was) if outvar && buf_was
|
46
86
|
end
|
@@ -56,14 +56,15 @@ class Roda
|
|
56
56
|
|
57
57
|
env = @_request.env
|
58
58
|
|
59
|
-
line = "#{env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-"} - #{env["REMOTE_USER"] || "-"} [#{Time.now.strftime("%d/%b/%Y:%H:%M:%S %z")}] \"#{env["REQUEST_METHOD"]} #{env["SCRIPT_NAME"]}#{env["PATH_INFO"]}#{"?#{env["QUERY_STRING"]}" if ((qs = env["QUERY_STRING"]) && !qs.empty?)} #{@_request.http_version}\" #{status} #{((length = headers[RodaResponseHeaders::CONTENT_LENGTH]) && (length unless length == '0')) || '-'} #{elapsed_time}
|
59
|
+
line = "#{env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-"} - #{env["REMOTE_USER"] || "-"} [#{Time.now.strftime("%d/%b/%Y:%H:%M:%S %z")}] \"#{env["REQUEST_METHOD"]} #{env["SCRIPT_NAME"]}#{env["PATH_INFO"]}#{"?#{env["QUERY_STRING"]}" if ((qs = env["QUERY_STRING"]) && !qs.empty?)} #{@_request.http_version}\" #{status} #{((length = headers[RodaResponseHeaders::CONTENT_LENGTH]) && (length unless length == '0')) || '-'} #{elapsed_time} "
|
60
60
|
if MUTATE_LINE
|
61
|
-
line.gsub!(/[^[:print:]
|
61
|
+
line.gsub!(/[^[:print:]]/){|c| sprintf("\\x%x", c.ord)}
|
62
62
|
# :nocov:
|
63
63
|
else
|
64
|
-
line = line.gsub(/[^[:print:]
|
64
|
+
line = line.gsub(/[^[:print:]]/){|c| sprintf("\\x%x", c.ord)}
|
65
65
|
# :nocov:
|
66
66
|
end
|
67
|
+
line[-1] = "\n"
|
67
68
|
opts[:common_logger_meth].call(line)
|
68
69
|
end
|
69
70
|
|
@@ -134,9 +134,7 @@ class Roda
|
|
134
134
|
# and store +app+ as the next middleware to call.
|
135
135
|
def initialize(mid, app, *args, &block)
|
136
136
|
@mid = Class.new(mid)
|
137
|
-
#
|
138
|
-
@mid.set_temporary_name("#{mid.name}(middleware)") if mid.name && RUBY_VERSION >= "3.3"
|
139
|
-
# :nocov:
|
137
|
+
RodaPlugins.set_temp_name(@mid){"#{mid}::middleware_subclass"}
|
140
138
|
if @mid.opts[:middleware_next_if_not_found]
|
141
139
|
@mid.plugin(:not_found, &NEXT_PROC)
|
142
140
|
end
|
@@ -15,6 +15,38 @@ class Roda
|
|
15
15
|
# is rendered, the local variable +foo+ will contain the given
|
16
16
|
# value (e.g. on the first rendering +foo+ is 1).
|
17
17
|
#
|
18
|
+
# If you provide a block when calling the method, it will yield
|
19
|
+
# each rendering instead of returning a concatentation of the
|
20
|
+
# renderings. This is useful if you want to wrap each rendering in
|
21
|
+
# something else. For example, instead of calling +render+ multiple
|
22
|
+
# times in a loop:
|
23
|
+
#
|
24
|
+
# <% [1,2,3].each do |v| %>
|
25
|
+
# <p><%= render(:foo, locals: {foo: v}) %></p>
|
26
|
+
# <% end %>
|
27
|
+
#
|
28
|
+
# You can use +render_each+, allowing for simpler and more optimized
|
29
|
+
# code:
|
30
|
+
#
|
31
|
+
# <% render_each([1,2,3], :foo) do |text| %>
|
32
|
+
# <p><%= text %></p>
|
33
|
+
# <% end %>
|
34
|
+
#
|
35
|
+
# You can also provide a block to avoid excess memory usage. For
|
36
|
+
# example, if you are calling the method inside an erb template,
|
37
|
+
# instead of doing:
|
38
|
+
#
|
39
|
+
# <%= render_each([1,2,3], :foo) %>
|
40
|
+
#
|
41
|
+
# You can do:
|
42
|
+
#
|
43
|
+
# <% render_each([1,2,3], :foo) %><%= body %><% end %>
|
44
|
+
#
|
45
|
+
# This results in the same behavior, but avoids building a large
|
46
|
+
# intermediate string just to concatenate to the template result.
|
47
|
+
#
|
48
|
+
# When passing a block, +render_each+ returns +nil+.
|
49
|
+
#
|
18
50
|
# You can pass additional render options via an options hash:
|
19
51
|
#
|
20
52
|
# render_each([1,2,3], :foo, views: 'partials')
|
@@ -45,15 +77,15 @@ class Roda
|
|
45
77
|
# :local :: The local variable to use for the current enum value
|
46
78
|
# inside the template. An explicit +nil+ value does not
|
47
79
|
# set a local variable. If not set, uses the template name.
|
48
|
-
def render_each(enum, template, opts=(no_opts = true; optimized_template = _cached_render_each_template_method(template); OPTS))
|
80
|
+
def render_each(enum, template, opts=(no_opts = true; optimized_template = _cached_render_each_template_method(template); OPTS), &block)
|
49
81
|
if optimized_template
|
50
|
-
return _optimized_render_each(enum, optimized_template, render_each_default_local(template), {})
|
82
|
+
return _optimized_render_each(enum, optimized_template, render_each_default_local(template), {}, &block)
|
51
83
|
elsif opts.has_key?(:local)
|
52
84
|
as = opts[:local]
|
53
85
|
else
|
54
86
|
as = render_each_default_local(template)
|
55
87
|
if no_opts && optimized_template.nil? && (optimized_template = _optimized_render_method_for_locals(template, (locals = {as=>nil})))
|
56
|
-
return _optimized_render_each(enum, optimized_template, as, locals)
|
88
|
+
return _optimized_render_each(enum, optimized_template, as, locals, &block)
|
57
89
|
end
|
58
90
|
end
|
59
91
|
|
@@ -67,14 +99,22 @@ class Roda
|
|
67
99
|
locals[as] = nil
|
68
100
|
|
69
101
|
if (opts.keys - ALLOWED_KEYS).empty? && (optimized_template = _optimized_render_method_for_locals(template, locals))
|
70
|
-
return _optimized_render_each(enum, optimized_template, as, locals)
|
102
|
+
return _optimized_render_each(enum, optimized_template, as, locals, &block)
|
71
103
|
end
|
72
104
|
end
|
73
105
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
106
|
+
if defined?(yield)
|
107
|
+
enum.each do |v|
|
108
|
+
locals[as] = v if as
|
109
|
+
yield render_template(template, opts)
|
110
|
+
end
|
111
|
+
nil
|
112
|
+
else
|
113
|
+
enum.map do |v|
|
114
|
+
locals[as] = v if as
|
115
|
+
render_template(template, opts)
|
116
|
+
end.join
|
117
|
+
end
|
78
118
|
end
|
79
119
|
|
80
120
|
private
|
@@ -103,10 +143,18 @@ class Roda
|
|
103
143
|
|
104
144
|
# Use an optimized render for each value in the enum.
|
105
145
|
def _optimized_render_each(enum, optimized_template, as, locals)
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
146
|
+
if defined?(yield)
|
147
|
+
enum.each do |v|
|
148
|
+
locals[as] = v
|
149
|
+
yield _call_optimized_template_method(optimized_template, locals)
|
150
|
+
end
|
151
|
+
nil
|
152
|
+
else
|
153
|
+
enum.map do |v|
|
154
|
+
locals[as] = v
|
155
|
+
_call_optimized_template_method(optimized_template, locals)
|
156
|
+
end.join
|
157
|
+
end
|
110
158
|
end
|
111
159
|
else
|
112
160
|
def _cached_render_each_template_method(template)
|
@@ -354,9 +354,7 @@ class Roda
|
|
354
354
|
res.status = opts[:status] || s
|
355
355
|
headers.delete(RodaResponseHeaders::CONTENT_LENGTH)
|
356
356
|
headers.replace(h.merge!(headers))
|
357
|
-
res.
|
358
|
-
|
359
|
-
halt
|
357
|
+
halt res.finish_with_body(b)
|
360
358
|
rescue Errno::ENOENT
|
361
359
|
not_found
|
362
360
|
end
|
data/lib/roda/plugins.rb
CHANGED
@@ -49,5 +49,20 @@ class Roda
|
|
49
49
|
end
|
50
50
|
# :nocov:
|
51
51
|
end
|
52
|
+
|
53
|
+
if RUBY_VERSION >= '3.3'
|
54
|
+
# Create a new module using the block, and set the temporary name
|
55
|
+
# on it using the given a containing module and name.
|
56
|
+
def self.set_temp_name(mod)
|
57
|
+
mod.set_temporary_name(yield)
|
58
|
+
mod
|
59
|
+
end
|
60
|
+
# :nocov:
|
61
|
+
else
|
62
|
+
def self.set_temp_name(mod)
|
63
|
+
mod
|
64
|
+
end
|
65
|
+
end
|
66
|
+
# :nocov:
|
52
67
|
end
|
53
68
|
end
|
@@ -159,6 +159,7 @@ class RodaSessionMiddleware
|
|
159
159
|
# Setup the middleware, passing +opts+ as the Roda sessions plugin options.
|
160
160
|
def initialize(app, opts)
|
161
161
|
mid = Class.new(Roda)
|
162
|
+
Roda::RodaPlugins.set_temp_name(mid){"RodaSessionMiddleware::_RodaSubclass"}
|
162
163
|
mid.plugin :sessions, opts
|
163
164
|
@req_class = mid::RodaRequest
|
164
165
|
@req_class.send(:include, RequestMethods)
|
data/lib/roda/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.91.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-04-11 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rack
|