actionview 5.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionview might be problematic. Click here for more details.

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