actionview 7.2.3 → 8.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -186
- data/README.rdoc +1 -1
- data/lib/action_view/base.rb +9 -6
- data/lib/action_view/dependency_tracker/erb_tracker.rb +35 -27
- data/lib/action_view/dependency_tracker/ruby_tracker.rb +2 -19
- data/lib/action_view/dependency_tracker/wildcard_resolver.rb +32 -0
- data/lib/action_view/dependency_tracker.rb +1 -0
- data/lib/action_view/digestor.rb +2 -6
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +4 -4
- data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
- data/lib/action_view/helpers/cache_helper.rb +10 -2
- data/lib/action_view/helpers/date_helper.rb +1 -8
- data/lib/action_view/helpers/form_helper.rb +90 -91
- data/lib/action_view/helpers/form_options_helper.rb +19 -20
- data/lib/action_view/helpers/form_tag_helper.rb +18 -16
- data/lib/action_view/helpers/output_safety_helper.rb +2 -1
- data/lib/action_view/helpers/rendering_helper.rb +160 -50
- data/lib/action_view/helpers/tag_helper.rb +41 -38
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +4 -3
- data/lib/action_view/helpers/tags/collection_helpers.rb +1 -2
- data/lib/action_view/helpers/text_helper.rb +4 -11
- data/lib/action_view/helpers/url_helper.rb +2 -4
- data/lib/action_view/layouts.rb +7 -7
- data/lib/action_view/render_parser/prism_render_parser.rb +13 -1
- data/lib/action_view/render_parser/ripper_render_parser.rb +10 -1
- data/lib/action_view/renderer/partial_renderer.rb +2 -2
- data/lib/action_view/renderer/streaming_template_renderer.rb +0 -1
- data/lib/action_view/renderer/template_renderer.rb +3 -3
- data/lib/action_view/rendering.rb +2 -3
- data/lib/action_view/template/error.rb +0 -11
- data/lib/action_view/template/handlers/erb.rb +37 -45
- data/lib/action_view/template/resolver.rb +0 -1
- data/lib/action_view/template.rb +3 -14
- data/lib/action_view/test_case.rb +1 -0
- data/lib/action_view.rb +0 -1
- metadata +17 -27
|
@@ -496,8 +496,7 @@ module ActionView
|
|
|
496
496
|
# <option value="France">France</option>
|
|
497
497
|
# </optgroup>
|
|
498
498
|
#
|
|
499
|
-
#
|
|
500
|
-
#
|
|
499
|
+
# Parameters:
|
|
501
500
|
# * +grouped_options+ - Accepts a nested array or hash of strings. The first value serves as the
|
|
502
501
|
# <tt><optgroup></tt> label while the second value must be an array of options. The second value can be a
|
|
503
502
|
# nested array of text-value pairs. See <tt>options_for_select</tt> for more info.
|
|
@@ -508,8 +507,7 @@ module ActionView
|
|
|
508
507
|
# which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
|
|
509
508
|
# as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
|
|
510
509
|
#
|
|
511
|
-
#
|
|
512
|
-
#
|
|
510
|
+
# Options:
|
|
513
511
|
# * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this
|
|
514
512
|
# prepends an option with a generic prompt - "Please select" - or the given prompt string.
|
|
515
513
|
# * <tt>:divider</tt> - the divider for the options groups.
|
|
@@ -601,8 +599,7 @@ module ActionView
|
|
|
601
599
|
|
|
602
600
|
# Returns a string of option tags for the days of the week.
|
|
603
601
|
#
|
|
604
|
-
#
|
|
605
|
-
#
|
|
602
|
+
# Options:
|
|
606
603
|
# * <tt>:index_as_value</tt> - Defaults to false, set to true to use the indexes from
|
|
607
604
|
# <tt>I18n.translate("date.day_names")</tt> as the values. By default, Sunday is always 0.
|
|
608
605
|
# * <tt>:day_format</tt> - The I18n key of the array to use for the weekday options.
|
|
@@ -689,7 +686,7 @@ module ActionView
|
|
|
689
686
|
# if a +User+ model has a +category_id+ field and in the form no category is selected, no +category_id+ parameter is sent. So,
|
|
690
687
|
# any strong parameters idiom like:
|
|
691
688
|
#
|
|
692
|
-
# params.
|
|
689
|
+
# params.expect(user: [...])
|
|
693
690
|
#
|
|
694
691
|
# will raise an error since no <tt>{user: ...}</tt> will be present.
|
|
695
692
|
#
|
|
@@ -726,7 +723,7 @@ module ActionView
|
|
|
726
723
|
# end
|
|
727
724
|
#
|
|
728
725
|
# Sample usage (selecting the associated Author for an instance of Post, <tt>@post</tt>):
|
|
729
|
-
#
|
|
726
|
+
# collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial)
|
|
730
727
|
#
|
|
731
728
|
# If <tt>@post.author_ids</tt> is already <tt>[1]</tt>, this would return:
|
|
732
729
|
# <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
|
|
@@ -739,8 +736,8 @@ module ActionView
|
|
|
739
736
|
#
|
|
740
737
|
# It is also possible to customize the way the elements will be shown by
|
|
741
738
|
# giving a block to the method:
|
|
742
|
-
#
|
|
743
|
-
# b.label { b.
|
|
739
|
+
# collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
|
|
740
|
+
# b.label { b.checkbox }
|
|
744
741
|
# end
|
|
745
742
|
#
|
|
746
743
|
# The argument passed to the block is a special kind of builder for this
|
|
@@ -749,17 +746,17 @@ module ActionView
|
|
|
749
746
|
# Using it, you can change the label and check box display order or even
|
|
750
747
|
# use the label as wrapper, as in the example above.
|
|
751
748
|
#
|
|
752
|
-
# The builder methods <tt>label</tt> and <tt>
|
|
749
|
+
# The builder methods <tt>label</tt> and <tt>checkbox</tt> also accept
|
|
753
750
|
# extra HTML options:
|
|
754
|
-
#
|
|
755
|
-
# b.label(class: "
|
|
751
|
+
# collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
|
|
752
|
+
# b.label(class: "checkbox") { b.checkbox(class: "checkbox") }
|
|
756
753
|
# end
|
|
757
754
|
#
|
|
758
755
|
# There are also three special methods available: <tt>object</tt>, <tt>text</tt> and
|
|
759
756
|
# <tt>value</tt>, which are the current item being rendered, its text and value methods,
|
|
760
757
|
# respectively. You can use them like this:
|
|
761
|
-
#
|
|
762
|
-
# b.label(:"data-value" => b.value) { b.
|
|
758
|
+
# collection_checkboxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
|
|
759
|
+
# b.label(:"data-value" => b.value) { b.checkbox + b.text }
|
|
763
760
|
# end
|
|
764
761
|
#
|
|
765
762
|
# ==== Gotcha
|
|
@@ -782,9 +779,10 @@ module ActionView
|
|
|
782
779
|
#
|
|
783
780
|
# In the rare case you don't want this hidden field, you can pass the
|
|
784
781
|
# <tt>include_hidden: false</tt> option to the helper method.
|
|
785
|
-
def
|
|
782
|
+
def collection_checkboxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
|
786
783
|
Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
|
|
787
784
|
end
|
|
785
|
+
alias_method :collection_check_boxes, :collection_checkboxes
|
|
788
786
|
|
|
789
787
|
private
|
|
790
788
|
def option_html_attributes(element)
|
|
@@ -900,17 +898,18 @@ module ActionView
|
|
|
900
898
|
@template.weekday_select(@object_name, method, objectify_options(options), @default_html_options.merge(html_options))
|
|
901
899
|
end
|
|
902
900
|
|
|
903
|
-
# Wraps ActionView::Helpers::FormOptionsHelper#
|
|
901
|
+
# Wraps ActionView::Helpers::FormOptionsHelper#collection_checkboxes for form builders:
|
|
904
902
|
#
|
|
905
903
|
# <%= form_for @post do |f| %>
|
|
906
|
-
# <%= f.
|
|
904
|
+
# <%= f.collection_checkboxes :author_ids, Author.all, :id, :name_with_initial %>
|
|
907
905
|
# <%= f.submit %>
|
|
908
906
|
# <% end %>
|
|
909
907
|
#
|
|
910
908
|
# Please refer to the documentation of the base helper for details.
|
|
911
|
-
def
|
|
912
|
-
@template.
|
|
909
|
+
def collection_checkboxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
|
910
|
+
@template.collection_checkboxes(@object_name, method, collection, value_method, text_method, objectify_options(options), @default_html_options.merge(html_options), &block)
|
|
913
911
|
end
|
|
912
|
+
alias_method :collection_check_boxes, :collection_checkboxes
|
|
914
913
|
|
|
915
914
|
# Wraps ActionView::Helpers::FormOptionsHelper#collection_radio_buttons for form builders:
|
|
916
915
|
#
|
|
@@ -393,24 +393,24 @@ module ActionView
|
|
|
393
393
|
# * Any other key creates standard HTML attributes for the tag.
|
|
394
394
|
#
|
|
395
395
|
# ==== Examples
|
|
396
|
-
#
|
|
396
|
+
# textarea_tag 'post'
|
|
397
397
|
# # => <textarea id="post" name="post"></textarea>
|
|
398
398
|
#
|
|
399
|
-
#
|
|
399
|
+
# textarea_tag 'bio', @user.bio
|
|
400
400
|
# # => <textarea id="bio" name="bio">This is my biography.</textarea>
|
|
401
401
|
#
|
|
402
|
-
#
|
|
402
|
+
# textarea_tag 'body', nil, rows: 10, cols: 25
|
|
403
403
|
# # => <textarea cols="25" id="body" name="body" rows="10"></textarea>
|
|
404
404
|
#
|
|
405
|
-
#
|
|
405
|
+
# textarea_tag 'body', nil, size: "25x10"
|
|
406
406
|
# # => <textarea name="body" id="body" cols="25" rows="10"></textarea>
|
|
407
407
|
#
|
|
408
|
-
#
|
|
408
|
+
# textarea_tag 'description', "Description goes here.", disabled: true
|
|
409
409
|
# # => <textarea disabled="disabled" id="description" name="description">Description goes here.</textarea>
|
|
410
410
|
#
|
|
411
|
-
#
|
|
411
|
+
# textarea_tag 'comment', nil, class: 'comment_input'
|
|
412
412
|
# # => <textarea class="comment_input" id="comment" name="comment"></textarea>
|
|
413
|
-
def
|
|
413
|
+
def textarea_tag(name, content = nil, options = {})
|
|
414
414
|
options = options.stringify_keys
|
|
415
415
|
|
|
416
416
|
if size = options.delete("size")
|
|
@@ -422,12 +422,13 @@ module ActionView
|
|
|
422
422
|
|
|
423
423
|
content_tag :textarea, content.to_s.html_safe, { "name" => name, "id" => sanitize_to_id(name) }.update(options)
|
|
424
424
|
end
|
|
425
|
+
alias_method :text_area_tag, :textarea_tag
|
|
425
426
|
|
|
426
427
|
##
|
|
427
428
|
# :call-seq:
|
|
428
|
-
#
|
|
429
|
-
#
|
|
430
|
-
#
|
|
429
|
+
# checkbox_tag(name, options = {})
|
|
430
|
+
# checkbox_tag(name, value, options = {})
|
|
431
|
+
# checkbox_tag(name, value, checked, options = {})
|
|
431
432
|
#
|
|
432
433
|
# Creates a check box form input tag.
|
|
433
434
|
#
|
|
@@ -438,21 +439,21 @@ module ActionView
|
|
|
438
439
|
# * Any other key creates standard HTML options for the tag.
|
|
439
440
|
#
|
|
440
441
|
# ==== Examples
|
|
441
|
-
#
|
|
442
|
+
# checkbox_tag 'accept'
|
|
442
443
|
# # => <input id="accept" name="accept" type="checkbox" value="1" />
|
|
443
444
|
#
|
|
444
|
-
#
|
|
445
|
+
# checkbox_tag 'rock', 'rock music'
|
|
445
446
|
# # => <input id="rock" name="rock" type="checkbox" value="rock music" />
|
|
446
447
|
#
|
|
447
|
-
#
|
|
448
|
+
# checkbox_tag 'receive_email', 'yes', true
|
|
448
449
|
# # => <input checked="checked" id="receive_email" name="receive_email" type="checkbox" value="yes" />
|
|
449
450
|
#
|
|
450
|
-
#
|
|
451
|
+
# checkbox_tag 'tos', 'yes', false, class: 'accept_tos'
|
|
451
452
|
# # => <input class="accept_tos" id="tos" name="tos" type="checkbox" value="yes" />
|
|
452
453
|
#
|
|
453
|
-
#
|
|
454
|
+
# checkbox_tag 'eula', 'accepted', false, disabled: true
|
|
454
455
|
# # => <input disabled="disabled" id="eula" name="eula" type="checkbox" value="accepted" />
|
|
455
|
-
def
|
|
456
|
+
def checkbox_tag(name, *args)
|
|
456
457
|
if args.length >= 4
|
|
457
458
|
raise ArgumentError, "wrong number of arguments (given #{args.length + 1}, expected 1..4)"
|
|
458
459
|
end
|
|
@@ -462,6 +463,7 @@ module ActionView
|
|
|
462
463
|
html_options["checked"] = "checked" if checked
|
|
463
464
|
tag :input, html_options
|
|
464
465
|
end
|
|
466
|
+
alias_method :check_box_tag, :checkbox_tag
|
|
465
467
|
|
|
466
468
|
##
|
|
467
469
|
# :call-seq:
|
|
@@ -38,7 +38,8 @@ module ActionView # :nodoc:
|
|
|
38
38
|
|
|
39
39
|
# Converts the array to a comma-separated sentence where the last element is
|
|
40
40
|
# joined by the connector word. This is the html_safe-aware version of
|
|
41
|
-
# ActiveSupport's Array#to_sentence.
|
|
41
|
+
# ActiveSupport's {Array#to_sentence}[https://api.rubyonrails.org/classes/Array.html#method-i-to_sentence].
|
|
42
|
+
#
|
|
42
43
|
def to_sentence(array, options = {})
|
|
43
44
|
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
|
44
45
|
|
|
@@ -1,32 +1,140 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# :markup: markdown
|
|
4
|
+
|
|
3
5
|
module ActionView
|
|
4
6
|
module Helpers # :nodoc:
|
|
5
|
-
#
|
|
7
|
+
# # Action View Rendering Helpers
|
|
6
8
|
#
|
|
7
|
-
# Implements methods that allow rendering from a view context.
|
|
8
|
-
#
|
|
9
|
-
#
|
|
9
|
+
# Implements methods that allow rendering from a view context. In order to use
|
|
10
|
+
# this module, all you need is to implement view_renderer that returns an
|
|
11
|
+
# ActionView::Renderer object.
|
|
10
12
|
module RenderingHelper
|
|
11
|
-
#
|
|
13
|
+
# Renders a template and returns the result.
|
|
14
|
+
#
|
|
15
|
+
# Pass the template to render as the first argument. This is shorthand
|
|
16
|
+
# syntax for partial rendering, so the template filename should be
|
|
17
|
+
# prefixed with an underscore. The partial renderer looks for the partial
|
|
18
|
+
# template in the directory of the calling template first.
|
|
19
|
+
#
|
|
20
|
+
# <% # app/views/posts/new.html.erb %>
|
|
21
|
+
# <%= render "form" %>
|
|
22
|
+
# # => renders app/views/posts/_form.html.erb
|
|
23
|
+
#
|
|
24
|
+
# Use the complete view path to render a partial from another directory.
|
|
25
|
+
#
|
|
26
|
+
# <% # app/views/posts/show.html.erb %>
|
|
27
|
+
# <%= render "comments/form" %>
|
|
28
|
+
# # => renders app/views/comments/_form.html.erb
|
|
29
|
+
#
|
|
30
|
+
# Without the rendering mode, the second argument can be a Hash of local
|
|
31
|
+
# variable assignments for the template.
|
|
32
|
+
#
|
|
33
|
+
# <% # app/views/posts/new.html.erb %>
|
|
34
|
+
# <%= render "form", post: Post.new %>
|
|
35
|
+
# # => renders app/views/posts/_form.html.erb
|
|
36
|
+
#
|
|
37
|
+
# If the first argument responds to `render_in`, the template will be rendered
|
|
38
|
+
# by calling `render_in` with the current view context.
|
|
39
|
+
#
|
|
40
|
+
# class Greeting
|
|
41
|
+
# def render_in(view_context)
|
|
42
|
+
# view_context.render html: "<h1>Hello, World</h1>"
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# def format
|
|
46
|
+
# :html
|
|
47
|
+
# end
|
|
48
|
+
# end
|
|
49
|
+
#
|
|
50
|
+
# <%= render Greeting.new %>
|
|
51
|
+
# # => "<h1>Hello, World</h1>"
|
|
52
|
+
#
|
|
53
|
+
# #### Rendering Mode
|
|
54
|
+
#
|
|
55
|
+
# Pass the rendering mode as first argument to override it.
|
|
56
|
+
#
|
|
57
|
+
# `:partial`
|
|
58
|
+
# : See ActionView::PartialRenderer for details.
|
|
59
|
+
#
|
|
60
|
+
# <%= render partial: "form", locals: { post: Post.new } %>
|
|
61
|
+
# # => renders app/views/posts/_form.html.erb
|
|
62
|
+
#
|
|
63
|
+
# `:file`
|
|
64
|
+
# : Renders the contents of a file. This option should **not** be used with
|
|
65
|
+
# unsanitized user input.
|
|
66
|
+
#
|
|
67
|
+
# <%= render file: "/path/to/some/file" %>
|
|
68
|
+
# # => renders /path/to/some/file
|
|
69
|
+
#
|
|
70
|
+
# `:inline`
|
|
71
|
+
# : Renders an ERB template string.
|
|
72
|
+
#
|
|
73
|
+
# <% name = "World" %>
|
|
74
|
+
# <%= render inline: "<h1>Hello, <%= name %>!</h1>" %>
|
|
75
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
76
|
+
#
|
|
77
|
+
# `:body`
|
|
78
|
+
# : Renders the provided text, and sets the format as `:text`.
|
|
79
|
+
#
|
|
80
|
+
# <%= render body: "Hello, World!" %>
|
|
81
|
+
# # => renders "Hello, World!"
|
|
82
|
+
#
|
|
83
|
+
# `:plain`
|
|
84
|
+
# : Renders the provided text, and sets the format as `:text`.
|
|
85
|
+
#
|
|
86
|
+
# <%= render plain: "Hello, World!" %>
|
|
87
|
+
# # => renders "Hello, World!"
|
|
88
|
+
#
|
|
89
|
+
# `:html`
|
|
90
|
+
# : Renders the provided HTML string, and sets the format as
|
|
91
|
+
# `:html`. If the string is not `html_safe?`, performs HTML escaping on
|
|
92
|
+
# the string before rendering.
|
|
93
|
+
#
|
|
94
|
+
# <%= render html: "<h1>Hello, World!</h1>".html_safe %>
|
|
95
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
96
|
+
#
|
|
97
|
+
# <%= render html: "<h1>Hello, World!</h1>" %>
|
|
98
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
99
|
+
#
|
|
100
|
+
# `:renderable`
|
|
101
|
+
# : Renders the provided object by calling `render_in` with the current view
|
|
102
|
+
# context. The format is determined by calling `format` on the
|
|
103
|
+
# renderable if it responds to `format`, falling back to `:html` by
|
|
104
|
+
# default.
|
|
105
|
+
#
|
|
106
|
+
# <%= render renderable: Greeting.new %>
|
|
107
|
+
# # => renders "<h1>Hello, World</h1>"
|
|
108
|
+
#
|
|
109
|
+
#
|
|
110
|
+
# #### Options
|
|
111
|
+
#
|
|
112
|
+
# `:locals`
|
|
113
|
+
# : Hash of local variable assignments for the template.
|
|
114
|
+
#
|
|
115
|
+
# <%= render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" } %>
|
|
116
|
+
# # => renders "<h1>Hello, World!</h1>"
|
|
117
|
+
#
|
|
118
|
+
# `:formats`
|
|
119
|
+
# : Override the current format to render a template for a different format.
|
|
120
|
+
#
|
|
121
|
+
# <% # app/views/posts/show.html.erb %>
|
|
122
|
+
# <%= render template: "posts/content", formats: [:text] %>
|
|
123
|
+
# # => renders app/views/posts/content.text.erb
|
|
12
124
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
|
|
16
|
-
# * <tt>:plain</tt> - Renders the text passed in out. Setting the content
|
|
17
|
-
# type as <tt>text/plain</tt>.
|
|
18
|
-
# * <tt>:html</tt> - Renders the HTML safe string passed in out, otherwise
|
|
19
|
-
# performs HTML escape on the string first. Setting the content type as
|
|
20
|
-
# <tt>text/html</tt>.
|
|
21
|
-
# * <tt>:body</tt> - Renders the text passed in, and inherits the content
|
|
22
|
-
# type of <tt>text/plain</tt> from ActionDispatch::Response object.
|
|
125
|
+
# `:variants`
|
|
126
|
+
# : Render a template for a different variant.
|
|
23
127
|
#
|
|
24
|
-
#
|
|
128
|
+
# <% # app/views/posts/show.html.erb %>
|
|
129
|
+
# <%= render template: "posts/content", variants: [:tablet] %>
|
|
130
|
+
# # => renders app/views/posts/content.html+tablet.erb
|
|
25
131
|
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
132
|
+
# `:handlers`
|
|
133
|
+
# : Render a template for a different handler.
|
|
28
134
|
#
|
|
29
|
-
#
|
|
135
|
+
# <% # app/views/posts/show.html.erb %>
|
|
136
|
+
# <%= render template: "posts/content", handlers: [:builder] %>
|
|
137
|
+
# # => renders app/views/posts/content.html.builder
|
|
30
138
|
def render(options = {}, locals = {}, &block)
|
|
31
139
|
case options
|
|
32
140
|
when Hash
|
|
@@ -47,52 +155,54 @@ module ActionView
|
|
|
47
155
|
end
|
|
48
156
|
|
|
49
157
|
# Overrides _layout_for in the context object so it supports the case a block is
|
|
50
|
-
# passed to a partial. Returns the contents that are yielded to a layout, given
|
|
51
|
-
# name or a block.
|
|
158
|
+
# passed to a partial. Returns the contents that are yielded to a layout, given
|
|
159
|
+
# a name or a block.
|
|
52
160
|
#
|
|
53
|
-
# You can think of a layout as a method that is called with a block. If the user
|
|
54
|
-
#
|
|
55
|
-
# If the user calls simply
|
|
161
|
+
# You can think of a layout as a method that is called with a block. If the user
|
|
162
|
+
# calls `yield :some_name`, the block, by default, returns
|
|
163
|
+
# `content_for(:some_name)`. If the user calls simply `yield`, the default block
|
|
164
|
+
# returns `content_for(:layout)`.
|
|
56
165
|
#
|
|
57
166
|
# The user can override this default by passing a block to the layout:
|
|
58
167
|
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
168
|
+
# # The template
|
|
169
|
+
# <%= render layout: "my_layout" do %>
|
|
170
|
+
# Content
|
|
171
|
+
# <% end %>
|
|
63
172
|
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
173
|
+
# # The layout
|
|
174
|
+
# <html>
|
|
175
|
+
# <%= yield %>
|
|
176
|
+
# </html>
|
|
68
177
|
#
|
|
69
|
-
# In this case, instead of the default block, which would return
|
|
70
|
-
# this method returns the block that was passed in to
|
|
178
|
+
# In this case, instead of the default block, which would return `content_for(:layout)`,
|
|
179
|
+
# this method returns the block that was passed in to `render :layout`, and the response
|
|
71
180
|
# would be
|
|
72
181
|
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
182
|
+
# <html>
|
|
183
|
+
# Content
|
|
184
|
+
# </html>
|
|
76
185
|
#
|
|
77
|
-
# Finally, the block can take block arguments, which can be passed in by
|
|
186
|
+
# Finally, the block can take block arguments, which can be passed in by
|
|
187
|
+
# `yield`:
|
|
78
188
|
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
189
|
+
# # The template
|
|
190
|
+
# <%= render layout: "my_layout" do |customer| %>
|
|
191
|
+
# Hello <%= customer.name %>
|
|
192
|
+
# <% end %>
|
|
83
193
|
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
194
|
+
# # The layout
|
|
195
|
+
# <html>
|
|
196
|
+
# <%= yield Struct.new(:name).new("David") %>
|
|
197
|
+
# </html>
|
|
88
198
|
#
|
|
89
|
-
# In this case, the layout would receive the block passed into
|
|
199
|
+
# In this case, the layout would receive the block passed into `render :layout`,
|
|
90
200
|
# and the struct specified would be passed into the block as an argument. The result
|
|
91
201
|
# would be
|
|
92
202
|
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
203
|
+
# <html>
|
|
204
|
+
# Hello David
|
|
205
|
+
# </html>
|
|
96
206
|
#
|
|
97
207
|
def _layout_for(*args, &block)
|
|
98
208
|
name = args.first
|
|
@@ -48,48 +48,51 @@ module ActionView
|
|
|
48
48
|
include CaptureHelper
|
|
49
49
|
include OutputSafetyHelper
|
|
50
50
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
def deprecated_void_content(name)
|
|
52
|
+
ActionView.deprecator.warn <<~TEXT
|
|
53
|
+
Putting content inside a void element (#{name}) is invalid
|
|
54
|
+
according to the HTML5 spec, and so it is being deprecated
|
|
55
|
+
without replacement. In Rails 8.0, passing content as a
|
|
56
|
+
positional argument will raise, and using a block will have
|
|
57
|
+
no effect.
|
|
58
|
+
TEXT
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.define_element(name, code_generator:, method_name: name)
|
|
62
|
+
return if method_defined?(name)
|
|
63
|
+
|
|
64
|
+
code_generator.class_eval do |batch|
|
|
65
|
+
batch << "\n" <<
|
|
66
|
+
"def #{method_name}(content = nil, escape: true, **options, &block)" <<
|
|
67
|
+
" tag_string(#{name.inspect}, content, options, escape: escape, &block)" <<
|
|
68
|
+
"end"
|
|
58
69
|
end
|
|
59
70
|
end
|
|
60
71
|
|
|
61
|
-
def self.define_void_element(name, code_generator:, method_name: name
|
|
62
|
-
code_generator.
|
|
63
|
-
batch
|
|
64
|
-
def #{method_name}(content = nil, escape: true, **options, &block)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
TEXT
|
|
73
|
-
tag_string("#{name}", content, options, escape: escape, &block)
|
|
74
|
-
else
|
|
75
|
-
self_closing_tag_string("#{name}", options, escape, ">")
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
RUBY
|
|
72
|
+
def self.define_void_element(name, code_generator:, method_name: name)
|
|
73
|
+
code_generator.class_eval do |batch|
|
|
74
|
+
batch << "\n" <<
|
|
75
|
+
"def #{method_name}(content = nil, escape: true, **options, &block)" <<
|
|
76
|
+
" if content || block" <<
|
|
77
|
+
" deprecated_void_content(#{name.inspect})" <<
|
|
78
|
+
" tag_string(#{name.inspect}, content, options, escape: escape, &block)" <<
|
|
79
|
+
" else" <<
|
|
80
|
+
" self_closing_tag_string(#{name.inspect}, options, escape, '>')" <<
|
|
81
|
+
" end" <<
|
|
82
|
+
"end"
|
|
79
83
|
end
|
|
80
84
|
end
|
|
81
85
|
|
|
82
|
-
def self.define_self_closing_element(name, code_generator:, method_name: name
|
|
83
|
-
code_generator.
|
|
84
|
-
batch
|
|
85
|
-
def #{method_name}(content = nil, escape: true, **options, &block)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
end
|
|
92
|
-
RUBY
|
|
86
|
+
def self.define_self_closing_element(name, code_generator:, method_name: name)
|
|
87
|
+
code_generator.class_eval do |batch|
|
|
88
|
+
batch << "\n" <<
|
|
89
|
+
"def #{method_name}(content = nil, escape: true, **options, &block)" <<
|
|
90
|
+
" if content || block" <<
|
|
91
|
+
" tag_string(#{name.inspect}, content, options, escape: escape, &block)" <<
|
|
92
|
+
" else" <<
|
|
93
|
+
" self_closing_tag_string(#{name.inspect}, options, escape)" <<
|
|
94
|
+
" end" <<
|
|
95
|
+
"end"
|
|
93
96
|
end
|
|
94
97
|
end
|
|
95
98
|
|
|
@@ -110,8 +113,8 @@ module ActionView
|
|
|
110
113
|
define_void_element :wbr, code_generator: code_generator
|
|
111
114
|
|
|
112
115
|
define_self_closing_element :animate, code_generator: code_generator
|
|
113
|
-
define_self_closing_element :animateMotion, code_generator: code_generator
|
|
114
|
-
define_self_closing_element :animateTransform, code_generator: code_generator
|
|
116
|
+
define_self_closing_element :animateMotion, code_generator: code_generator, method_name: :animate_motion
|
|
117
|
+
define_self_closing_element :animateTransform, code_generator: code_generator, method_name: :animate_transform
|
|
115
118
|
define_self_closing_element :circle, code_generator: code_generator
|
|
116
119
|
define_self_closing_element :ellipse, code_generator: code_generator
|
|
117
120
|
define_self_closing_element :line, code_generator: code_generator
|
|
@@ -10,12 +10,13 @@ module ActionView
|
|
|
10
10
|
include FormOptionsHelper
|
|
11
11
|
|
|
12
12
|
class CheckBoxBuilder < Builder # :nodoc:
|
|
13
|
-
def
|
|
13
|
+
def checkbox(extra_html_options = {})
|
|
14
14
|
html_options = extra_html_options.merge(@input_html_options)
|
|
15
15
|
html_options[:multiple] = true
|
|
16
16
|
html_options[:skip_default_ids] = false
|
|
17
|
-
@template_object.
|
|
17
|
+
@template_object.checkbox(@object_name, @method_name, html_options, @value, nil)
|
|
18
18
|
end
|
|
19
|
+
alias_method :check_box, :checkbox
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def render(&block)
|
|
@@ -24,7 +25,7 @@ module ActionView
|
|
|
24
25
|
|
|
25
26
|
private
|
|
26
27
|
def render_component(builder)
|
|
27
|
-
builder.
|
|
28
|
+
builder.checkbox + builder.label
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def hidden_field_name
|
|
@@ -106,8 +106,7 @@ module ActionView
|
|
|
106
106
|
|
|
107
107
|
def hidden_field
|
|
108
108
|
hidden_name = @html_options[:name] || hidden_field_name
|
|
109
|
-
|
|
110
|
-
@template_object.hidden_field_tag(hidden_name, "", options)
|
|
109
|
+
@template_object.hidden_field_tag(hidden_name, "", id: nil)
|
|
111
110
|
end
|
|
112
111
|
|
|
113
112
|
def hidden_field_name
|
|
@@ -166,7 +166,7 @@ module ActionView
|
|
|
166
166
|
# highlight('You searched for: rails', 'rails', highlighter: '<a href="search?q=\1">\1</a>')
|
|
167
167
|
# # => "You searched for: <a href=\"search?q=rails\">rails</a>"
|
|
168
168
|
#
|
|
169
|
-
# highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match)) }
|
|
169
|
+
# highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match, match)) }
|
|
170
170
|
# # => "You searched for: <a href=\"search?q=rails\">rails</a>"
|
|
171
171
|
#
|
|
172
172
|
# highlight('<a href="javascript:alert(\'no!\')">ruby</a> on rails', 'rails', sanitize: false)
|
|
@@ -260,14 +260,7 @@ module ActionView
|
|
|
260
260
|
prefix, first_part = cut_excerpt_part(:first, first_part, separator, options)
|
|
261
261
|
postfix, second_part = cut_excerpt_part(:second, second_part, separator, options)
|
|
262
262
|
|
|
263
|
-
affix = [
|
|
264
|
-
first_part,
|
|
265
|
-
!first_part.empty? ? separator : "",
|
|
266
|
-
phrase,
|
|
267
|
-
!second_part.empty? ? separator : "",
|
|
268
|
-
second_part
|
|
269
|
-
].join.strip
|
|
270
|
-
|
|
263
|
+
affix = [first_part, separator, phrase, separator, second_part].join.strip
|
|
271
264
|
[prefix, affix, postfix].join
|
|
272
265
|
end
|
|
273
266
|
|
|
@@ -278,7 +271,7 @@ module ActionView
|
|
|
278
271
|
#
|
|
279
272
|
# The word will be pluralized using rules defined for the locale
|
|
280
273
|
# (you must define your own inflection rules for languages other than English).
|
|
281
|
-
# See ActiveSupport::Inflector.pluralize
|
|
274
|
+
# See ActiveSupport::Inflector.pluralize
|
|
282
275
|
#
|
|
283
276
|
# pluralize(1, 'person')
|
|
284
277
|
# # => "1 person"
|
|
@@ -353,7 +346,7 @@ module ActionView
|
|
|
353
346
|
# ==== Options
|
|
354
347
|
# * <tt>:sanitize</tt> - If +false+, does not sanitize +text+.
|
|
355
348
|
# * <tt>:sanitize_options</tt> - Any extra options you want appended to the sanitize.
|
|
356
|
-
# * <tt>:wrapper_tag</tt> - String representing the wrapper tag, defaults to <tt>"p"</tt
|
|
349
|
+
# * <tt>:wrapper_tag</tt> - String representing the wrapper tag, defaults to <tt>"p"</tt>
|
|
357
350
|
#
|
|
358
351
|
# ==== Examples
|
|
359
352
|
# my_text = "Here is some basic text...\n...with a line break."
|