ultra-lite-hub 0.0.1

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.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/roda-3.105.0/MIT-LICENSE +21 -0
  3. data/roda-3.105.0/lib/roda/cache.rb +42 -0
  4. data/roda-3.105.0/lib/roda/plugins/Integer_matcher_max.rb +55 -0
  5. data/roda-3.105.0/lib/roda/plugins/_after_hook.rb +11 -0
  6. data/roda-3.105.0/lib/roda/plugins/_base64.rb +34 -0
  7. data/roda-3.105.0/lib/roda/plugins/_before_hook.rb +41 -0
  8. data/roda-3.105.0/lib/roda/plugins/_optimized_matching.rb +227 -0
  9. data/roda-3.105.0/lib/roda/plugins/_symbol_class_matchers.rb +108 -0
  10. data/roda-3.105.0/lib/roda/plugins/_symbol_regexp_matchers.rb +24 -0
  11. data/roda-3.105.0/lib/roda/plugins/additional_render_engines.rb +61 -0
  12. data/roda-3.105.0/lib/roda/plugins/additional_view_directories.rb +66 -0
  13. data/roda-3.105.0/lib/roda/plugins/all_verbs.rb +50 -0
  14. data/roda-3.105.0/lib/roda/plugins/assets.rb +902 -0
  15. data/roda-3.105.0/lib/roda/plugins/assets_preloading.rb +89 -0
  16. data/roda-3.105.0/lib/roda/plugins/assume_ssl.rb +28 -0
  17. data/roda-3.105.0/lib/roda/plugins/autoload_hash_branches.rb +79 -0
  18. data/roda-3.105.0/lib/roda/plugins/autoload_named_routes.rb +65 -0
  19. data/roda-3.105.0/lib/roda/plugins/backtracking_array.rb +88 -0
  20. data/roda-3.105.0/lib/roda/plugins/bearer_token.rb +28 -0
  21. data/roda-3.105.0/lib/roda/plugins/branch_locals.rb +74 -0
  22. data/roda-3.105.0/lib/roda/plugins/break.rb +43 -0
  23. data/roda-3.105.0/lib/roda/plugins/caching.rb +206 -0
  24. data/roda-3.105.0/lib/roda/plugins/capture_erb.rb +94 -0
  25. data/roda-3.105.0/lib/roda/plugins/chunked.rb +331 -0
  26. data/roda-3.105.0/lib/roda/plugins/class_level_routing.rb +111 -0
  27. data/roda-3.105.0/lib/roda/plugins/class_matchers.rb +155 -0
  28. data/roda-3.105.0/lib/roda/plugins/common_logger.rb +80 -0
  29. data/roda-3.105.0/lib/roda/plugins/conditional_sessions.rb +67 -0
  30. data/roda-3.105.0/lib/roda/plugins/content_for.rb +103 -0
  31. data/roda-3.105.0/lib/roda/plugins/content_security_policy.rb +329 -0
  32. data/roda-3.105.0/lib/roda/plugins/cookie_flags.rb +157 -0
  33. data/roda-3.105.0/lib/roda/plugins/cookies.rb +51 -0
  34. data/roda-3.105.0/lib/roda/plugins/csrf.rb +81 -0
  35. data/roda-3.105.0/lib/roda/plugins/custom_block_results.rb +85 -0
  36. data/roda-3.105.0/lib/roda/plugins/custom_matchers.rb +89 -0
  37. data/roda-3.105.0/lib/roda/plugins/default_headers.rb +64 -0
  38. data/roda-3.105.0/lib/roda/plugins/default_status.rb +35 -0
  39. data/roda-3.105.0/lib/roda/plugins/delay_build.rb +18 -0
  40. data/roda-3.105.0/lib/roda/plugins/delegate.rb +77 -0
  41. data/roda-3.105.0/lib/roda/plugins/delete_empty_headers.rb +36 -0
  42. data/roda-3.105.0/lib/roda/plugins/direct_call.rb +38 -0
  43. data/roda-3.105.0/lib/roda/plugins/disallow_file_uploads.rb +38 -0
  44. data/roda-3.105.0/lib/roda/plugins/drop_body.rb +43 -0
  45. data/roda-3.105.0/lib/roda/plugins/each_part.rb +87 -0
  46. data/roda-3.105.0/lib/roda/plugins/early_hints.rb +25 -0
  47. data/roda-3.105.0/lib/roda/plugins/empty_root.rb +49 -0
  48. data/roda-3.105.0/lib/roda/plugins/environments.rb +79 -0
  49. data/roda-3.105.0/lib/roda/plugins/erb_h.rb +43 -0
  50. data/roda-3.105.0/lib/roda/plugins/error_email.rb +152 -0
  51. data/roda-3.105.0/lib/roda/plugins/error_handler.rb +133 -0
  52. data/roda-3.105.0/lib/roda/plugins/error_mail.rb +149 -0
  53. data/roda-3.105.0/lib/roda/plugins/exception_page.rb +445 -0
  54. data/roda-3.105.0/lib/roda/plugins/filter_common_logger.rb +46 -0
  55. data/roda-3.105.0/lib/roda/plugins/flash.rb +117 -0
  56. data/roda-3.105.0/lib/roda/plugins/h.rb +59 -0
  57. data/roda-3.105.0/lib/roda/plugins/halt.rb +108 -0
  58. data/roda-3.105.0/lib/roda/plugins/hash_branch_view_subdir.rb +76 -0
  59. data/roda-3.105.0/lib/roda/plugins/hash_branches.rb +145 -0
  60. data/roda-3.105.0/lib/roda/plugins/hash_matcher.rb +39 -0
  61. data/roda-3.105.0/lib/roda/plugins/hash_paths.rb +128 -0
  62. data/roda-3.105.0/lib/roda/plugins/hash_public.rb +125 -0
  63. data/roda-3.105.0/lib/roda/plugins/hash_public_cache.rb +91 -0
  64. data/roda-3.105.0/lib/roda/plugins/hash_routes.rb +304 -0
  65. data/roda-3.105.0/lib/roda/plugins/head.rb +99 -0
  66. data/roda-3.105.0/lib/roda/plugins/header_matchers.rb +88 -0
  67. data/roda-3.105.0/lib/roda/plugins/heartbeat.rb +41 -0
  68. data/roda-3.105.0/lib/roda/plugins/hmac_paths.rb +413 -0
  69. data/roda-3.105.0/lib/roda/plugins/hooks.rb +92 -0
  70. data/roda-3.105.0/lib/roda/plugins/host_authorization.rb +155 -0
  71. data/roda-3.105.0/lib/roda/plugins/host_routing.rb +190 -0
  72. data/roda-3.105.0/lib/roda/plugins/hsts.rb +35 -0
  73. data/roda-3.105.0/lib/roda/plugins/indifferent_params.rb +124 -0
  74. data/roda-3.105.0/lib/roda/plugins/inject_erb.rb +33 -0
  75. data/roda-3.105.0/lib/roda/plugins/invalid_request_body.rb +107 -0
  76. data/roda-3.105.0/lib/roda/plugins/ip_from_header.rb +34 -0
  77. data/roda-3.105.0/lib/roda/plugins/json.rb +119 -0
  78. data/roda-3.105.0/lib/roda/plugins/json_parser.rb +107 -0
  79. data/roda-3.105.0/lib/roda/plugins/link_to.rb +83 -0
  80. data/roda-3.105.0/lib/roda/plugins/mail_processor.rb +629 -0
  81. data/roda-3.105.0/lib/roda/plugins/mailer.rb +283 -0
  82. data/roda-3.105.0/lib/roda/plugins/map_matcher.rb +48 -0
  83. data/roda-3.105.0/lib/roda/plugins/match_affix.rb +64 -0
  84. data/roda-3.105.0/lib/roda/plugins/match_hook.rb +34 -0
  85. data/roda-3.105.0/lib/roda/plugins/match_hook_args.rb +93 -0
  86. data/roda-3.105.0/lib/roda/plugins/middleware.rb +225 -0
  87. data/roda-3.105.0/lib/roda/plugins/middleware_stack.rb +101 -0
  88. data/roda-3.105.0/lib/roda/plugins/module_include.rb +96 -0
  89. data/roda-3.105.0/lib/roda/plugins/multi_public.rb +95 -0
  90. data/roda-3.105.0/lib/roda/plugins/multi_route.rb +156 -0
  91. data/roda-3.105.0/lib/roda/plugins/multi_run.rb +144 -0
  92. data/roda-3.105.0/lib/roda/plugins/multi_view.rb +83 -0
  93. data/roda-3.105.0/lib/roda/plugins/multibyte_string_matcher.rb +57 -0
  94. data/roda-3.105.0/lib/roda/plugins/named_routes.rb +167 -0
  95. data/roda-3.105.0/lib/roda/plugins/named_templates.rb +102 -0
  96. data/roda-3.105.0/lib/roda/plugins/not_allowed.rb +149 -0
  97. data/roda-3.105.0/lib/roda/plugins/not_found.rb +55 -0
  98. data/roda-3.105.0/lib/roda/plugins/optimized_segment_matchers.rb +53 -0
  99. data/roda-3.105.0/lib/roda/plugins/optimized_string_matchers.rb +50 -0
  100. data/roda-3.105.0/lib/roda/plugins/padrino_render.rb +42 -0
  101. data/roda-3.105.0/lib/roda/plugins/param_matchers.rb +83 -0
  102. data/roda-3.105.0/lib/roda/plugins/params_capturing.rb +116 -0
  103. data/roda-3.105.0/lib/roda/plugins/part.rb +76 -0
  104. data/roda-3.105.0/lib/roda/plugins/partials.rb +74 -0
  105. data/roda-3.105.0/lib/roda/plugins/pass.rb +47 -0
  106. data/roda-3.105.0/lib/roda/plugins/path.rb +255 -0
  107. data/roda-3.105.0/lib/roda/plugins/path_matchers.rb +54 -0
  108. data/roda-3.105.0/lib/roda/plugins/path_rewriter.rb +111 -0
  109. data/roda-3.105.0/lib/roda/plugins/permissions_policy.rb +336 -0
  110. data/roda-3.105.0/lib/roda/plugins/placeholder_string_matchers.rb +48 -0
  111. data/roda-3.105.0/lib/roda/plugins/plain_hash_response_headers.rb +32 -0
  112. data/roda-3.105.0/lib/roda/plugins/precompile_templates.rb +156 -0
  113. data/roda-3.105.0/lib/roda/plugins/public.rb +182 -0
  114. data/roda-3.105.0/lib/roda/plugins/r.rb +35 -0
  115. data/roda-3.105.0/lib/roda/plugins/recheck_precompiled_assets.rb +107 -0
  116. data/roda-3.105.0/lib/roda/plugins/redirect_http_to_https.rb +99 -0
  117. data/roda-3.105.0/lib/roda/plugins/redirect_path.rb +59 -0
  118. data/roda-3.105.0/lib/roda/plugins/relative_path.rb +74 -0
  119. data/roda-3.105.0/lib/roda/plugins/render.rb +998 -0
  120. data/roda-3.105.0/lib/roda/plugins/render_coverage.rb +105 -0
  121. data/roda-3.105.0/lib/roda/plugins/render_each.rb +224 -0
  122. data/roda-3.105.0/lib/roda/plugins/render_locals.rb +102 -0
  123. data/roda-3.105.0/lib/roda/plugins/request_aref.rb +77 -0
  124. data/roda-3.105.0/lib/roda/plugins/request_headers.rb +81 -0
  125. data/roda-3.105.0/lib/roda/plugins/response_attachment.rb +94 -0
  126. data/roda-3.105.0/lib/roda/plugins/response_content_type.rb +79 -0
  127. data/roda-3.105.0/lib/roda/plugins/response_request.rb +29 -0
  128. data/roda-3.105.0/lib/roda/plugins/route_block_args.rb +50 -0
  129. data/roda-3.105.0/lib/roda/plugins/route_csrf.rb +388 -0
  130. data/roda-3.105.0/lib/roda/plugins/run_append_slash.rb +51 -0
  131. data/roda-3.105.0/lib/roda/plugins/run_handler.rb +51 -0
  132. data/roda-3.105.0/lib/roda/plugins/run_require_slash.rb +46 -0
  133. data/roda-3.105.0/lib/roda/plugins/sec_fetch_site_csrf.rb +131 -0
  134. data/roda-3.105.0/lib/roda/plugins/send_file.rb +127 -0
  135. data/roda-3.105.0/lib/roda/plugins/sessions.rb +537 -0
  136. data/roda-3.105.0/lib/roda/plugins/shared_vars.rb +86 -0
  137. data/roda-3.105.0/lib/roda/plugins/sinatra_helpers.rb +443 -0
  138. data/roda-3.105.0/lib/roda/plugins/slash_path_empty.rb +26 -0
  139. data/roda-3.105.0/lib/roda/plugins/static.rb +42 -0
  140. data/roda-3.105.0/lib/roda/plugins/static_routing.rb +89 -0
  141. data/roda-3.105.0/lib/roda/plugins/status_303.rb +34 -0
  142. data/roda-3.105.0/lib/roda/plugins/status_handler.rb +86 -0
  143. data/roda-3.105.0/lib/roda/plugins/streaming.rb +170 -0
  144. data/roda-3.105.0/lib/roda/plugins/strip_path_prefix.rb +33 -0
  145. data/roda-3.105.0/lib/roda/plugins/symbol_matchers.rb +188 -0
  146. data/roda-3.105.0/lib/roda/plugins/symbol_status.rb +32 -0
  147. data/roda-3.105.0/lib/roda/plugins/symbol_views.rb +37 -0
  148. data/roda-3.105.0/lib/roda/plugins/timestamp_public.rb +78 -0
  149. data/roda-3.105.0/lib/roda/plugins/type_routing.rb +215 -0
  150. data/roda-3.105.0/lib/roda/plugins/typecast_params.rb +1183 -0
  151. data/roda-3.105.0/lib/roda/plugins/typecast_params_sized_integers.rb +108 -0
  152. data/roda-3.105.0/lib/roda/plugins/unescape_path.rb +41 -0
  153. data/roda-3.105.0/lib/roda/plugins/view_options.rb +201 -0
  154. data/roda-3.105.0/lib/roda/plugins/view_subdir_leading_slash.rb +49 -0
  155. data/roda-3.105.0/lib/roda/plugins.rb +68 -0
  156. data/roda-3.105.0/lib/roda/request.rb +722 -0
  157. data/roda-3.105.0/lib/roda/response.rb +221 -0
  158. data/roda-3.105.0/lib/roda/session_middleware.rb +183 -0
  159. data/roda-3.105.0/lib/roda/version.rb +18 -0
  160. data/roda-3.105.0/lib/roda.rb +586 -0
  161. data/ultra-lite-hub.gemspec +12 -0
  162. metadata +201 -0
@@ -0,0 +1,108 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The typecast_params_sized_integers plugin adds sized integer conversion
7
+ # methods to typecast_params:
8
+ #
9
+ # * int8, uint8, pos_int8, pos_uint8, Integer8, Integeru8
10
+ # * int16, uint16, pos_int16, pos_uint16, Integer16, Integeru16
11
+ # * int32, uint32, pos_int32, pos_uint32, Integer32, Integeru32
12
+ # * int64, uint64, pos_int64, pos_uint64, Integer64, Integeru64
13
+ #
14
+ # The int*, pos_int*, and Integer* methods operate the same as the
15
+ # standard int, pos_int, and Integer methods in typecast_params,
16
+ # except that they will only handle parameter values in the given
17
+ # range for the signed integer type. The uint*, pos_int*, and
18
+ # Integeru* methods are similar to the int*, pos_int*, and
19
+ # Integer* methods, except they use the range of the unsigned
20
+ # integer type instead of the range of the signed integer type.
21
+ #
22
+ # Here are the signed and unsigned integer type ranges:
23
+ # 8 :: [-128, 127], [0, 255]
24
+ # 16 :: [-32768, 32767], [0, 65535]
25
+ # 32 :: [-2147483648, 2147483647], [0, 4294967295]
26
+ # 64 :: [-9223372036854775808, 9223372036854775807], [0, 18446744073709551615]
27
+ #
28
+ # To only create methods for certain integer sizes, you can pass a
29
+ # :sizes option when loading the plugin, and it will only create
30
+ # methods for the sizes you specify.
31
+ #
32
+ # You can provide a :default_size option when loading the plugin,
33
+ # in which case the int, uint, pos_int, pos_uint, Integer, and Integeru,
34
+ # typecast_params conversion methods will be aliases to the conversion
35
+ # methods for the given sized type:
36
+ #
37
+ # plugin :typecast_params_sized_integers, default_size: 64
38
+ #
39
+ # route do |r|
40
+ # # Returns nil unless param.to_i > 0 && param.to_i <= 9223372036854775807
41
+ # typecast_params.pos_int('param_name')
42
+ # end
43
+ module TypecastParamsSizedIntegers
44
+ def self.load_dependencies(app, opts=OPTS)
45
+ app.plugin :typecast_params do
46
+ (opts[:sizes] || [8, 16, 32, 64]).each do |i|
47
+ # Avoid defining the same methods more than once
48
+ next if method_defined?(:"pos_int#{i}")
49
+
50
+ min_signed = -(2**(i-1))
51
+ max_signed = 2**(i-1)-1
52
+ max_unsigned = 2**i-1
53
+
54
+ handle_type(:"int#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, or too-large integer provided for parameter") do |v|
55
+ if (v = base_convert_int(v)) && v >= min_signed && v <= max_signed
56
+ v
57
+ end
58
+ end
59
+
60
+ handle_type(:"uint#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, negative integer, or too-large integer provided for parameter") do |v|
61
+ if (v = base_convert_int(v)) && v >= 0 && v <= max_unsigned
62
+ v
63
+ end
64
+ end
65
+
66
+ handle_type(:"pos_int#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, non-positive integer, or too-large integer provided for parameter") do |v|
67
+ if (v = base_convert_int(v)) && v > 0 && v <= max_signed
68
+ v
69
+ end
70
+ end
71
+
72
+ handle_type(:"pos_uint#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, non-positive integer, or too-large integer provided for parameter") do |v|
73
+ if (v = base_convert_int(v)) && v > 0 && v <= max_unsigned
74
+ v
75
+ end
76
+ end
77
+
78
+ handle_type(:"Integer#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, or too-large integer provided for parameter") do |v|
79
+ if (v = base_convert_Integer(v)) && v >= min_signed && v <= max_signed
80
+ v
81
+ end
82
+ end
83
+
84
+ handle_type(:"Integeru#{i}", :max_input_bytesize=>100, :invalid_value_message=>"empty string, non-integer, negative integer, or too-large integer provided for parameter") do |v|
85
+ if (v = base_convert_Integer(v)) && v >= 0 && v <= max_unsigned
86
+ v
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ if default = opts[:default_size]
93
+ app::TypecastParams.class_eval do
94
+ meths = ['', 'convert_', '_convert_array_', '_max_input_bytesize_for_', '_invalid_value_message_for_']
95
+ %w[int uint pos_int pos_uint Integer Integeru].each do |type|
96
+ meths.each do |prefix|
97
+ alias_method :"#{prefix}#{type}", :"#{prefix}#{type}#{default}"
98
+ end
99
+ alias_method :"#{type}!", :"#{type}#{default}!"
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ register_plugin(:typecast_params_sized_integers, TypecastParamsSizedIntegers)
107
+ end
108
+ end
@@ -0,0 +1,41 @@
1
+ # frozen-string-literal: true
2
+
3
+ require 'rack/utils'
4
+
5
+ #
6
+ class Roda
7
+ module RodaPlugins
8
+ # The unescape_path plugin decodes a URL-encoded path
9
+ # before routing. This fixes routing when the slashes
10
+ # are URL-encoded as %2f and returns decoded parameters
11
+ # when matched by symbols or regexps.
12
+ #
13
+ # plugin :unescape_path
14
+ #
15
+ # route do |r|
16
+ # # Assume /b/a URL encoded at %2f%62%2f%61
17
+ # r.on :x, /(.)/ do |*x|
18
+ # # x => ['b', 'a']
19
+ # end
20
+ # end
21
+ module UnescapePath
22
+ module RequestMethods
23
+ # Make sure the matched path calculation handles the unescaping
24
+ # of the remaining path.
25
+ def matched_path
26
+ e = @env
27
+ Rack::Utils.unescape(e["SCRIPT_NAME"] + e["PATH_INFO"]).chomp(@remaining_path)
28
+ end
29
+
30
+ private
31
+
32
+ # Unescape the path.
33
+ def _remaining_path(env)
34
+ Rack::Utils.unescape(super)
35
+ end
36
+ end
37
+ end
38
+
39
+ register_plugin(:unescape_path, UnescapePath)
40
+ end
41
+ end
@@ -0,0 +1,201 @@
1
+ # frozen-string-literal: true
2
+
3
+ require_relative 'render'
4
+
5
+ #
6
+ class Roda
7
+ module RodaPlugins
8
+ # The view_options plugin allows you to override view and layout
9
+ # options for specific branches and routes.
10
+ #
11
+ # plugin :render
12
+ # plugin :view_options
13
+ #
14
+ # route do |r|
15
+ # r.on "users" do
16
+ # set_layout_options template: 'users_layout'
17
+ # set_view_options engine: 'haml'
18
+ #
19
+ # # ...
20
+ # end
21
+ # end
22
+ #
23
+ # The options you specify via the set_view_options and
24
+ # set_layout_options methods have higher precedence than
25
+ # the render plugin options, but lower precedence than options
26
+ # you directly pass to the view/render methods.
27
+ #
28
+ # = View Subdirectories
29
+ #
30
+ # The view_options plugin also has special support for sites
31
+ # that have outgrown a flat view directory and use subdirectories
32
+ # for views. It allows you to set the view directory to
33
+ # use, and template names that do not contain a slash will
34
+ # automatically use that view subdirectory. Example:
35
+ #
36
+ # plugin :render, layout: './layout'
37
+ # plugin :view_options
38
+ #
39
+ # route do |r|
40
+ # r.on "users" do
41
+ # set_view_subdir 'users'
42
+ #
43
+ # r.get Integer do |id|
44
+ # append_view_subdir 'profile'
45
+ # view 'index' # uses ./views/users/profile/index.erb
46
+ # end
47
+ #
48
+ # r.get 'list' do
49
+ # view 'lists/users' # uses ./views/lists/users.erb
50
+ # end
51
+ # end
52
+ # end
53
+ #
54
+ # Note that when a view subdirectory is set, the layout will
55
+ # also be looked up in the subdirectory unless it contains
56
+ # a slash. So if you want to use a view subdirectory for
57
+ # templates but have a shared layout, you should make sure your
58
+ # layout contains a slash, similar to the example above.
59
+ #
60
+ # = Per-branch HTML escaping
61
+ #
62
+ # If you have an existing Roda application that doesn't use
63
+ # automatic HTML escaping for <tt><%= %></tt> tags via the
64
+ # render plugin's +:escape+ option, but you want to switch to
65
+ # using the +:escape+ option, you can now do so without making
66
+ # all changes at once. With set_view_options, you can now
67
+ # specify escaping or not on a per branch basis in the routing
68
+ # tree:
69
+ #
70
+ # plugin :render, escape: true
71
+ # plugin :view_options
72
+ #
73
+ # route do |r|
74
+ # # Don't escape <%= %> by default
75
+ # set_view_options template_opts: {escape: false}
76
+ #
77
+ # r.on "users" do
78
+ # # Escape <%= %> in this branch
79
+ # set_view_options template_opts: {escape: true}
80
+ # end
81
+ # end
82
+ module ViewOptions
83
+ # Load the render plugin before this plugin, since this plugin
84
+ # works by overriding methods in the render plugin.
85
+ def self.load_dependencies(app)
86
+ app.plugin :render
87
+ end
88
+
89
+ module InstanceMethods
90
+ # Append a view subdirectory to use. If there hasn't already
91
+ # been a view subdirectory set, this just sets it to the argument.
92
+ # If there has already been a view subdirectory set, this sets
93
+ # the view subdirectory to a subdirectory of the existing
94
+ # view subdirectory.
95
+ def append_view_subdir(v)
96
+ if subdir = @_view_subdir
97
+ set_view_subdir("#{subdir}/#{v}")
98
+ else
99
+ set_view_subdir(v)
100
+ end
101
+ end
102
+
103
+ # Set the view subdirectory to use. This can be set to nil
104
+ # to not use a view subdirectory.
105
+ def set_view_subdir(v)
106
+ @_view_subdir = v
107
+ end
108
+
109
+ # Set branch/route options to use when rendering the layout
110
+ def set_layout_options(opts)
111
+ if options = @_layout_options
112
+ @_layout_options = options.merge!(opts)
113
+ else
114
+ @_layout_options = opts
115
+ end
116
+ end
117
+
118
+ # Set branch/route options to use when rendering the view
119
+ def set_view_options(opts)
120
+ if options = @_view_options
121
+ @_view_options = options.merge!(opts)
122
+ else
123
+ @_view_options = opts
124
+ end
125
+ end
126
+
127
+ private
128
+
129
+ if Render::COMPILED_METHOD_SUPPORT
130
+ # Return nil if using custom view or layout options.
131
+ # If using a view subdir, prefix the template key with the subdir.
132
+ def _cached_template_method_key(template)
133
+ return if @_view_options || @_layout_options
134
+
135
+ if subdir = @_view_subdir
136
+ template = [subdir, template].freeze
137
+ end
138
+
139
+ super
140
+ end
141
+
142
+ # Return nil if using custom view or layout options.
143
+ # If using a view subdir, prefix the template key with the subdir.
144
+ def _cached_template_method_lookup(method_cache, template)
145
+ return if @_view_options || @_layout_options
146
+
147
+ if subdir = @_view_subdir
148
+ template = [subdir, template]
149
+ end
150
+
151
+ super
152
+ end
153
+ end
154
+
155
+ # If view options or locals have been set and this
156
+ # template isn't a layout template, merge the options
157
+ # and locals into the returned hash.
158
+ def parse_template_opts(template, opts)
159
+ t_opts = super
160
+
161
+ if !t_opts[:_is_layout] && (v_opts = @_view_options)
162
+ t_opts.merge!(v_opts)
163
+ end
164
+
165
+ t_opts
166
+ end
167
+
168
+ # If layout options or locals have been set,
169
+ # merge the options and locals into the returned hash.
170
+ def render_layout_opts
171
+ opts = super
172
+
173
+ if l_opts = @_layout_options
174
+ opts.merge!(l_opts)
175
+ end
176
+
177
+ opts
178
+ end
179
+
180
+ # Override the template name to use the view subdirectory if the
181
+ # there is a view subdirectory and the template name does not
182
+ # contain a slash.
183
+ def template_name(opts)
184
+ name = super
185
+ if (v = @_view_subdir) && use_view_subdir_for_template_name?(name)
186
+ "#{v}/#{name}"
187
+ else
188
+ name
189
+ end
190
+ end
191
+
192
+ # Whether to use a view subdir for the template name.
193
+ def use_view_subdir_for_template_name?(name)
194
+ !name.include?('/')
195
+ end
196
+ end
197
+ end
198
+
199
+ register_plugin(:view_options, ViewOptions)
200
+ end
201
+ end
@@ -0,0 +1,49 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The view_subdir_leading_slash plugin builds on the view_options
7
+ # plugin, and changes the behavior so that if a view subdir is set,
8
+ # it is used for all templates, unless the template starts with a
9
+ # leading slash:
10
+ #
11
+ # plugin :view_subdir_leading_slash
12
+ #
13
+ # route do |r|
14
+ # r.on "users" do
15
+ # set_view_subdir 'users'
16
+ #
17
+ # r.get 'list' do
18
+ # view 'lists/users' # uses ./views/users/lists/users.erb
19
+ # end
20
+ #
21
+ # r.get 'list' do
22
+ # view '/lists/users' # uses ./views//lists/users.erb
23
+ # end
24
+ # end
25
+ # end
26
+ #
27
+ # The default for the view_options plugin is to not use a
28
+ # view subdir if the template name contains a slash at all.
29
+ module ViewSubdirLeadingSlash
30
+ # Load the view_options plugin before this plugin, since this plugin
31
+ # works by overriding a method in the view_options plugin.
32
+ def self.load_dependencies(app)
33
+ app.plugin :view_options
34
+ end
35
+
36
+ module InstanceMethods
37
+ private
38
+
39
+ # Use a view subdir unless the template starts with a slash.
40
+ def use_view_subdir_for_template_name?(name)
41
+ !name.start_with?('/')
42
+ end
43
+ end
44
+ end
45
+
46
+ register_plugin(:view_subdir_leading_slash, ViewSubdirLeadingSlash)
47
+ end
48
+ end
49
+
@@ -0,0 +1,68 @@
1
+ # frozen-string-literal: true
2
+
3
+ require_relative "cache"
4
+
5
+ class Roda
6
+ # Module in which all Roda plugins should be stored. Also contains logic for
7
+ # registering and loading plugins.
8
+ module RodaPlugins
9
+ OPTS = {}.freeze
10
+ EMPTY_ARRAY = [].freeze
11
+
12
+ # Stores registered plugins
13
+ @plugins = RodaCache.new
14
+
15
+ class << self
16
+ # Make warn a public method, as it is used for deprecation warnings.
17
+ # Roda::RodaPlugins.warn can be overridden for custom handling of
18
+ # deprecation warnings.
19
+ public :warn
20
+ end
21
+
22
+ # If the registered plugin already exists, use it. Otherwise,
23
+ # require it and return it. This raises a LoadError if such a
24
+ # plugin doesn't exist, or a RodaError if it exists but it does
25
+ # not register itself correctly.
26
+ def self.load_plugin(name)
27
+ h = @plugins
28
+ unless plugin = h[name]
29
+ require "roda/plugins/#{name}"
30
+ raise RodaError, "Plugin #{name} did not register itself correctly in Roda::RodaPlugins" unless plugin = h[name]
31
+ end
32
+ plugin
33
+ end
34
+
35
+ # Register the given plugin with Roda, so that it can be loaded using #plugin
36
+ # with a symbol. Should be used by plugin files. Example:
37
+ #
38
+ # Roda::RodaPlugins.register_plugin(:plugin_name, PluginModule)
39
+ def self.register_plugin(name, mod)
40
+ @plugins[name] = mod
41
+ end
42
+
43
+ # Deprecate the constant with the given name in the given module,
44
+ # if the ruby version supports it.
45
+ def self.deprecate_constant(mod, name)
46
+ # :nocov:
47
+ if RUBY_VERSION >= '2.3'
48
+ mod.deprecate_constant(name)
49
+ end
50
+ # :nocov:
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:
67
+ end
68
+ end