actionview 7.0.4.3 → 7.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c5e82261a3ce6545cd9da95815e27508878283047dfa4cf62f88c8f171b44d2
4
- data.tar.gz: fa0c7f1e6a1fb7e8ce87f6207f9030a91aee87024e5668b429ab24f27c092586
3
+ metadata.gz: cf696a7a48e0b6e50f6bf99b5785e13508eb0dd4db6d8e2d2718426d06bfb588
4
+ data.tar.gz: 1b09f452de6f2c9c6e402fe2a599729a695017670da1e0d573b5880a4f1fc56f
5
5
  SHA512:
6
- metadata.gz: 7bea507511dc206ecaac5d6f216fa80b74d63fa6571d3ee58ef2d58dc55d306e449fc864de6500402e4dfe24bee2444668d4afa9287bff42ca8e408867d361b0
7
- data.tar.gz: accb8dabd32a6b53f7fc1f2c1f05b2ae4cee32393799c9d71e2ec0a6e4b376dbebb44dac9a8b130b383cb9bc438246a2a82d37b31ed4689ca38c730b50ede2fd
6
+ metadata.gz: 26fbd17c95aca83483cd7b5803636cd2722523244f36799fddcc3c84d1d850a5e2be543e6c7c3457a2412c42c3464a1fcb7afb69f911dd7d5a37a53e10c8e668
7
+ data.tar.gz: d51e7cab7e610b0ece90aebbd6fa411b34b9d179c5cbd09f105bf7151fda435b706bb97e930d94a8866d8054d6422a443e72c5e6af7ce77c1820fd2cb0dfdede
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## Rails 7.0.5 (May 24, 2023) ##
2
+
3
+ * `FormBuilder#id` finds id set by `form_for` and `form_with`.
4
+
5
+ *Matt Polito*
6
+
7
+ * Allow all available locales for template lookups.
8
+
9
+ *Ben Dilley*
10
+
11
+ * Choices of `select` can optionally contain html attributes as the last element
12
+ of the child arrays when using grouped/nested collections
13
+
14
+ ```erb
15
+ <%= form.select :foo, [["North America", [["United States","US"],["Canada","CA"]], { disabled: "disabled" }]] %>
16
+ # => <select><optgroup label="North America" disabled="disabled"><option value="US">United States</option><option value="CA">Canada</option></optgroup></select>
17
+ ```
18
+
19
+ *Chris Gunther*
20
+
21
+
1
22
  ## Rails 7.0.4.3 (March 13, 2023) ##
2
23
 
3
24
  * Ignore certain data-* attributes in rails-ujs when element is contenteditable
@@ -9,8 +9,8 @@ module ActionView
9
9
  module VERSION
10
10
  MAJOR = 7
11
11
  MINOR = 0
12
- TINY = 4
13
- PRE = "3"
12
+ TINY = 5
13
+ PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -41,7 +41,7 @@ module ActionView
41
41
  # When the Asset Pipeline is enabled, you can pass the name of your manifest as
42
42
  # source, and include other JavaScript or CoffeeScript files inside the manifest.
43
43
  #
44
- # If the server supports Early Hints header links for these assets will be
44
+ # If the server supports Early Hints, header links for these assets will be
45
45
  # automatically pushed.
46
46
  #
47
47
  # ==== Options
@@ -130,7 +130,7 @@ module ActionView
130
130
  # set <tt>extname: false</tt> in the options.
131
131
  # You can modify the link attributes by passing a hash as the last argument.
132
132
  #
133
- # If the server supports Early Hints header links for these assets will be
133
+ # If the server supports Early Hints, header links for these assets will be
134
134
  # automatically pushed.
135
135
  #
136
136
  # ==== Options
@@ -121,7 +121,7 @@ module ActionView
121
121
  # <li><%= link_to 'Home', action: 'index' %></li>
122
122
  # <% end %>
123
123
  #
124
- # And in another place:
124
+ # And in another place:
125
125
  #
126
126
  # <% content_for :navigation do %>
127
127
  # <li><%= link_to 'Login', action: 'login' %></li>
@@ -137,7 +137,7 @@ module ActionView
137
137
  # <li><%= link_to 'Home', action: 'index' %></li>
138
138
  # <% end %>
139
139
  #
140
- # <%# Add some other content, or use a different template: %>
140
+ # <%# Add some other content, or use a different template: %>
141
141
  #
142
142
  # <% content_for :navigation, flush: true do %>
143
143
  # <li><%= link_to 'Login', action: 'login' %></li>
@@ -17,7 +17,7 @@ module ActionView
17
17
  # You don't need to use these tags for regular forms as they generate their own hidden fields.
18
18
  #
19
19
  # For AJAX requests other than GETs, extract the "csrf-token" from the meta-tag and send as the
20
- # "X-CSRF-Token" HTTP header. If you are using rails-ujs this happens automatically.
20
+ # +X-CSRF-Token+ HTTP header. If you are using rails-ujs, this happens automatically.
21
21
  #
22
22
  def csrf_meta_tags
23
23
  if defined?(protect_against_forgery?) && protect_against_forgery?
@@ -1001,22 +1001,25 @@ module ActionView
1001
1001
  end
1002
1002
 
1003
1003
  # Build select option HTML from date value and options.
1004
- # build_options(15, start: 1, end: 31)
1005
- # => "<option value="1">1</option>
1006
- # <option value="2">2</option>
1007
- # <option value="3">3</option>..."
1008
1004
  #
1009
- # If <tt>use_two_digit_numbers: true</tt> option is passed
1010
- # build_options(15, start: 1, end: 31, use_two_digit_numbers: true)
1011
- # => "<option value="1">01</option>
1012
- # <option value="2">02</option>
1013
- # <option value="3">03</option>..."
1005
+ # build_options(15, start: 1, end: 31)
1006
+ # => "<option value="1">1</option>
1007
+ # <option value="2">2</option>
1008
+ # <option value="3">3</option>..."
1014
1009
  #
1015
- # If <tt>:step</tt> options is passed
1016
- # build_options(15, start: 1, end: 31, step: 2)
1017
- # => "<option value="1">1</option>
1018
- # <option value="3">3</option>
1019
- # <option value="5">5</option>..."
1010
+ # If <tt>use_two_digit_numbers: true</tt> option is passed:
1011
+ #
1012
+ # build_options(15, start: 1, end: 31, use_two_digit_numbers: true)
1013
+ # => "<option value="1">01</option>
1014
+ # <option value="2">02</option>
1015
+ # <option value="3">03</option>..."
1016
+ #
1017
+ # If <tt>:step</tt> options is passed:
1018
+ #
1019
+ # build_options(15, start: 1, end: 31, step: 2)
1020
+ # => "<option value="1">1</option>
1021
+ # <option value="3">3</option>
1022
+ # <option value="5">5</option>..."
1020
1023
  def build_options(selected, options = {})
1021
1024
  options = {
1022
1025
  leading_zeros: true, ampm: false, use_two_digit_numbers: false
@@ -1041,22 +1044,25 @@ module ActionView
1041
1044
  end
1042
1045
 
1043
1046
  # Build select option HTML for day.
1044
- # build_day_options(2)
1045
- # => "<option value="1">1</option>
1046
- # <option value="2" selected="selected">2</option>
1047
- # <option value="3">3</option>..."
1047
+ #
1048
+ # build_day_options(2)
1049
+ # => "<option value="1">1</option>
1050
+ # <option value="2" selected="selected">2</option>
1051
+ # <option value="3">3</option>..."
1048
1052
  #
1049
1053
  # If <tt>day_format: ->(day) { day.ordinalize }</tt> option is passed to DateTimeSelector
1050
- # build_day_options(2)
1051
- # => "<option value="1">1st</option>
1052
- # <option value="2" selected="selected">2nd</option>
1053
- # <option value="3">3rd</option>..."
1054
+ #
1055
+ # build_day_options(2)
1056
+ # => "<option value="1">1st</option>
1057
+ # <option value="2" selected="selected">2nd</option>
1058
+ # <option value="3">3rd</option>..."
1054
1059
  #
1055
1060
  # If <tt>use_two_digit_numbers: true</tt> option is passed to DateTimeSelector
1056
- # build_day_options(2)
1057
- # => "<option value="1">01</option>
1058
- # <option value="2" selected="selected">02</option>
1059
- # <option value="3">03</option>..."
1061
+ #
1062
+ # build_day_options(2)
1063
+ # => "<option value="1">01</option>
1064
+ # <option value="2" selected="selected">02</option>
1065
+ # <option value="3">03</option>..."
1060
1066
  def build_day_options(selected)
1061
1067
  select_options = []
1062
1068
  (1..31).each do |value|
@@ -1071,16 +1077,16 @@ module ActionView
1071
1077
 
1072
1078
  # Build select option HTML for year.
1073
1079
  # If <tt>year_format</tt> option is not passed
1074
- # build_year_options(1998, start: 1998, end: 2000)
1075
- # => "<option value="1998" selected="selected">1998</option>
1076
- # <option value="1999">1999</option>
1077
- # <option value="2000">2000</option>"
1080
+ # build_year_options(1998, start: 1998, end: 2000)
1081
+ # => "<option value="1998" selected="selected">1998</option>
1082
+ # <option value="1999">1999</option>
1083
+ # <option value="2000">2000</option>"
1078
1084
  #
1079
1085
  # If <tt>year_format</tt> option is passed
1080
- # build_year_options(1998, start: 1998, end: 2000, year_format: ->year { "Heisei #{ year - 1988 }" })
1081
- # => "<option value="1998" selected="selected">Heisei 10</option>
1082
- # <option value="1999">Heisei 11</option>
1083
- # <option value="2000">Heisei 12</option>"
1086
+ # build_year_options(1998, start: 1998, end: 2000, year_format: ->year { "Heisei #{ year - 1988 }" })
1087
+ # => "<option value="1998" selected="selected">Heisei 10</option>
1088
+ # <option value="1999">Heisei 11</option>
1089
+ # <option value="2000">Heisei 12</option>"
1084
1090
  def build_year_options(selected, options = {})
1085
1091
  start = options.delete(:start)
1086
1092
  stop = options.delete(:end)
@@ -1098,10 +1104,11 @@ module ActionView
1098
1104
  end
1099
1105
 
1100
1106
  # Builds select tag from date type and HTML select options.
1101
- # build_select(:month, "<option value="1">January</option>...")
1102
- # => "<select id="post_written_on_2i" name="post[written_on(2i)]">
1103
- # <option value="1">January</option>...
1104
- # </select>"
1107
+ #
1108
+ # build_select(:month, "<option value="1">January</option>...")
1109
+ # => "<select id="post_written_on_2i" name="post[written_on(2i)]">
1110
+ # <option value="1">January</option>...
1111
+ # </select>"
1105
1112
  def build_select(type, select_options_as_html)
1106
1113
  select_options = {
1107
1114
  id: input_id_from_type(type),
@@ -1118,9 +1125,10 @@ module ActionView
1118
1125
  (content_tag("select", select_html.html_safe, select_options) + "\n").html_safe
1119
1126
  end
1120
1127
 
1121
- # Builds the CSS class value for the select element
1122
- # css_class_attribute(:year, 'date optional', { year: 'my-year' })
1123
- # => "date optional my-year"
1128
+ # Builds the CSS class value for the select element.
1129
+ #
1130
+ # css_class_attribute(:year, 'date optional', { year: 'my-year' })
1131
+ # => "date optional my-year"
1124
1132
  def css_class_attribute(type, html_options_class, options) # :nodoc:
1125
1133
  css_class = \
1126
1134
  case options
@@ -1134,8 +1142,9 @@ module ActionView
1134
1142
  end
1135
1143
 
1136
1144
  # Builds a prompt option tag with supplied options or from default options.
1137
- # prompt_option_tag(:month, prompt: 'Select month')
1138
- # => "<option value="">Select month</option>"
1145
+ #
1146
+ # prompt_option_tag(:month, prompt: 'Select month')
1147
+ # => "<option value="">Select month</option>"
1139
1148
  def prompt_option_tag(type, options)
1140
1149
  prompt = \
1141
1150
  case options
@@ -1152,8 +1161,9 @@ module ActionView
1152
1161
  end
1153
1162
 
1154
1163
  # Builds hidden input tag for date part and value.
1155
- # build_hidden(:year, 2008)
1156
- # => "<input type="hidden" id="date_year" name="date[year]" value="2008" autocomplete="off" />"
1164
+ #
1165
+ # build_hidden(:year, 2008)
1166
+ # => "<input type="hidden" id="date_year" name="date[year]" value="2008" autocomplete="off" />"
1157
1167
  def build_hidden(type, value)
1158
1168
  select_options = {
1159
1169
  type: "hidden",
@@ -1735,7 +1735,7 @@ module ActionView
1735
1735
  # <tt><button></tt> element should be treated as the <tt><form></tt>
1736
1736
  # element's submit button, regardless of where it exists in the DOM.
1737
1737
  def id
1738
- options.dig(:html, :id)
1738
+ options.dig(:html, :id) || options[:id]
1739
1739
  end
1740
1740
 
1741
1741
  # Generate an HTML <tt>id</tt> attribute value for the given field
@@ -500,6 +500,8 @@ module ActionView
500
500
  # <tt><optgroup></tt> label while the second value must be an array of options. The second value can be a
501
501
  # nested array of text-value pairs. See <tt>options_for_select</tt> for more info.
502
502
  # Ex. ["North America",[["United States","US"],["Canada","CA"]]]
503
+ # An optional third value can be provided as HTML attributes for the <tt>optgroup</tt>.
504
+ # Ex. ["North America",[["United States","US"],["Canada","CA"]], { disabled: "disabled" }]
503
505
  # * +selected_key+ - A value equal to the +value+ attribute for one of the <tt><option></tt> tags,
504
506
  # which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
505
507
  # as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
@@ -202,7 +202,7 @@ module ActionView
202
202
  # number_with_delimiter("123456.78",
203
203
  # delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/) # => "1,23,456.78"
204
204
  #
205
- # number_with_delimiter("112a", raise: true) # => raise InvalidNumberError
205
+ # number_with_delimiter("112a", raise: true) # => raise InvalidNumberError
206
206
  def number_with_delimiter(number, options = {})
207
207
  delegate_number_helper_method(:number_to_delimited, number, options)
208
208
  end
@@ -370,13 +370,14 @@ module ActionView
370
370
  # out by default (set <tt>:strip_insignificant_zeros</tt> to
371
371
  # +false+ to change that):
372
372
  #
373
- # number_to_human(12.00001) # => "12"
374
- # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
373
+ # number_to_human(12.00001) # => "12"
374
+ # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
375
375
  #
376
376
  # ==== Custom Unit Quantifiers
377
377
  #
378
378
  # You can also use your own custom unit quantifiers:
379
- # number_to_human(500000, units: {unit: "ml", thousand: "lt"}) # => "500 lt"
379
+ #
380
+ # number_to_human(500000, units: {unit: "ml", thousand: "lt"}) # => "500 lt"
380
381
  #
381
382
  # If in your I18n locale you have:
382
383
  # distance:
@@ -393,12 +394,12 @@ module ActionView
393
394
  #
394
395
  # Then you could do:
395
396
  #
396
- # number_to_human(543934, units: :distance) # => "544 kilometers"
397
- # number_to_human(54393498, units: :distance) # => "54400 kilometers"
398
- # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
399
- # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
400
- # number_to_human(1, units: :distance) # => "1 meter"
401
- # number_to_human(0.34, units: :distance) # => "34 centimeters"
397
+ # number_to_human(543934, units: :distance) # => "544 kilometers"
398
+ # number_to_human(54393498, units: :distance) # => "54400 kilometers"
399
+ # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
400
+ # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
401
+ # number_to_human(1, units: :distance) # => "1 meter"
402
+ # number_to_human(0.34, units: :distance) # => "34 centimeters"
402
403
  #
403
404
  def number_to_human(number, options = {})
404
405
  delegate_number_helper_method(:number_to_human, number, options)
@@ -13,8 +13,8 @@ module ActionView # :nodoc:
13
13
  #
14
14
  # For example:
15
15
  #
16
- # raw @user.name
17
- # # => 'Jimmy <alert>Tables</alert>'
16
+ # raw @user.name
17
+ # # => 'Jimmy <alert>Tables</alert>'
18
18
  def raw(stringish)
19
19
  stringish.to_s.html_safe
20
20
  end
@@ -34,7 +34,7 @@ module ActionView
34
34
  # [nil, []]
35
35
  # { nil => [] }
36
36
  def grouped_choices?
37
- !@choices.blank? && @choices.first.respond_to?(:last) && Array === @choices.first.last
37
+ !@choices.blank? && @choices.first.respond_to?(:second) && Array === @choices.first.second
38
38
  end
39
39
  end
40
40
  end
@@ -492,7 +492,7 @@ module ActionView
492
492
  # * <tt>:body</tt> - Preset the body of the email.
493
493
  # * <tt>:cc</tt> - Carbon Copy additional recipients on the email.
494
494
  # * <tt>:bcc</tt> - Blind Carbon Copy additional recipients on the email.
495
- # * <tt>:reply_to</tt> - Preset the Reply-To field of the email.
495
+ # * <tt>:reply_to</tt> - Preset the +Reply-To+ field of the email.
496
496
  #
497
497
  # ==== Obfuscation
498
498
  # Prior to Rails 4.0, +mail_to+ provided options for encoding the address
@@ -6,14 +6,14 @@ module ActionView
6
6
  module RoutingUrlFor
7
7
  # Returns the URL for the set of +options+ provided. This takes the
8
8
  # same options as +url_for+ in Action Controller (see the
9
- # documentation for <tt>ActionController::Base#url_for</tt>). Note that by default
10
- # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative "/controller/action"
11
- # instead of the fully qualified URL like "http://example.com/controller/action".
9
+ # documentation for ActionDispatch::Routing::UrlFor#url_for). Note that by default
10
+ # <tt>:only_path</tt> is <tt>true</tt> so you'll get the relative <tt>"/controller/action"</tt>
11
+ # instead of the fully qualified URL like <tt>"http://example.com/controller/action"</tt>.
12
12
  #
13
13
  # ==== Options
14
14
  # * <tt>:anchor</tt> - Specifies the anchor name to be appended to the path.
15
15
  # * <tt>:only_path</tt> - If true, returns the relative URL (omitting the protocol, host name, and port) (<tt>true</tt> by default unless <tt>:host</tt> is specified).
16
- # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2005/". Note that this
16
+ # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in <tt>"/archive/2005/"</tt>. Note that this
17
17
  # is currently not recommended since it breaks caching.
18
18
  # * <tt>:host</tt> - Overrides the default (current) host if provided.
19
19
  # * <tt>:protocol</tt> - Overrides the default (current) protocol if provided.
@@ -17,9 +17,11 @@ module ActionView
17
17
  ParsedPath = Struct.new(:path, :details)
18
18
 
19
19
  def build_path_regex
20
- handlers = Template::Handlers.extensions.map { |x| Regexp.escape(x) }.join("|")
21
- formats = Template::Types.symbols.map { |x| Regexp.escape(x) }.join("|")
22
- locales = "[a-z]{2}(?:[-_][A-Z]{2})?"
20
+ handlers = Regexp.union(Template::Handlers.extensions.map(&:to_s))
21
+ formats = Regexp.union(Template::Types.symbols.map(&:to_s))
22
+ available_locales = I18n.available_locales.map(&:to_s)
23
+ regular_locales = [/[a-z]{2}(?:[-_][A-Z]{2})?/]
24
+ locales = Regexp.union(available_locales + regular_locales)
23
25
  variants = "[^.]*"
24
26
 
25
27
  %r{
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionview
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.4.3
4
+ version: 7.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-13 00:00:00.000000000 Z
11
+ date: 2023-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.4.3
19
+ version: 7.0.5
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.4.3
26
+ version: 7.0.5
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: builder
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -92,28 +92,28 @@ dependencies:
92
92
  requirements:
93
93
  - - '='
94
94
  - !ruby/object:Gem::Version
95
- version: 7.0.4.3
95
+ version: 7.0.5
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - '='
101
101
  - !ruby/object:Gem::Version
102
- version: 7.0.4.3
102
+ version: 7.0.5
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: activemodel
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: 7.0.4.3
109
+ version: 7.0.5
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - '='
115
115
  - !ruby/object:Gem::Version
116
- version: 7.0.4.3
116
+ version: 7.0.5
117
117
  description: Simple, battle-tested conventions and helpers for building web pages.
118
118
  email: david@loudthinking.com
119
119
  executables: []
@@ -246,12 +246,12 @@ licenses:
246
246
  - MIT
247
247
  metadata:
248
248
  bug_tracker_uri: https://github.com/rails/rails/issues
249
- changelog_uri: https://github.com/rails/rails/blob/v7.0.4.3/actionview/CHANGELOG.md
250
- documentation_uri: https://api.rubyonrails.org/v7.0.4.3/
249
+ changelog_uri: https://github.com/rails/rails/blob/v7.0.5/actionview/CHANGELOG.md
250
+ documentation_uri: https://api.rubyonrails.org/v7.0.5/
251
251
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
252
- source_code_uri: https://github.com/rails/rails/tree/v7.0.4.3/actionview
252
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.5/actionview
253
253
  rubygems_mfa_required: 'true'
254
- post_install_message:
254
+ post_install_message:
255
255
  rdoc_options: []
256
256
  require_paths:
257
257
  - lib
@@ -267,8 +267,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
267
  version: '0'
268
268
  requirements:
269
269
  - none
270
- rubygems_version: 3.4.3
271
- signing_key:
270
+ rubygems_version: 3.4.10
271
+ signing_key:
272
272
  specification_version: 4
273
273
  summary: Rendering framework putting the V in MVC (part of Rails).
274
274
  test_files: []