omg-actionview 8.0.0.alpha1

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 (130) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +25 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +40 -0
  5. data/app/assets/javascripts/rails-ujs.esm.js +686 -0
  6. data/app/assets/javascripts/rails-ujs.js +630 -0
  7. data/lib/action_view/base.rb +316 -0
  8. data/lib/action_view/buffers.rb +165 -0
  9. data/lib/action_view/cache_expiry.rb +69 -0
  10. data/lib/action_view/context.rb +32 -0
  11. data/lib/action_view/dependency_tracker/erb_tracker.rb +159 -0
  12. data/lib/action_view/dependency_tracker/ruby_tracker.rb +43 -0
  13. data/lib/action_view/dependency_tracker/wildcard_resolver.rb +32 -0
  14. data/lib/action_view/dependency_tracker.rb +41 -0
  15. data/lib/action_view/deprecator.rb +7 -0
  16. data/lib/action_view/digestor.rb +130 -0
  17. data/lib/action_view/flows.rb +75 -0
  18. data/lib/action_view/gem_version.rb +17 -0
  19. data/lib/action_view/helpers/active_model_helper.rb +54 -0
  20. data/lib/action_view/helpers/asset_tag_helper.rb +680 -0
  21. data/lib/action_view/helpers/asset_url_helper.rb +473 -0
  22. data/lib/action_view/helpers/atom_feed_helper.rb +205 -0
  23. data/lib/action_view/helpers/cache_helper.rb +315 -0
  24. data/lib/action_view/helpers/capture_helper.rb +236 -0
  25. data/lib/action_view/helpers/content_exfiltration_prevention_helper.rb +70 -0
  26. data/lib/action_view/helpers/controller_helper.rb +42 -0
  27. data/lib/action_view/helpers/csp_helper.rb +26 -0
  28. data/lib/action_view/helpers/csrf_helper.rb +35 -0
  29. data/lib/action_view/helpers/date_helper.rb +1266 -0
  30. data/lib/action_view/helpers/debug_helper.rb +38 -0
  31. data/lib/action_view/helpers/form_helper.rb +2765 -0
  32. data/lib/action_view/helpers/form_options_helper.rb +927 -0
  33. data/lib/action_view/helpers/form_tag_helper.rb +1088 -0
  34. data/lib/action_view/helpers/javascript_helper.rb +96 -0
  35. data/lib/action_view/helpers/number_helper.rb +165 -0
  36. data/lib/action_view/helpers/output_safety_helper.rb +70 -0
  37. data/lib/action_view/helpers/rendering_helper.rb +218 -0
  38. data/lib/action_view/helpers/sanitize_helper.rb +201 -0
  39. data/lib/action_view/helpers/tag_helper.rb +621 -0
  40. data/lib/action_view/helpers/tags/base.rb +138 -0
  41. data/lib/action_view/helpers/tags/check_box.rb +65 -0
  42. data/lib/action_view/helpers/tags/checkable.rb +18 -0
  43. data/lib/action_view/helpers/tags/collection_check_boxes.rb +37 -0
  44. data/lib/action_view/helpers/tags/collection_helpers.rb +118 -0
  45. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +31 -0
  46. data/lib/action_view/helpers/tags/collection_select.rb +33 -0
  47. data/lib/action_view/helpers/tags/color_field.rb +26 -0
  48. data/lib/action_view/helpers/tags/date_field.rb +14 -0
  49. data/lib/action_view/helpers/tags/date_select.rb +75 -0
  50. data/lib/action_view/helpers/tags/datetime_field.rb +39 -0
  51. data/lib/action_view/helpers/tags/datetime_local_field.rb +29 -0
  52. data/lib/action_view/helpers/tags/datetime_select.rb +10 -0
  53. data/lib/action_view/helpers/tags/email_field.rb +10 -0
  54. data/lib/action_view/helpers/tags/file_field.rb +26 -0
  55. data/lib/action_view/helpers/tags/grouped_collection_select.rb +34 -0
  56. data/lib/action_view/helpers/tags/hidden_field.rb +14 -0
  57. data/lib/action_view/helpers/tags/label.rb +84 -0
  58. data/lib/action_view/helpers/tags/month_field.rb +14 -0
  59. data/lib/action_view/helpers/tags/number_field.rb +20 -0
  60. data/lib/action_view/helpers/tags/password_field.rb +14 -0
  61. data/lib/action_view/helpers/tags/placeholderable.rb +24 -0
  62. data/lib/action_view/helpers/tags/radio_button.rb +32 -0
  63. data/lib/action_view/helpers/tags/range_field.rb +10 -0
  64. data/lib/action_view/helpers/tags/search_field.rb +27 -0
  65. data/lib/action_view/helpers/tags/select.rb +45 -0
  66. data/lib/action_view/helpers/tags/select_renderer.rb +56 -0
  67. data/lib/action_view/helpers/tags/tel_field.rb +10 -0
  68. data/lib/action_view/helpers/tags/text_area.rb +24 -0
  69. data/lib/action_view/helpers/tags/text_field.rb +33 -0
  70. data/lib/action_view/helpers/tags/time_field.rb +23 -0
  71. data/lib/action_view/helpers/tags/time_select.rb +10 -0
  72. data/lib/action_view/helpers/tags/time_zone_select.rb +25 -0
  73. data/lib/action_view/helpers/tags/translator.rb +39 -0
  74. data/lib/action_view/helpers/tags/url_field.rb +10 -0
  75. data/lib/action_view/helpers/tags/week_field.rb +14 -0
  76. data/lib/action_view/helpers/tags/weekday_select.rb +31 -0
  77. data/lib/action_view/helpers/tags.rb +47 -0
  78. data/lib/action_view/helpers/text_helper.rb +568 -0
  79. data/lib/action_view/helpers/translation_helper.rb +161 -0
  80. data/lib/action_view/helpers/url_helper.rb +812 -0
  81. data/lib/action_view/helpers.rb +68 -0
  82. data/lib/action_view/layouts.rb +434 -0
  83. data/lib/action_view/locale/en.yml +56 -0
  84. data/lib/action_view/log_subscriber.rb +132 -0
  85. data/lib/action_view/lookup_context.rb +299 -0
  86. data/lib/action_view/model_naming.rb +14 -0
  87. data/lib/action_view/path_registry.rb +57 -0
  88. data/lib/action_view/path_set.rb +84 -0
  89. data/lib/action_view/railtie.rb +132 -0
  90. data/lib/action_view/record_identifier.rb +118 -0
  91. data/lib/action_view/render_parser/prism_render_parser.rb +139 -0
  92. data/lib/action_view/render_parser/ripper_render_parser.rb +350 -0
  93. data/lib/action_view/render_parser.rb +40 -0
  94. data/lib/action_view/renderer/abstract_renderer.rb +186 -0
  95. data/lib/action_view/renderer/collection_renderer.rb +204 -0
  96. data/lib/action_view/renderer/object_renderer.rb +34 -0
  97. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +120 -0
  98. data/lib/action_view/renderer/partial_renderer.rb +267 -0
  99. data/lib/action_view/renderer/renderer.rb +107 -0
  100. data/lib/action_view/renderer/streaming_template_renderer.rb +107 -0
  101. data/lib/action_view/renderer/template_renderer.rb +115 -0
  102. data/lib/action_view/rendering.rb +190 -0
  103. data/lib/action_view/routing_url_for.rb +149 -0
  104. data/lib/action_view/tasks/cache_digests.rake +25 -0
  105. data/lib/action_view/template/error.rb +264 -0
  106. data/lib/action_view/template/handlers/builder.rb +25 -0
  107. data/lib/action_view/template/handlers/erb/erubi.rb +85 -0
  108. data/lib/action_view/template/handlers/erb.rb +157 -0
  109. data/lib/action_view/template/handlers/html.rb +11 -0
  110. data/lib/action_view/template/handlers/raw.rb +11 -0
  111. data/lib/action_view/template/handlers.rb +66 -0
  112. data/lib/action_view/template/html.rb +33 -0
  113. data/lib/action_view/template/inline.rb +22 -0
  114. data/lib/action_view/template/raw_file.rb +25 -0
  115. data/lib/action_view/template/renderable.rb +30 -0
  116. data/lib/action_view/template/resolver.rb +212 -0
  117. data/lib/action_view/template/sources/file.rb +17 -0
  118. data/lib/action_view/template/sources.rb +13 -0
  119. data/lib/action_view/template/text.rb +32 -0
  120. data/lib/action_view/template/types.rb +50 -0
  121. data/lib/action_view/template.rb +580 -0
  122. data/lib/action_view/template_details.rb +66 -0
  123. data/lib/action_view/template_path.rb +66 -0
  124. data/lib/action_view/test_case.rb +449 -0
  125. data/lib/action_view/testing/resolvers.rb +44 -0
  126. data/lib/action_view/unbound_template.rb +67 -0
  127. data/lib/action_view/version.rb +10 -0
  128. data/lib/action_view/view_paths.rb +117 -0
  129. data/lib/action_view.rb +104 -0
  130. metadata +275 -0
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/benchmarkable"
4
+ require "action_view/helpers/capture_helper"
5
+ require "action_view/helpers/output_safety_helper"
6
+ require "action_view/helpers/tag_helper"
7
+ require "action_view/helpers/url_helper"
8
+ require "action_view/helpers/sanitize_helper"
9
+ require "action_view/helpers/text_helper"
10
+ require "action_view/helpers/active_model_helper"
11
+ require "action_view/helpers/asset_tag_helper"
12
+ require "action_view/helpers/asset_url_helper"
13
+ require "action_view/helpers/atom_feed_helper"
14
+ require "action_view/helpers/cache_helper"
15
+ require "action_view/helpers/content_exfiltration_prevention_helper"
16
+ require "action_view/helpers/controller_helper"
17
+ require "action_view/helpers/csp_helper"
18
+ require "action_view/helpers/csrf_helper"
19
+ require "action_view/helpers/date_helper"
20
+ require "action_view/helpers/debug_helper"
21
+ require "action_view/helpers/form_tag_helper"
22
+ require "action_view/helpers/form_helper"
23
+ require "action_view/helpers/form_options_helper"
24
+ require "action_view/helpers/javascript_helper"
25
+ require "action_view/helpers/number_helper"
26
+ require "action_view/helpers/rendering_helper"
27
+ require "action_view/helpers/translation_helper"
28
+
29
+ module ActionView # :nodoc:
30
+ module Helpers # :nodoc:
31
+ extend ActiveSupport::Autoload
32
+
33
+ autoload :Tags
34
+
35
+ def self.eager_load!
36
+ super
37
+ Tags.eager_load!
38
+ end
39
+
40
+ extend ActiveSupport::Concern
41
+
42
+ include ActiveSupport::Benchmarkable
43
+ include ActiveModelHelper
44
+ include AssetTagHelper
45
+ include AssetUrlHelper
46
+ include AtomFeedHelper
47
+ include CacheHelper
48
+ include CaptureHelper
49
+ include ContentExfiltrationPreventionHelper
50
+ include ControllerHelper
51
+ include CspHelper
52
+ include CsrfHelper
53
+ include DateHelper
54
+ include DebugHelper
55
+ include FormHelper
56
+ include FormOptionsHelper
57
+ include FormTagHelper
58
+ include JavaScriptHelper
59
+ include NumberHelper
60
+ include OutputSafetyHelper
61
+ include RenderingHelper
62
+ include SanitizeHelper
63
+ include TagHelper
64
+ include TextHelper
65
+ include TranslationHelper
66
+ include UrlHelper
67
+ end
68
+ end
@@ -0,0 +1,434 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_view/rendering"
4
+ require "active_support/core_ext/module/redefine_method"
5
+
6
+ module ActionView
7
+ # = Action View \Layouts
8
+ #
9
+ # Layouts reverse the common pattern of including shared headers and footers in many templates to isolate changes in
10
+ # repeated setups. The inclusion pattern has pages that look like this:
11
+ #
12
+ # <%= render "application/header" %>
13
+ # Hello World
14
+ # <%= render "application/footer" %>
15
+ #
16
+ # This approach is a decent way of keeping common structures isolated from the changing content, but it's verbose
17
+ # and if you ever want to change the structure of these two includes, you'll have to change all the templates.
18
+ #
19
+ # With layouts, you can flip it around and have the common structure know where to insert changing content. This means
20
+ # that the header and footer are only mentioned in one place, like this:
21
+ #
22
+ # // The header part of this layout
23
+ # <%= yield %>
24
+ # // The footer part of this layout
25
+ #
26
+ # And then you have content pages that look like this:
27
+ #
28
+ # hello world
29
+ #
30
+ # At rendering time, the content page is computed and then inserted in the layout, like this:
31
+ #
32
+ # // The header part of this layout
33
+ # hello world
34
+ # // The footer part of this layout
35
+ #
36
+ # == Accessing shared variables
37
+ #
38
+ # Layouts have access to variables specified in the content pages and vice versa. This allows you to have layouts with
39
+ # references that won't materialize before rendering time:
40
+ #
41
+ # <h1><%= @page_title %></h1>
42
+ # <%= yield %>
43
+ #
44
+ # ...and content pages that fulfill these references _at_ rendering time:
45
+ #
46
+ # <% @page_title = "Welcome" %>
47
+ # Off-world colonies offers you a chance to start a new life
48
+ #
49
+ # The result after rendering is:
50
+ #
51
+ # <h1>Welcome</h1>
52
+ # Off-world colonies offers you a chance to start a new life
53
+ #
54
+ # == Layout assignment
55
+ #
56
+ # You can either specify a layout declaratively (using the #layout class method) or give
57
+ # it the same name as your controller, and place it in <tt>app/views/layouts</tt>.
58
+ # If a subclass does not have a layout specified, it inherits its layout using normal Ruby inheritance.
59
+ #
60
+ # For instance, if you have PostsController and a template named <tt>app/views/layouts/posts.html.erb</tt>,
61
+ # that template will be used for all actions in PostsController and controllers inheriting
62
+ # from PostsController.
63
+ #
64
+ # If you use a module, for instance Weblog::PostsController, you will need a template named
65
+ # <tt>app/views/layouts/weblog/posts.html.erb</tt>.
66
+ #
67
+ # Since all your controllers inherit from ApplicationController, they will use
68
+ # <tt>app/views/layouts/application.html.erb</tt> if no other layout is specified
69
+ # or provided.
70
+ #
71
+ # == Inheritance Examples
72
+ #
73
+ # class BankController < ActionController::Base
74
+ # # bank.html.erb exists
75
+ #
76
+ # class ExchangeController < BankController
77
+ # # exchange.html.erb exists
78
+ #
79
+ # class CurrencyController < BankController
80
+ #
81
+ # class InformationController < BankController
82
+ # layout "information"
83
+ #
84
+ # class TellerController < InformationController
85
+ # # teller.html.erb exists
86
+ #
87
+ # class EmployeeController < InformationController
88
+ # # employee.html.erb exists
89
+ # layout nil
90
+ #
91
+ # class VaultController < BankController
92
+ # layout :access_level_layout
93
+ #
94
+ # class TillController < BankController
95
+ # layout false
96
+ #
97
+ # In these examples, we have three implicit lookup scenarios:
98
+ # * The +BankController+ uses the "bank" layout.
99
+ # * The +ExchangeController+ uses the "exchange" layout.
100
+ # * The +CurrencyController+ inherits the layout from BankController.
101
+ #
102
+ # However, when a layout is explicitly set, the explicitly set layout wins:
103
+ # * The +InformationController+ uses the "information" layout, explicitly set.
104
+ # * The +TellerController+ also uses the "information" layout, because the parent explicitly set it.
105
+ # * The +EmployeeController+ uses the "employee" layout, because it set the layout to +nil+, resetting the parent configuration.
106
+ # * The +VaultController+ chooses a layout dynamically by calling the <tt>access_level_layout</tt> method.
107
+ # * The +TillController+ does not use a layout at all.
108
+ #
109
+ # == Types of layouts
110
+ #
111
+ # Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes
112
+ # you want to alternate layouts depending on runtime information, such as whether someone is logged in or not. This can
113
+ # be done either by specifying a method reference as a symbol or using an inline method (as a proc).
114
+ #
115
+ # The method reference is the preferred approach to variable layouts and is used like this:
116
+ #
117
+ # class WeblogController < ActionController::Base
118
+ # layout :writers_and_readers
119
+ #
120
+ # def index
121
+ # # fetching posts
122
+ # end
123
+ #
124
+ # private
125
+ # def writers_and_readers
126
+ # logged_in? ? "writer_layout" : "reader_layout"
127
+ # end
128
+ # end
129
+ #
130
+ # Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing
131
+ # is logged in or not.
132
+ #
133
+ # If you want to use an inline method, such as a proc, do something like this:
134
+ #
135
+ # class WeblogController < ActionController::Base
136
+ # layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" }
137
+ # end
138
+ #
139
+ # If an argument isn't given to the proc, it's evaluated in the context of
140
+ # the current controller anyway.
141
+ #
142
+ # class WeblogController < ActionController::Base
143
+ # layout proc { logged_in? ? "writer_layout" : "reader_layout" }
144
+ # end
145
+ #
146
+ # Of course, the most common way of specifying a layout is still just as a plain template name:
147
+ #
148
+ # class WeblogController < ActionController::Base
149
+ # layout "weblog_standard"
150
+ # end
151
+ #
152
+ # The template will be looked always in <tt>app/views/layouts/</tt> folder. But you can point
153
+ # <tt>layouts</tt> folder direct also. <tt>layout "layouts/demo"</tt> is the same as <tt>layout "demo"</tt>.
154
+ #
155
+ # Setting the layout to +nil+ forces it to be looked up in the filesystem and falls back to the parent behavior if none exists.
156
+ # Setting it to +nil+ is useful to re-enable template lookup overriding a previous configuration set in the parent:
157
+ #
158
+ # class ApplicationController < ActionController::Base
159
+ # layout "application"
160
+ # end
161
+ #
162
+ # class PostsController < ApplicationController
163
+ # # Will use "application" layout
164
+ # end
165
+ #
166
+ # class CommentsController < ApplicationController
167
+ # # Will search for "comments" layout and fall back to "application" layout
168
+ # layout nil
169
+ # end
170
+ #
171
+ # == Conditional layouts
172
+ #
173
+ # If you have a layout that by default is applied to all the actions of a controller, you still have the option of rendering
174
+ # a given action or set of actions without a layout, or restricting a layout to only a single action or a set of actions. The
175
+ # <tt>:only</tt> and <tt>:except</tt> options can be passed to the layout call. For example:
176
+ #
177
+ # class WeblogController < ActionController::Base
178
+ # layout "weblog_standard", except: :rss
179
+ #
180
+ # # ...
181
+ #
182
+ # end
183
+ #
184
+ # This will assign "weblog_standard" as the WeblogController's layout for all actions except for the +rss+ action, which will
185
+ # be rendered directly, without wrapping a layout around the rendered view.
186
+ #
187
+ # Both the <tt>:only</tt> and <tt>:except</tt> condition can accept an arbitrary number of method references, so
188
+ # <tt>except: [ :rss, :text_only ]</tt> is valid, as is <tt>except: :rss</tt>.
189
+ #
190
+ # == Using a different layout in the action render call
191
+ #
192
+ # If most of your actions use the same layout, it makes perfect sense to define a controller-wide layout as described above.
193
+ # Sometimes you'll have exceptions where one action wants to use a different layout than the rest of the controller.
194
+ # You can do this by passing a <tt>:layout</tt> option to the <tt>render</tt> call. For example:
195
+ #
196
+ # class WeblogController < ActionController::Base
197
+ # layout "weblog_standard"
198
+ #
199
+ # def help
200
+ # render action: "help", layout: "help"
201
+ # end
202
+ # end
203
+ #
204
+ # This will override the controller-wide "weblog_standard" layout, and will render the help action with the "help" layout instead.
205
+ module Layouts
206
+ extend ActiveSupport::Concern
207
+
208
+ include ActionView::Rendering
209
+
210
+ included do
211
+ class_attribute :_layout, instance_accessor: false
212
+ class_attribute :_layout_conditions, instance_accessor: false, instance_reader: true, default: {}
213
+
214
+ _write_layout_method
215
+ end
216
+
217
+ module ClassMethods
218
+ def inherited(klass) # :nodoc:
219
+ super
220
+ klass._write_layout_method
221
+ end
222
+
223
+ # This module is mixed in if layout conditions are provided. This means
224
+ # that if no layout conditions are used, this method is not used
225
+ module LayoutConditions # :nodoc:
226
+ private
227
+ # Determines whether the current action has a layout definition by
228
+ # checking the action name against the :only and :except conditions
229
+ # set by the <tt>layout</tt> method.
230
+ #
231
+ # ==== Returns
232
+ # * <tt>Boolean</tt> - True if the action has a layout definition, false otherwise.
233
+ def _conditional_layout?
234
+ return unless super
235
+
236
+ conditions = _layout_conditions
237
+
238
+ if only = conditions[:only]
239
+ only.include?(action_name)
240
+ elsif except = conditions[:except]
241
+ !except.include?(action_name)
242
+ else
243
+ true
244
+ end
245
+ end
246
+ end
247
+
248
+ # Specify the layout to use for this class.
249
+ #
250
+ # If the specified layout is a:
251
+ # String:: the String is the template name
252
+ # Symbol:: call the method specified by the symbol
253
+ # Proc:: call the passed Proc
254
+ # false:: There is no layout
255
+ # true:: raise an ArgumentError
256
+ # nil:: Force default layout behavior with inheritance
257
+ #
258
+ # Return value of +Proc+ and +Symbol+ arguments should be +String+, +false+, +true+, or +nil+
259
+ # with the same meaning as described above.
260
+ #
261
+ # ==== Parameters
262
+ #
263
+ # * <tt>layout</tt> - The layout to use.
264
+ #
265
+ # ==== Options (conditions)
266
+ #
267
+ # * +:only+ - A list of actions to apply this layout to.
268
+ # * +:except+ - Apply this layout to all actions but this one.
269
+ def layout(layout, conditions = {})
270
+ include LayoutConditions unless conditions.empty?
271
+
272
+ conditions.each { |k, v| conditions[k] = Array(v).map(&:to_s) }
273
+ self._layout_conditions = conditions
274
+
275
+ self._layout = layout
276
+ _write_layout_method
277
+ end
278
+
279
+ # Creates a _layout method to be called by _default_layout .
280
+ #
281
+ # If a layout is not explicitly mentioned then look for a layout with the controller's name.
282
+ # if nothing is found then try same procedure to find super class's layout.
283
+ def _write_layout_method # :nodoc:
284
+ silence_redefinition_of_method(:_layout)
285
+
286
+ prefixes = /\blayouts/.match?(_implied_layout_name) ? [] : ["layouts"]
287
+ default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, [], { formats: formats }).first || super"
288
+ name_clause = if name
289
+ default_behavior
290
+ else
291
+ <<-RUBY
292
+ super
293
+ RUBY
294
+ end
295
+
296
+ layout_definition = \
297
+ case _layout
298
+ when String
299
+ _layout.inspect
300
+ when Symbol
301
+ <<-RUBY
302
+ #{_layout}.tap do |layout|
303
+ return #{default_behavior} if layout.nil?
304
+ unless layout.is_a?(String) || !layout
305
+ raise ArgumentError, "Your layout method :#{_layout} returned \#{layout}. It " \
306
+ "should have returned a String, false, or nil"
307
+ end
308
+ end
309
+ RUBY
310
+ when Proc
311
+ define_method :_layout_from_proc, &_layout
312
+ private :_layout_from_proc
313
+ <<-RUBY
314
+ result = _layout_from_proc(#{_layout.arity == 0 ? '' : 'self'})
315
+ return #{default_behavior} if result.nil?
316
+ result
317
+ RUBY
318
+ when false
319
+ nil
320
+ when true
321
+ raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil"
322
+ when nil
323
+ name_clause
324
+ end
325
+
326
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
327
+ # frozen_string_literal: true
328
+ def _layout(lookup_context, formats)
329
+ if _conditional_layout?
330
+ #{layout_definition}
331
+ else
332
+ #{name_clause}
333
+ end
334
+ end
335
+ private :_layout
336
+ RUBY
337
+ end
338
+
339
+ private
340
+ # If no layout is supplied, look for a template named the return
341
+ # value of this method.
342
+ #
343
+ # ==== Returns
344
+ # * <tt>String</tt> - A template name
345
+ def _implied_layout_name
346
+ controller_path
347
+ end
348
+ end
349
+
350
+ def _normalize_options(options) # :nodoc:
351
+ super
352
+
353
+ if _include_layout?(options)
354
+ layout = options.delete(:layout) { :default }
355
+ options[:layout] = _layout_for_option(layout)
356
+ end
357
+ end
358
+
359
+ attr_internal_writer :action_has_layout
360
+
361
+ def initialize(*) # :nodoc:
362
+ @_action_has_layout = true
363
+ super
364
+ end
365
+
366
+ # Controls whether an action should be rendered using a layout.
367
+ # If you want to disable any <tt>layout</tt> settings for the
368
+ # current action so that it is rendered without a layout then
369
+ # either override this method in your controller to return false
370
+ # for that action or set the <tt>action_has_layout</tt> attribute
371
+ # to false before rendering.
372
+ def action_has_layout?
373
+ @_action_has_layout
374
+ end
375
+
376
+ private
377
+ def _conditional_layout?
378
+ true
379
+ end
380
+
381
+ # This will be overwritten by _write_layout_method
382
+ def _layout(*); end
383
+
384
+ # Determine the layout for a given name, taking into account the name type.
385
+ #
386
+ # ==== Parameters
387
+ # * <tt>name</tt> - The name of the template
388
+ def _layout_for_option(name)
389
+ case name
390
+ when String then _normalize_layout(name)
391
+ when Proc then name
392
+ when true then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, true) }
393
+ when :default then Proc.new { |lookup_context, formats| _default_layout(lookup_context, formats, false) }
394
+ when false, nil then nil
395
+ else
396
+ raise ArgumentError,
397
+ "String, Proc, :default, true, or false, expected for `layout'; you passed #{name.inspect}"
398
+ end
399
+ end
400
+
401
+ def _normalize_layout(value)
402
+ value.is_a?(String) && !value.match?(/\blayouts/) ? "layouts/#{value}" : value
403
+ end
404
+
405
+ # Returns the default layout for this controller.
406
+ # Optionally raises an exception if the layout could not be found.
407
+ #
408
+ # ==== Parameters
409
+ # * <tt>formats</tt> - The formats accepted to this layout
410
+ # * <tt>require_layout</tt> - If set to +true+ and layout is not found,
411
+ # an +ArgumentError+ exception is raised (defaults to +false+)
412
+ #
413
+ # ==== Returns
414
+ # * <tt>template</tt> - The template object for the default layout (or +nil+)
415
+ def _default_layout(lookup_context, formats, require_layout = false)
416
+ begin
417
+ value = _layout(lookup_context, formats) if action_has_layout?
418
+ rescue NameError => e
419
+ raise e, "Could not render layout: #{e.message}"
420
+ end
421
+
422
+ if require_layout && action_has_layout? && !value
423
+ raise ArgumentError,
424
+ "There was no default layout for #{self.class} in #{view_paths.inspect}"
425
+ end
426
+
427
+ _normalize_layout(value)
428
+ end
429
+
430
+ def _include_layout?(options)
431
+ !options.keys.intersect?([:body, :plain, :html, :inline, :partial]) || options.key?(:layout)
432
+ end
433
+ end
434
+ end
@@ -0,0 +1,56 @@
1
+ "en":
2
+ # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
3
+ datetime:
4
+ distance_in_words:
5
+ half_a_minute: "half a minute"
6
+ less_than_x_seconds:
7
+ one: "less than 1 second"
8
+ other: "less than %{count} seconds"
9
+ x_seconds:
10
+ one: "1 second"
11
+ other: "%{count} seconds"
12
+ less_than_x_minutes:
13
+ one: "less than a minute"
14
+ other: "less than %{count} minutes"
15
+ x_minutes:
16
+ one: "1 minute"
17
+ other: "%{count} minutes"
18
+ about_x_hours:
19
+ one: "about 1 hour"
20
+ other: "about %{count} hours"
21
+ x_days:
22
+ one: "1 day"
23
+ other: "%{count} days"
24
+ about_x_months:
25
+ one: "about 1 month"
26
+ other: "about %{count} months"
27
+ x_months:
28
+ one: "1 month"
29
+ other: "%{count} months"
30
+ about_x_years:
31
+ one: "about 1 year"
32
+ other: "about %{count} years"
33
+ over_x_years:
34
+ one: "over 1 year"
35
+ other: "over %{count} years"
36
+ almost_x_years:
37
+ one: "almost 1 year"
38
+ other: "almost %{count} years"
39
+ prompts:
40
+ year: "Year"
41
+ month: "Month"
42
+ day: "Day"
43
+ hour: "Hour"
44
+ minute: "Minute"
45
+ second: "Seconds"
46
+
47
+ helpers:
48
+ select:
49
+ # Default value for :prompt => true in FormOptionsHelper
50
+ prompt: "Please select"
51
+
52
+ # Default translation keys for submit and button FormHelper
53
+ submit:
54
+ create: 'Create %{model}'
55
+ update: 'Update %{model}'
56
+ submit: 'Save %{model}'
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/log_subscriber"
4
+
5
+ module ActionView
6
+ # = Action View Log Subscriber
7
+ #
8
+ # Provides functionality so that \Rails can output logs from Action View.
9
+ class LogSubscriber < ActiveSupport::LogSubscriber
10
+ VIEWS_PATTERN = /^app\/views\//
11
+
12
+ def initialize
13
+ @root = nil
14
+ super
15
+ end
16
+
17
+ def render_template(event)
18
+ info do
19
+ message = +" Rendered #{from_rails_root(event.payload[:identifier])}"
20
+ message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
21
+ message << " (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
22
+ end
23
+ end
24
+ subscribe_log_level :render_template, :debug
25
+
26
+ def render_partial(event)
27
+ debug do
28
+ message = +" Rendered #{from_rails_root(event.payload[:identifier])}"
29
+ message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
30
+ message << " (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
31
+ message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
32
+ message
33
+ end
34
+ end
35
+ subscribe_log_level :render_partial, :debug
36
+
37
+ def render_layout(event)
38
+ info do
39
+ message = +" Rendered layout #{from_rails_root(event.payload[:identifier])}"
40
+ message << " (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
41
+ end
42
+ end
43
+ subscribe_log_level :render_layout, :info
44
+
45
+ def render_collection(event)
46
+ identifier = event.payload[:identifier] || "templates"
47
+
48
+ debug do
49
+ message = +" Rendered collection of #{from_rails_root(identifier)}"
50
+ message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
51
+ message << " #{render_count(event.payload)} (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
52
+ message
53
+ end
54
+ end
55
+ subscribe_log_level :render_collection, :debug
56
+
57
+ module Utils # :nodoc:
58
+ def logger
59
+ ActionView::Base.logger
60
+ end
61
+
62
+ private
63
+ def from_rails_root(string)
64
+ string = string.sub(rails_root, "")
65
+ string.sub!(VIEWS_PATTERN, "")
66
+ string
67
+ end
68
+
69
+ def rails_root # :doc:
70
+ @root ||= "#{Rails.root}/"
71
+ end
72
+ end
73
+
74
+ include Utils
75
+
76
+ class Start # :nodoc:
77
+ include Utils
78
+
79
+ def start(name, id, payload)
80
+ return unless logger
81
+ logger.debug do
82
+ qualifier =
83
+ if name == "render_template.action_view"
84
+ ""
85
+ elsif name == "render_layout.action_view"
86
+ "layout "
87
+ end
88
+
89
+ return unless qualifier
90
+
91
+ message = +" Rendering #{qualifier}#{from_rails_root(payload[:identifier])}"
92
+ message << " within #{from_rails_root(payload[:layout])}" if payload[:layout]
93
+ message
94
+ end
95
+ end
96
+
97
+ def finish(name, id, payload)
98
+ end
99
+
100
+ def silenced?(_)
101
+ logger.nil? || !logger.debug?
102
+ end
103
+ end
104
+
105
+ def self.attach_to(*)
106
+ ActiveSupport::Notifications.subscribe("render_template.action_view", ActionView::LogSubscriber::Start.new)
107
+ ActiveSupport::Notifications.subscribe("render_layout.action_view", ActionView::LogSubscriber::Start.new)
108
+
109
+ super
110
+ end
111
+
112
+ private
113
+ def render_count(payload) # :doc:
114
+ if payload[:cache_hits]
115
+ "[#{payload[:cache_hits]} / #{payload[:count]} cache hits]"
116
+ else
117
+ "[#{payload[:count]} times]"
118
+ end
119
+ end
120
+
121
+ def cache_message(payload) # :doc:
122
+ case payload[:cache_hit]
123
+ when :hit
124
+ "[cache hit]"
125
+ when :miss
126
+ "[cache miss]"
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ ActionView::LogSubscriber.attach_to :action_view