roda 2.29.0 → 3.0.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 +52 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +51 -109
- data/Rakefile +7 -14
- data/doc/conventions.rdoc +4 -4
- data/doc/release_notes/1.2.0.txt +1 -1
- data/doc/release_notes/3.0.0.txt +84 -0
- data/lib/roda.rb +25 -79
- data/lib/roda/plugins/assets.rb +25 -58
- data/lib/roda/plugins/assets_preloading.rb +0 -5
- data/lib/roda/plugins/backtracking_array.rb +0 -5
- data/lib/roda/plugins/branch_locals.rb +3 -3
- data/lib/roda/plugins/caching.rb +5 -38
- data/lib/roda/plugins/chunked.rb +7 -25
- data/lib/roda/plugins/class_level_routing.rb +2 -2
- data/lib/roda/plugins/content_for.rb +7 -10
- data/lib/roda/plugins/cookies.rb +3 -3
- data/lib/roda/plugins/csrf.rb +2 -2
- data/lib/roda/plugins/delegate.rb +3 -3
- data/lib/roda/plugins/drop_body.rb +0 -7
- data/lib/roda/plugins/empty_root.rb +0 -3
- data/lib/roda/plugins/error_email.rb +4 -6
- data/lib/roda/plugins/error_handler.rb +1 -2
- data/lib/roda/plugins/error_mail.rb +3 -6
- data/lib/roda/plugins/flash.rb +0 -4
- data/lib/roda/plugins/h.rb +5 -0
- data/lib/roda/plugins/hash_matcher.rb +4 -2
- data/lib/roda/plugins/head.rb +5 -7
- data/lib/roda/plugins/header_matchers.rb +12 -33
- data/lib/roda/plugins/heartbeat.rb +2 -7
- data/lib/roda/plugins/indifferent_params.rb +2 -2
- data/lib/roda/plugins/json.rb +6 -14
- data/lib/roda/plugins/json_parser.rb +2 -13
- data/lib/roda/plugins/mailer.rb +29 -39
- data/lib/roda/plugins/match_affix.rb +0 -5
- data/lib/roda/plugins/middleware.rb +10 -15
- data/lib/roda/plugins/multi_route.rb +8 -5
- data/lib/roda/plugins/multi_run.rb +1 -0
- data/lib/roda/plugins/named_templates.rb +2 -2
- data/lib/roda/plugins/optimized_string_matchers.rb +0 -3
- data/lib/roda/plugins/padrino_render.rb +6 -9
- data/lib/roda/plugins/param_matchers.rb +6 -6
- data/lib/roda/plugins/params_capturing.rb +15 -35
- data/lib/roda/plugins/partials.rb +3 -8
- data/lib/roda/plugins/path.rb +5 -5
- data/lib/roda/plugins/path_matchers.rb +3 -3
- data/lib/roda/plugins/path_rewriter.rb +4 -9
- data/lib/roda/plugins/placeholder_string_matchers.rb +1 -1
- data/lib/roda/plugins/precompile_templates.rb +10 -20
- data/lib/roda/plugins/public.rb +6 -9
- data/lib/roda/plugins/render.rb +50 -171
- data/lib/roda/plugins/render_each.rb +4 -7
- data/lib/roda/plugins/render_locals.rb +6 -20
- data/lib/roda/plugins/request_headers.rb +2 -4
- data/lib/roda/plugins/run_append_slash.rb +1 -4
- data/lib/roda/plugins/run_handler.rb +4 -7
- data/lib/roda/plugins/shared_vars.rb +3 -6
- data/lib/roda/plugins/sinatra_helpers.rb +11 -40
- data/lib/roda/plugins/slash_path_empty.rb +0 -3
- data/lib/roda/plugins/static.rb +2 -2
- data/lib/roda/plugins/static_routing.rb +2 -3
- data/lib/roda/plugins/streaming.rb +15 -108
- data/lib/roda/plugins/strip_path_prefix.rb +1 -1
- data/lib/roda/plugins/symbol_matchers.rb +7 -23
- data/lib/roda/plugins/type_routing.rb +4 -9
- data/lib/roda/plugins/view_options.rb +10 -66
- data/lib/roda/version.rb +2 -2
- data/spec/all.rb +0 -2
- data/spec/composition_spec.rb +1 -1
- data/spec/env_spec.rb +1 -1
- data/spec/freeze_spec.rb +1 -1
- data/spec/integration_spec.rb +1 -1
- data/spec/matchers_spec.rb +26 -70
- data/spec/opts_spec.rb +1 -1
- data/spec/plugin/all_verbs_spec.rb +1 -1
- data/spec/plugin/assets_preloading_spec.rb +1 -1
- data/spec/plugin/assets_spec.rb +43 -27
- data/spec/plugin/backtracking_array_spec.rb +1 -1
- data/spec/plugin/branch_locals_spec.rb +1 -1
- data/spec/plugin/caching_spec.rb +1 -1
- data/spec/plugin/chunked_spec.rb +1 -1
- data/spec/plugin/class_level_routing_spec.rb +1 -1
- data/spec/plugin/class_matchers_spec.rb +1 -1
- data/spec/plugin/content_for_spec.rb +2 -7
- data/spec/plugin/cookies_spec.rb +1 -1
- data/spec/plugin/csrf_spec.rb +1 -1
- data/spec/plugin/default_headers_spec.rb +1 -1
- data/spec/plugin/default_status_spec.rb +1 -1
- data/spec/plugin/delay_build_spec.rb +1 -1
- data/spec/plugin/delegate_spec.rb +1 -1
- data/spec/plugin/delete_empty_headers_spec.rb +1 -1
- data/spec/plugin/disallow_file_uploads_spec.rb +2 -2
- data/spec/plugin/drop_body_spec.rb +1 -1
- data/spec/plugin/empty_root_spec.rb +1 -1
- data/spec/plugin/environments_spec.rb +1 -1
- data/spec/plugin/error_email_spec.rb +1 -1
- data/spec/plugin/error_handler_spec.rb +1 -1
- data/spec/plugin/error_mail_spec.rb +2 -2
- data/spec/plugin/flash_spec.rb +1 -1
- data/spec/plugin/h_spec.rb +1 -1
- data/spec/plugin/halt_spec.rb +2 -2
- data/spec/plugin/hash_matcher_spec.rb +1 -1
- data/spec/plugin/head_spec.rb +1 -1
- data/spec/plugin/header_matchers_spec.rb +4 -47
- data/spec/plugin/heartbeat_spec.rb +1 -1
- data/spec/plugin/hooks_spec.rb +1 -1
- data/spec/plugin/indifferent_params_spec.rb +1 -1
- data/spec/plugin/json_parser_spec.rb +12 -1
- data/spec/plugin/json_spec.rb +8 -1
- data/spec/plugin/mailer_spec.rb +1 -1
- data/spec/plugin/match_affix_spec.rb +1 -1
- data/spec/plugin/middleware_spec.rb +15 -1
- data/spec/plugin/module_include_spec.rb +1 -1
- data/spec/plugin/multi_route_spec.rb +5 -3
- data/spec/plugin/multi_run_spec.rb +1 -1
- data/spec/plugin/multi_view_spec.rb +1 -1
- data/spec/plugin/named_templates_spec.rb +1 -1
- data/spec/plugin/not_allowed_spec.rb +1 -1
- data/spec/plugin/not_found_spec.rb +1 -1
- data/spec/plugin/optimized_string_matchers_spec.rb +1 -1
- data/spec/plugin/padrino_render_spec.rb +1 -1
- data/spec/plugin/param_matchers_spec.rb +1 -1
- data/spec/plugin/params_capturing_spec.rb +6 -22
- data/spec/plugin/partials_spec.rb +1 -1
- data/spec/plugin/pass_spec.rb +1 -1
- data/spec/plugin/path_matchers_spec.rb +1 -1
- data/spec/plugin/path_rewriter_spec.rb +1 -1
- data/spec/plugin/path_spec.rb +1 -1
- data/spec/plugin/placeholder_string_matchers_spec.rb +3 -36
- data/spec/plugin/precompile_templates_spec.rb +1 -17
- data/spec/plugin/public_spec.rb +3 -4
- data/spec/plugin/render_each_spec.rb +1 -1
- data/spec/plugin/render_locals_spec.rb +1 -1
- data/spec/plugin/render_spec.rb +28 -114
- data/spec/plugin/request_headers_spec.rb +1 -1
- data/spec/plugin/response_request_spec.rb +1 -1
- data/spec/plugin/run_append_slash_spec.rb +1 -1
- data/spec/plugin/run_handler_spec.rb +1 -1
- data/spec/plugin/shared_vars_spec.rb +1 -1
- data/spec/plugin/sinatra_helpers_spec.rb +1 -1
- data/spec/plugin/slash_path_empty_spec.rb +1 -1
- data/spec/plugin/static_routing_spec.rb +1 -1
- data/spec/plugin/static_spec.rb +1 -1
- data/spec/plugin/status_303_spec.rb +1 -1
- data/spec/plugin/status_handler_spec.rb +1 -1
- data/spec/plugin/streaming_spec.rb +1 -106
- data/spec/plugin/strip_path_prefix_spec.rb +1 -1
- data/spec/plugin/symbol_matchers_spec.rb +1 -77
- data/spec/plugin/symbol_status_spec.rb +1 -1
- data/spec/plugin/symbol_views_spec.rb +1 -1
- data/spec/plugin/type_routing_spec.rb +1 -1
- data/spec/plugin/unescape_path_spec.rb +1 -1
- data/spec/plugin/view_options_spec.rb +16 -110
- data/spec/plugin_spec.rb +1 -1
- data/spec/redirect_spec.rb +1 -1
- data/spec/request_spec.rb +1 -1
- data/spec/response_spec.rb +1 -1
- data/spec/session_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -3
- data/spec/version_spec.rb +1 -1
- metadata +6 -26
- data/lib/roda/plugins/_erubis_escaping.rb +0 -59
- data/lib/roda/plugins/per_thread_caching.rb +0 -71
- data/lib/roda/plugins/static_path_info.rb +0 -12
- data/lib/roda/plugins/view_subdirs.rb +0 -7
- data/lib/roda/plugins/websockets.rb +0 -107
- data/spec/plugin/_erubis_escaping_spec.rb +0 -97
- data/spec/plugin/per_thread_caching_spec.rb +0 -28
- data/spec/plugin/websockets_spec.rb +0 -84
|
@@ -17,7 +17,7 @@ class Roda
|
|
|
17
17
|
# end
|
|
18
18
|
#
|
|
19
19
|
# It is not recommended to use this in new applications, and it is encouraged
|
|
20
|
-
# to use separate
|
|
20
|
+
# to use separate string class or symbol matchers instead:
|
|
21
21
|
#
|
|
22
22
|
# r.is "foo", String
|
|
23
23
|
# r.is "foo", :bar
|
|
@@ -25,16 +25,10 @@ class Roda
|
|
|
25
25
|
# If the templates use local variables, you need to specify which local
|
|
26
26
|
# variables to precompile, which should be an array of symbols:
|
|
27
27
|
#
|
|
28
|
-
# precompile_templates 'views/users/_*.erb', :
|
|
28
|
+
# precompile_templates 'views/users/_*.erb', locals: [:user]
|
|
29
29
|
#
|
|
30
|
-
# Note that
|
|
31
|
-
#
|
|
32
|
-
# same order as the keys in the :locals hash you pass to render/view. Since
|
|
33
|
-
# hashes are not ordered in ruby 1.8, you should not attempt to precompile
|
|
34
|
-
# templates that use :locals on ruby 1.8 unless you are using a Tilt version
|
|
35
|
-
# greater than 2.0.1. If you are running the Tilt master branch, you can
|
|
36
|
-
# force sorting of locals using the +:sort_locals+ option when loading the
|
|
37
|
-
# plugin.
|
|
30
|
+
# Note that you should use Tilt 2.0.1+ if you are using this plugin, so
|
|
31
|
+
# that locals are handled in the same order.
|
|
38
32
|
#
|
|
39
33
|
# You can specify other render options when calling +precompile_templates+,
|
|
40
34
|
# including +:cache_key+, +:template_class+, and +:template_opts+. If you
|
|
@@ -44,29 +38,25 @@ class Roda
|
|
|
44
38
|
# To compile inline templates, just pass a single hash containing an :inline
|
|
45
39
|
# to +precompile_templates+:
|
|
46
40
|
#
|
|
47
|
-
# precompile_templates :
|
|
41
|
+
# precompile_templates inline: some_template_string
|
|
48
42
|
module PrecompileTemplates
|
|
49
|
-
OPTS = {}.freeze
|
|
50
|
-
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
51
|
-
|
|
52
43
|
# Load the render plugin as precompile_templates depends on it.
|
|
53
|
-
|
|
54
|
-
def self.load_dependencies(app, opts=RodaPlugins::OPTS)
|
|
44
|
+
def self.load_dependencies(app, opts=OPTS)
|
|
55
45
|
app.plugin :render
|
|
56
|
-
app.opts[:precompile_templates_sort] = opts.fetch(:sort_locals, Tilt::VERSION > '2.0.1')
|
|
57
46
|
end
|
|
58
47
|
|
|
59
48
|
module ClassMethods
|
|
60
49
|
# Precompile the templates using the given options. See PrecompileTemplates
|
|
61
50
|
# for details.
|
|
62
|
-
def precompile_templates(pattern, opts=
|
|
51
|
+
def precompile_templates(pattern, opts=OPTS)
|
|
63
52
|
if pattern.is_a?(Hash)
|
|
64
53
|
opts = pattern.merge(opts)
|
|
65
54
|
end
|
|
66
55
|
|
|
67
|
-
locals = opts[:locals]
|
|
68
|
-
|
|
69
|
-
|
|
56
|
+
if locals = opts[:locals]
|
|
57
|
+
locals.sort!
|
|
58
|
+
else
|
|
59
|
+
locals = EMPTY_ARRAY
|
|
70
60
|
end
|
|
71
61
|
|
|
72
62
|
compile_opts = if pattern.is_a?(Hash)
|
data/lib/roda/plugins/public.rb
CHANGED
|
@@ -10,7 +10,7 @@ class Roda
|
|
|
10
10
|
#
|
|
11
11
|
# The public plugin recognizes the application's :root option, and defaults to
|
|
12
12
|
# using the +public+ subfolder of the application's +:root+ option. If the application's
|
|
13
|
-
# :root option is not set, it defaults to the
|
|
13
|
+
# :root option is not set, it defaults to the +public+ folder in the working
|
|
14
14
|
# directory. Additionally, if a relative path is provided as the :root
|
|
15
15
|
# option to the plugin, it will be considered relative to the application's
|
|
16
16
|
# +:root+ option.
|
|
@@ -19,13 +19,10 @@ class Roda
|
|
|
19
19
|
#
|
|
20
20
|
# opts[:root] = '/path/to/app'
|
|
21
21
|
# plugin :public
|
|
22
|
-
# plugin :public, :
|
|
22
|
+
# plugin :public, root: 'static'
|
|
23
23
|
module Public
|
|
24
24
|
SPLIT = Regexp.union(*[File::SEPARATOR, File::ALT_SEPARATOR].compact)
|
|
25
|
-
PARSER =
|
|
26
|
-
|
|
27
|
-
NULL_BYTE = "\0".freeze
|
|
28
|
-
RodaPlugins.deprecate_constant(self, :NULL_BYTE)
|
|
25
|
+
PARSER = URI::DEFAULT_PARSER
|
|
29
26
|
|
|
30
27
|
# Use options given to setup a Rack::File instance for serving files. Options:
|
|
31
28
|
# :default_mime :: The default mime type to use if the mime type is not recognized.
|
|
@@ -97,18 +94,18 @@ class Roda
|
|
|
97
94
|
end
|
|
98
95
|
|
|
99
96
|
if ::Rack.release > '2'
|
|
100
|
-
#
|
|
97
|
+
# Serve the given path using the given Rack::File server.
|
|
101
98
|
def public_serve(server, path)
|
|
102
99
|
server.serving(self, path)
|
|
103
100
|
end
|
|
104
|
-
# :nocov:
|
|
105
101
|
else
|
|
106
|
-
#
|
|
102
|
+
# :nocov:
|
|
107
103
|
def public_serve(server, path)
|
|
108
104
|
server = server.dup
|
|
109
105
|
server.path = path
|
|
110
106
|
server.serving(env)
|
|
111
107
|
end
|
|
108
|
+
# :nocov:
|
|
112
109
|
end
|
|
113
110
|
end
|
|
114
111
|
end
|
data/lib/roda/plugins/render.rb
CHANGED
|
@@ -24,7 +24,7 @@ class Roda
|
|
|
24
24
|
# side effects (unless the templates themselves have side effects).
|
|
25
25
|
# As Roda uses the routing block return value as the body of the response,
|
|
26
26
|
# in most cases you will call these methods as the last expression in a
|
|
27
|
-
# routing block
|
|
27
|
+
# routing block to have the response body be the result of the template
|
|
28
28
|
# rendering.
|
|
29
29
|
#
|
|
30
30
|
# Because +render+ and +view+ just return strings, you can call them inside
|
|
@@ -33,40 +33,34 @@ class Roda
|
|
|
33
33
|
#
|
|
34
34
|
# route do |r|
|
|
35
35
|
# r.is 'foo-bars' do
|
|
36
|
-
# @bars = Bar.where(:foo).map{|b| render(:bar, :
|
|
36
|
+
# @bars = Bar.where(:foo).map{|b| render(:bar, locals: {bar: b})}.join
|
|
37
37
|
# view('foo')
|
|
38
38
|
# end
|
|
39
39
|
# end
|
|
40
40
|
#
|
|
41
41
|
# You can provide options to the plugin method:
|
|
42
42
|
#
|
|
43
|
-
# plugin :render, :
|
|
43
|
+
# plugin :render, engine: 'haml', views: 'admin_views'
|
|
44
44
|
#
|
|
45
45
|
# = Plugin Options
|
|
46
46
|
#
|
|
47
47
|
# The following plugin options are supported:
|
|
48
48
|
#
|
|
49
|
-
# :allowed_paths :: Set the template paths to allow
|
|
50
|
-
# Defaults to the +:views+ directory.
|
|
51
|
-
# :cache :: nil/false to
|
|
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.
|
|
51
|
+
# :cache :: nil/false to disable template caching by default. By default, caching
|
|
52
|
+
# is disabled by default if RACK_ENV is development.
|
|
52
53
|
# :cache_class :: A class to use as the template cache instead of the default.
|
|
53
|
-
# :check_paths ::
|
|
54
|
-
# and raise a RodaError if the path doesn't.
|
|
54
|
+
# :check_paths :: Can be set to false to turn off template path checking.
|
|
55
55
|
# :engine :: The tilt engine to use for rendering, also the default file extension for
|
|
56
56
|
# templates, defaults to 'erb'.
|
|
57
|
-
# :escape :: Use
|
|
58
|
-
# <tt
|
|
59
|
-
# <tt><%= %></tt> tags. Can have a value of :erubi to use Erubi escaping support.
|
|
60
|
-
# :explicit_cache :: Only use the template cache if the :cache option is provided when rendering
|
|
61
|
-
# (useful for development). Defaults to true if RACK_ENV is development, allowing explicit
|
|
62
|
-
# caching of specific templates, but not caching by default.
|
|
63
|
-
# :inherit_cache :: Whether to create a dup of the cache in subclasses. The default is false, which
|
|
64
|
-
# starts subclasses with an empty cache.
|
|
57
|
+
# :escape :: Use Erubi as the ERB template engine, and enable escaping by default,
|
|
58
|
+
# which makes <tt><%= %></tt> escape output and <tt><%== %></tt> not escape output.
|
|
65
59
|
# :layout :: The base name of the layout file, defaults to 'layout'. This can be provided as a hash
|
|
66
60
|
# with the :template or :inline options.
|
|
67
61
|
# :layout_opts :: The options to use when rendering the layout, if different from the default options.
|
|
68
62
|
# :template_opts :: The tilt options used when rendering all templates. defaults to:
|
|
69
|
-
# <tt>{:
|
|
63
|
+
# <tt>{outvar: '@_out_buf', default_encoding: Encoding.default_external}</tt>.
|
|
70
64
|
# :engine_opts :: The tilt options to use per template engine. Keys are
|
|
71
65
|
# engine strings, values are hashes of template options.
|
|
72
66
|
# :views :: The directory holding the view files, defaults to the 'views' subdirectory of the
|
|
@@ -77,8 +71,8 @@ class Roda
|
|
|
77
71
|
# Most of these options can be overridden at runtime by passing options
|
|
78
72
|
# to the +view+ or +render+ methods:
|
|
79
73
|
#
|
|
80
|
-
# view('foo', :
|
|
81
|
-
# render('foo', :
|
|
74
|
+
# view('foo', engine: 'html.erb')
|
|
75
|
+
# render('foo', views: 'admin_views')
|
|
82
76
|
#
|
|
83
77
|
# There are additional options to +view+ and +render+ that are
|
|
84
78
|
# available at runtime:
|
|
@@ -108,10 +102,10 @@ class Roda
|
|
|
108
102
|
# :template_class :: Provides the template class to use, inside of using
|
|
109
103
|
# Tilt or <tt>Tilt[:engine]</tt>.
|
|
110
104
|
#
|
|
111
|
-
# Here's
|
|
105
|
+
# Here's an example of using these options:
|
|
112
106
|
#
|
|
113
|
-
# view(:
|
|
114
|
-
# render(:
|
|
107
|
+
# view(inline: '<%= @foo %>')
|
|
108
|
+
# render(path: '/path/to/template.erb')
|
|
115
109
|
#
|
|
116
110
|
# If you pass a hash as the first argument to +view+ or +render+, it should
|
|
117
111
|
# have either +:template+, +:inline+, +:path+, or +:content+ (for +view+) as
|
|
@@ -128,7 +122,7 @@ class Roda
|
|
|
128
122
|
# path never uses more than one template, you can use the +view_options+ plugin
|
|
129
123
|
# and do:
|
|
130
124
|
#
|
|
131
|
-
# set_view_options :
|
|
125
|
+
# set_view_options cache_key: r.path_info
|
|
132
126
|
#
|
|
133
127
|
# at the top of your route block. You can even do this if you do have paths
|
|
134
128
|
# that use more than one template, as long as you specify +:cache_key+
|
|
@@ -138,18 +132,8 @@ class Roda
|
|
|
138
132
|
# rendering faster by specifying +:cache_key+ inside the +:layout_opts+
|
|
139
133
|
# plugin option.
|
|
140
134
|
module Render
|
|
141
|
-
OPTS={}.freeze
|
|
142
|
-
RodaPlugins.deprecate_constant(self, :OPTS)
|
|
143
|
-
|
|
144
|
-
# RODA3: Remove
|
|
145
|
-
def self.load_dependencies(app, opts=RodaPlugins::OPTS)
|
|
146
|
-
if opts[:escape] && opts[:escape] != :erubi
|
|
147
|
-
app.plugin :_erubis_escaping
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
135
|
# Setup default rendering options. See Render for details.
|
|
152
|
-
def self.configure(app, opts=
|
|
136
|
+
def self.configure(app, opts=OPTS)
|
|
153
137
|
if app.opts[:render]
|
|
154
138
|
orig_cache = app.opts[:render][:cache]
|
|
155
139
|
opts = app.opts[:render][:orig_opts].merge(opts)
|
|
@@ -158,49 +142,27 @@ class Roda
|
|
|
158
142
|
app.opts[:render][:orig_opts] = opts
|
|
159
143
|
|
|
160
144
|
opts = app.opts[:render]
|
|
161
|
-
|
|
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
|
|
164
|
-
opts[:engine] = (opts[:engine] || opts[:ext] || "erb").dup.freeze
|
|
145
|
+
opts[:engine] = (opts[:engine] || "erb").dup.freeze
|
|
165
146
|
opts[:views] = app.expand_path(opts[:views]||"views").freeze
|
|
166
147
|
opts[:allowed_paths] ||= [opts[:views]].freeze
|
|
167
148
|
opts[:allowed_paths] = opts[:allowed_paths].map{|f| app.expand_path(f, nil)}.uniq.freeze
|
|
149
|
+
opts[:check_paths] = true unless opts.has_key?(:check_paths)
|
|
168
150
|
|
|
169
|
-
|
|
170
|
-
if
|
|
171
|
-
|
|
172
|
-
elsif cache_class = opts[:cache_class]
|
|
173
|
-
opts[:cache] = cache_class.new
|
|
151
|
+
unless opts.has_key?(:explicit_cache)
|
|
152
|
+
opts[:explicit_cache] = if opts.fetch(:cache, true)
|
|
153
|
+
ENV['RACK_ENV'] == 'development'
|
|
174
154
|
else
|
|
175
|
-
|
|
155
|
+
true
|
|
176
156
|
end
|
|
177
157
|
end
|
|
178
158
|
|
|
179
|
-
opts[:
|
|
159
|
+
opts[:cache] = orig_cache || (opts[:cache_class] || RodaCache).new
|
|
180
160
|
|
|
181
161
|
opts[:layout_opts] = (opts[:layout_opts] || {}).dup
|
|
162
|
+
opts[:layout_opts][:_is_layout] = true
|
|
182
163
|
if opts[:layout_opts][:views]
|
|
183
164
|
opts[:layout_opts][:views] = app.expand_path(opts[:layout_opts][:views]).freeze
|
|
184
165
|
end
|
|
185
|
-
# RODA3: Remove
|
|
186
|
-
opts[:layout_opts][:_is_layout] = true
|
|
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
|
|
201
|
-
if opts[:layout_opts][:merge_locals] && opts[:locals]
|
|
202
|
-
opts[:layout_opts][:locals] = opts[:locals].merge(opts[:layout_opts][:locals] || {})
|
|
203
|
-
end
|
|
204
166
|
|
|
205
167
|
if layout = opts.fetch(:layout, true)
|
|
206
168
|
opts[:layout] = true unless opts.has_key?(:layout)
|
|
@@ -218,21 +180,13 @@ class Roda
|
|
|
218
180
|
|
|
219
181
|
template_opts = opts[:template_opts] = (opts[:template_opts] || {}).dup
|
|
220
182
|
template_opts[:outvar] ||= '@_out_buf'
|
|
221
|
-
|
|
183
|
+
unless template_opts.has_key?(:default_encoding)
|
|
222
184
|
template_opts[:default_encoding] = Encoding.default_external
|
|
223
185
|
end
|
|
224
|
-
|
|
225
|
-
if opts[:escape]
|
|
186
|
+
|
|
187
|
+
if opts[:escape]
|
|
226
188
|
require 'tilt/erubi'
|
|
227
189
|
template_opts[:escape] = true
|
|
228
|
-
elsif opts[:escape]
|
|
229
|
-
template_opts[:engine_class] = ErubisEscaping::Eruby
|
|
230
|
-
|
|
231
|
-
opts[:escaper] ||= if opts[:escape_safe_classes]
|
|
232
|
-
ErubisEscaping::UnsafeClassEscaper.new(opts[:escape_safe_classes])
|
|
233
|
-
else
|
|
234
|
-
::Erubis::XmlHelper
|
|
235
|
-
end
|
|
236
190
|
end
|
|
237
191
|
template_opts.freeze
|
|
238
192
|
|
|
@@ -252,17 +206,7 @@ class Roda
|
|
|
252
206
|
def inherited(subclass)
|
|
253
207
|
super
|
|
254
208
|
opts = subclass.opts[:render] = subclass.opts[:render].dup
|
|
255
|
-
|
|
256
|
-
if opts[:cache]
|
|
257
|
-
opts[:cache] = if opts[:inherit_cache]
|
|
258
|
-
opts[:cache] = opts[:cache].dup
|
|
259
|
-
elsif cache_class = opts[:cache_class]
|
|
260
|
-
opts[:cache] = cache_class.new
|
|
261
|
-
else
|
|
262
|
-
opts[:cache] = thread_safe_cache
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
|
|
209
|
+
opts[:cache] = opts[:cache].dup
|
|
266
210
|
opts.freeze
|
|
267
211
|
end
|
|
268
212
|
|
|
@@ -274,14 +218,12 @@ class Roda
|
|
|
274
218
|
|
|
275
219
|
module InstanceMethods
|
|
276
220
|
# Render the given template. See Render for details.
|
|
277
|
-
def render(template, opts =
|
|
221
|
+
def render(template, opts = OPTS, &block)
|
|
278
222
|
opts = render_template_opts(template, opts)
|
|
279
|
-
retrieve_template(opts).render((opts[:scope]||self), (opts[:locals]||
|
|
223
|
+
retrieve_template(opts).render((opts[:scope]||self), (opts[:locals]||OPTS), &block)
|
|
280
224
|
end
|
|
281
225
|
|
|
282
|
-
# Return the render options for the instance's class.
|
|
283
|
-
# is not currently frozen, it may be frozen in a future version,
|
|
284
|
-
# so you should not attempt to modify it.
|
|
226
|
+
# Return the render options for the instance's class.
|
|
285
227
|
def render_opts
|
|
286
228
|
self.class.render_opts
|
|
287
229
|
end
|
|
@@ -289,7 +231,7 @@ class Roda
|
|
|
289
231
|
# Render the given template. If there is a default layout
|
|
290
232
|
# for the class, take the result of the template rendering
|
|
291
233
|
# and render it inside the layout. See Render for details.
|
|
292
|
-
def view(template, opts=
|
|
234
|
+
def view(template, opts=OPTS)
|
|
293
235
|
opts = parse_template_opts(template, opts)
|
|
294
236
|
content = opts[:content] || render_template(opts)
|
|
295
237
|
|
|
@@ -304,12 +246,7 @@ class Roda
|
|
|
304
246
|
|
|
305
247
|
# Convert template options to single hash when rendering templates using render.
|
|
306
248
|
def render_template_opts(template, opts)
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
# RODA3: Remove
|
|
310
|
-
merge_render_locals(opts) if render_plugin_handle_locals?
|
|
311
|
-
|
|
312
|
-
opts
|
|
249
|
+
parse_template_opts(template, opts)
|
|
313
250
|
end
|
|
314
251
|
|
|
315
252
|
# Private alias for render. Should be used by other plugins when they want to render a template
|
|
@@ -319,7 +256,8 @@ class Roda
|
|
|
319
256
|
# If caching templates, attempt to retrieve the template from the cache. Otherwise, just yield
|
|
320
257
|
# to get the template.
|
|
321
258
|
def cached_template(opts, &block)
|
|
322
|
-
if (!render_opts[:explicit_cache] || opts[:cache]) && (
|
|
259
|
+
if (!render_opts[:explicit_cache] || opts[:cache]) && (key = opts[:cache_key])
|
|
260
|
+
cache = render_opts[:cache]
|
|
323
261
|
unless template = cache[key]
|
|
324
262
|
template = cache[key] = yield
|
|
325
263
|
end
|
|
@@ -333,10 +271,7 @@ class Roda
|
|
|
333
271
|
# template block, and locals to use for the render in the passed options.
|
|
334
272
|
def find_template(opts)
|
|
335
273
|
render_opts = render_opts()
|
|
336
|
-
|
|
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
|
|
339
|
-
engine_override = opts[:engine] ||= opts[:ext]
|
|
274
|
+
engine_override = opts[:engine]
|
|
340
275
|
engine = opts[:engine] ||= render_opts[:engine]
|
|
341
276
|
if content = opts[:inline]
|
|
342
277
|
path = opts[:path] = content
|
|
@@ -349,41 +284,26 @@ class Roda
|
|
|
349
284
|
opts[:template_class] ||= ::Tilt
|
|
350
285
|
end
|
|
351
286
|
|
|
352
|
-
if
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
end
|
|
287
|
+
if (cache = opts[:cache]).nil?
|
|
288
|
+
cache = content || !opts[:template_block]
|
|
289
|
+
end
|
|
356
290
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
291
|
+
if cache
|
|
292
|
+
template_block = opts[:template_block] unless content
|
|
293
|
+
template_opts = opts[:template_opts]
|
|
360
294
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
else
|
|
364
|
-
path
|
|
365
|
-
end
|
|
295
|
+
opts[:cache_key] ||= if template_class || engine_override || template_opts || template_block
|
|
296
|
+
[path, template_class, engine_override, template_opts, template_block]
|
|
366
297
|
else
|
|
367
|
-
|
|
298
|
+
path
|
|
368
299
|
end
|
|
369
|
-
|
|
370
|
-
|
|
300
|
+
else
|
|
301
|
+
opts.delete(:cache_key)
|
|
371
302
|
end
|
|
372
303
|
|
|
373
304
|
opts
|
|
374
305
|
end
|
|
375
306
|
|
|
376
|
-
# RODA3: Remove
|
|
377
|
-
def merge_render_locals(opts)
|
|
378
|
-
if !opts[:_is_layout] && (r_locals = render_opts[:locals])
|
|
379
|
-
opts[:locals] = if locals = opts[:locals]
|
|
380
|
-
Hash[r_locals].merge!(locals)
|
|
381
|
-
else
|
|
382
|
-
r_locals
|
|
383
|
-
end
|
|
384
|
-
end
|
|
385
|
-
end
|
|
386
|
-
|
|
387
307
|
# Return a single hash combining the template and opts arguments.
|
|
388
308
|
def parse_template_opts(template, opts)
|
|
389
309
|
opts = Hash[opts]
|
|
@@ -427,24 +347,15 @@ class Roda
|
|
|
427
347
|
# The template path for the given options.
|
|
428
348
|
def template_path(opts)
|
|
429
349
|
path = "#{opts[:views]}/#{template_name(opts)}.#{opts[:engine]}"
|
|
430
|
-
full_path = self.class.expand_path(path)
|
|
431
350
|
if opts.fetch(:check_paths){render_opts[:check_paths]}
|
|
351
|
+
full_path = self.class.expand_path(path)
|
|
432
352
|
unless render_opts[:allowed_paths].any?{|f| full_path.start_with?(f)}
|
|
433
353
|
raise RodaError, "attempt to render path not in allowed_paths: #{full_path} (allowed: #{render_opts[:allowed_paths].join(', ')})"
|
|
434
354
|
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."
|
|
438
|
-
end
|
|
439
355
|
end
|
|
440
356
|
path
|
|
441
357
|
end
|
|
442
358
|
|
|
443
|
-
# RODA3: Remove
|
|
444
|
-
def render_plugin_handle_locals?
|
|
445
|
-
true
|
|
446
|
-
end
|
|
447
|
-
|
|
448
359
|
# If a layout should be used, return a hash of options for
|
|
449
360
|
# rendering the layout template. If a layout should not be
|
|
450
361
|
# used, return nil.
|
|
@@ -452,41 +363,9 @@ class Roda
|
|
|
452
363
|
if layout = opts.fetch(:layout, render_opts[:layout])
|
|
453
364
|
layout_opts = render_layout_opts
|
|
454
365
|
|
|
455
|
-
# RODA3: Remove
|
|
456
|
-
merge_locals = layout_opts[:merge_locals]
|
|
457
|
-
|
|
458
366
|
method_layout_opts = opts[:layout_opts]
|
|
459
|
-
|
|
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
|
|
483
|
-
end
|
|
484
|
-
|
|
485
367
|
layout_opts.merge!(method_layout_opts) if method_layout_opts
|
|
486
368
|
|
|
487
|
-
# RODA3: Remove
|
|
488
|
-
layout_opts[:locals] = locals if render_plugin_handle_locals? && !locals.empty?
|
|
489
|
-
|
|
490
369
|
case layout
|
|
491
370
|
when Hash
|
|
492
371
|
layout_opts.merge!(layout)
|