omg-actionview 8.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
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