actionview 6.1.7.10 → 7.0.0.alpha1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -409
- data/MIT-LICENSE +2 -1
- data/lib/action_view/base.rb +3 -3
- data/lib/action_view/buffers.rb +2 -2
- data/lib/action_view/cache_expiry.rb +46 -32
- data/lib/action_view/dependency_tracker/erb_tracker.rb +154 -0
- data/lib/action_view/dependency_tracker/ripper_tracker.rb +59 -0
- data/lib/action_view/dependency_tracker.rb +6 -147
- data/lib/action_view/digestor.rb +7 -4
- data/lib/action_view/flows.rb +4 -4
- data/lib/action_view/gem_version.rb +4 -4
- data/lib/action_view/helpers/active_model_helper.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +84 -29
- data/lib/action_view/helpers/asset_url_helper.rb +7 -7
- data/lib/action_view/helpers/atom_feed_helper.rb +3 -4
- data/lib/action_view/helpers/cache_helper.rb +51 -3
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/controller_helper.rb +2 -2
- data/lib/action_view/helpers/csp_helper.rb +1 -1
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +6 -7
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +72 -12
- data/lib/action_view/helpers/form_options_helper.rb +65 -33
- data/lib/action_view/helpers/form_tag_helper.rb +75 -32
- data/lib/action_view/helpers/javascript_helper.rb +3 -5
- data/lib/action_view/helpers/number_helper.rb +3 -4
- data/lib/action_view/helpers/output_safety_helper.rb +2 -2
- data/lib/action_view/helpers/rendering_helper.rb +1 -1
- data/lib/action_view/helpers/sanitize_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +25 -44
- data/lib/action_view/helpers/tags/base.rb +3 -15
- data/lib/action_view/helpers/tags/check_box.rb +2 -2
- data/lib/action_view/helpers/tags/collection_select.rb +1 -1
- data/lib/action_view/helpers/tags/hidden_field.rb +0 -4
- data/lib/action_view/helpers/tags/time_field.rb +10 -1
- data/lib/action_view/helpers/tags/weekday_select.rb +27 -0
- data/lib/action_view/helpers/tags.rb +3 -2
- data/lib/action_view/helpers/text_helper.rb +24 -13
- data/lib/action_view/helpers/translation_helper.rb +1 -2
- data/lib/action_view/helpers/url_helper.rb +102 -77
- data/lib/action_view/helpers.rb +25 -25
- data/lib/action_view/lookup_context.rb +33 -52
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +16 -22
- data/lib/action_view/railtie.rb +14 -1
- data/lib/action_view/render_parser.rb +188 -0
- data/lib/action_view/renderer/abstract_renderer.rb +2 -2
- data/lib/action_view/renderer/partial_renderer.rb +0 -34
- data/lib/action_view/renderer/renderer.rb +4 -4
- data/lib/action_view/renderer/streaming_template_renderer.rb +3 -3
- data/lib/action_view/renderer/template_renderer.rb +6 -2
- data/lib/action_view/rendering.rb +2 -2
- data/lib/action_view/ripper_ast_parser.rb +198 -0
- data/lib/action_view/routing_url_for.rb +1 -1
- data/lib/action_view/template/error.rb +108 -13
- data/lib/action_view/template/handlers/erb.rb +6 -0
- data/lib/action_view/template/handlers.rb +3 -3
- data/lib/action_view/template/html.rb +3 -3
- data/lib/action_view/template/inline.rb +3 -3
- data/lib/action_view/template/raw_file.rb +3 -3
- data/lib/action_view/template/resolver.rb +84 -311
- data/lib/action_view/template/text.rb +3 -3
- data/lib/action_view/template/types.rb +14 -12
- data/lib/action_view/template.rb +10 -1
- data/lib/action_view/template_details.rb +66 -0
- data/lib/action_view/template_path.rb +64 -0
- data/lib/action_view/test_case.rb +6 -2
- data/lib/action_view/testing/resolvers.rb +11 -12
- data/lib/action_view/unbound_template.rb +33 -7
- data/lib/action_view.rb +3 -4
- data/lib/assets/compiled/rails-ujs.js +5 -36
- metadata +22 -16
@@ -24,6 +24,10 @@ module ActionView
|
|
24
24
|
self.class.controller_path = path
|
25
25
|
end
|
26
26
|
|
27
|
+
def self.controller_name
|
28
|
+
"test"
|
29
|
+
end
|
30
|
+
|
27
31
|
def initialize
|
28
32
|
super
|
29
33
|
self.class.controller_path = ""
|
@@ -74,11 +78,11 @@ module ActionView
|
|
74
78
|
def helper_method(*methods)
|
75
79
|
# Almost a duplicate from ActionController::Helpers
|
76
80
|
methods.flatten.each do |method|
|
77
|
-
_helpers_for_modification.module_eval
|
81
|
+
_helpers_for_modification.module_eval <<~end_eval, __FILE__, __LINE__ + 1
|
78
82
|
def #{method}(*args, &block) # def current_user(*args, &block)
|
79
83
|
_test_case.send(:'#{method}', *args, &block) # _test_case.send(:'current_user', *args, &block)
|
80
84
|
end # end
|
81
|
-
ruby2_keywords(:'#{method}')
|
85
|
+
ruby2_keywords(:'#{method}')
|
82
86
|
end_eval
|
83
87
|
end
|
84
88
|
end
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
require "action_view/template/resolver"
|
4
4
|
|
5
|
-
module ActionView
|
5
|
+
module ActionView # :nodoc:
|
6
6
|
# Use FixtureResolver in your tests to simulate the presence of files on the
|
7
7
|
# file system. This is used internally by Rails' own test suite, and is
|
8
8
|
# useful for testing extensions that have no way of knowing what the file
|
9
9
|
# system will look like at runtime.
|
10
|
-
class FixtureResolver <
|
10
|
+
class FixtureResolver < FileSystemResolver
|
11
11
|
def initialize(hash = {})
|
12
12
|
super("")
|
13
13
|
@hash = hash
|
@@ -23,23 +23,22 @@ module ActionView #:nodoc:
|
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
26
|
-
def
|
27
|
-
@hash.keys.
|
28
|
-
|
29
|
-
end.map do |fixture|
|
30
|
-
"/#{fixture}"
|
26
|
+
def template_glob(glob)
|
27
|
+
@hash.keys.filter_map do |path|
|
28
|
+
"/#{path}" if File.fnmatch(glob, path)
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
32
|
def source_for_template(template)
|
35
|
-
@hash[template
|
33
|
+
@hash[template.from(1)]
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
|
-
class NullResolver <
|
40
|
-
def
|
41
|
-
|
42
|
-
|
37
|
+
class NullResolver < Resolver
|
38
|
+
def find_templates(name, prefix, partial, details, locals = [])
|
39
|
+
path = TemplatePath.build(name, prefix, partial)
|
40
|
+
handler = ActionView::Template::Handlers::Raw
|
41
|
+
[ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: nil, variant: nil, locals: locals)]
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
@@ -4,28 +4,54 @@ require "concurrent/map"
|
|
4
4
|
|
5
5
|
module ActionView
|
6
6
|
class UnboundTemplate
|
7
|
-
|
7
|
+
attr_reader :virtual_path, :details
|
8
|
+
delegate :locale, :format, :variant, :handler, to: :@details
|
9
|
+
|
10
|
+
def initialize(source, identifier, details:, virtual_path:)
|
8
11
|
@source = source
|
9
12
|
@identifier = identifier
|
10
|
-
@
|
11
|
-
@
|
13
|
+
@details = details
|
14
|
+
@virtual_path = virtual_path
|
12
15
|
|
13
16
|
@templates = Concurrent::Map.new(initial_capacity: 2)
|
17
|
+
@write_lock = Mutex.new
|
14
18
|
end
|
15
19
|
|
16
20
|
def bind_locals(locals)
|
17
|
-
@templates[locals]
|
21
|
+
if template = @templates[locals]
|
22
|
+
template
|
23
|
+
else
|
24
|
+
@write_lock.synchronize do
|
25
|
+
normalized_locals = normalize_locals(locals)
|
26
|
+
|
27
|
+
# We need ||=, both to dedup on the normalized locals and to check
|
28
|
+
# while holding the lock.
|
29
|
+
@templates[normalized_locals] ||= build_template(normalized_locals)
|
30
|
+
|
31
|
+
# This may have already been assigned, but we've already de-dup'd so
|
32
|
+
# reassignment is fine.
|
33
|
+
@templates[locals.dup] = @templates[normalized_locals]
|
34
|
+
end
|
35
|
+
end
|
18
36
|
end
|
19
37
|
|
20
38
|
private
|
21
39
|
def build_template(locals)
|
22
|
-
options = @options.merge(locals: locals)
|
23
40
|
Template.new(
|
24
41
|
@source,
|
25
42
|
@identifier,
|
26
|
-
|
27
|
-
|
43
|
+
details.handler_class,
|
44
|
+
|
45
|
+
format: details.format_or_default,
|
46
|
+
variant: variant&.to_s,
|
47
|
+
virtual_path: @virtual_path,
|
48
|
+
|
49
|
+
locals: locals.map(&:to_s)
|
28
50
|
)
|
29
51
|
end
|
52
|
+
|
53
|
+
def normalize_locals(locals)
|
54
|
+
locals.map(&:to_sym).sort!.freeze
|
55
|
+
end
|
30
56
|
end
|
31
57
|
end
|
data/lib/action_view.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2021 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -44,6 +44,8 @@ module ActionView
|
|
44
44
|
autoload :Rendering
|
45
45
|
autoload :RoutingUrlFor
|
46
46
|
autoload :Template
|
47
|
+
autoload :TemplateDetails
|
48
|
+
autoload :TemplatePath
|
47
49
|
autoload :UnboundTemplate
|
48
50
|
autoload :ViewPaths
|
49
51
|
|
@@ -59,10 +61,7 @@ module ActionView
|
|
59
61
|
|
60
62
|
autoload_at "action_view/template/resolver" do
|
61
63
|
autoload :Resolver
|
62
|
-
autoload :PathResolver
|
63
64
|
autoload :FileSystemResolver
|
64
|
-
autoload :OptimizedFileSystemResolver
|
65
|
-
autoload :FallbackFileSystemResolver
|
66
65
|
end
|
67
66
|
|
68
67
|
autoload_at "action_view/buffers" do
|
@@ -73,22 +73,6 @@ Released under the MIT license
|
|
73
73
|
return element[expando][key] = value;
|
74
74
|
};
|
75
75
|
|
76
|
-
Rails.isContentEditable = function(element) {
|
77
|
-
var isEditable;
|
78
|
-
isEditable = false;
|
79
|
-
while (true) {
|
80
|
-
if (element.isContentEditable) {
|
81
|
-
isEditable = true;
|
82
|
-
break;
|
83
|
-
}
|
84
|
-
element = element.parentElement;
|
85
|
-
if (!element) {
|
86
|
-
break;
|
87
|
-
}
|
88
|
-
}
|
89
|
-
return isEditable;
|
90
|
-
};
|
91
|
-
|
92
76
|
Rails.$ = function(selector) {
|
93
77
|
return Array.prototype.slice.call(document.querySelectorAll(selector));
|
94
78
|
};
|
@@ -411,9 +395,9 @@ Released under the MIT license
|
|
411
395
|
|
412
396
|
}).call(this);
|
413
397
|
(function() {
|
414
|
-
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData,
|
398
|
+
var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isXhrRedirect, matches, setData, stopEverything;
|
415
399
|
|
416
|
-
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements
|
400
|
+
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;
|
417
401
|
|
418
402
|
Rails.handleDisabledElement = function(e) {
|
419
403
|
var element;
|
@@ -433,9 +417,6 @@ Released under the MIT license
|
|
433
417
|
} else {
|
434
418
|
element = e;
|
435
419
|
}
|
436
|
-
if (isContentEditable(element)) {
|
437
|
-
return;
|
438
|
-
}
|
439
420
|
if (matches(element, Rails.linkDisableSelector)) {
|
440
421
|
return enableLinkElement(element);
|
441
422
|
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {
|
@@ -448,9 +429,6 @@ Released under the MIT license
|
|
448
429
|
Rails.disableElement = function(e) {
|
449
430
|
var element;
|
450
431
|
element = e instanceof Event ? e.target : e;
|
451
|
-
if (isContentEditable(element)) {
|
452
|
-
return;
|
453
|
-
}
|
454
432
|
if (matches(element, Rails.linkDisableSelector)) {
|
455
433
|
return disableLinkElement(element);
|
456
434
|
} else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) {
|
@@ -535,12 +513,10 @@ Released under the MIT license
|
|
535
513
|
|
536
514
|
}).call(this);
|
537
515
|
(function() {
|
538
|
-
var
|
516
|
+
var stopEverything;
|
539
517
|
|
540
518
|
stopEverything = Rails.stopEverything;
|
541
519
|
|
542
|
-
isContentEditable = Rails.isContentEditable;
|
543
|
-
|
544
520
|
Rails.handleMethod = function(e) {
|
545
521
|
var csrfParam, csrfToken, form, formContent, href, link, method;
|
546
522
|
link = this;
|
@@ -548,9 +524,6 @@ Released under the MIT license
|
|
548
524
|
if (!method) {
|
549
525
|
return;
|
550
526
|
}
|
551
|
-
if (isContentEditable(this)) {
|
552
|
-
return;
|
553
|
-
}
|
554
527
|
href = Rails.href(link);
|
555
528
|
csrfToken = Rails.csrfToken();
|
556
529
|
csrfParam = Rails.csrfParam();
|
@@ -572,10 +545,10 @@ Released under the MIT license
|
|
572
545
|
|
573
546
|
}).call(this);
|
574
547
|
(function() {
|
575
|
-
var ajax, fire, getData,
|
548
|
+
var ajax, fire, getData, isCrossDomain, isRemote, matches, serializeElement, setData, stopEverything,
|
576
549
|
slice = [].slice;
|
577
550
|
|
578
|
-
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement
|
551
|
+
matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement;
|
579
552
|
|
580
553
|
isRemote = function(element) {
|
581
554
|
var value;
|
@@ -593,10 +566,6 @@ Released under the MIT license
|
|
593
566
|
fire(element, 'ajax:stopped');
|
594
567
|
return false;
|
595
568
|
}
|
596
|
-
if (isContentEditable(element)) {
|
597
|
-
fire(element, 'ajax:stopped');
|
598
|
-
return false;
|
599
|
-
}
|
600
569
|
withCredentials = element.getAttribute('data-with-credentials');
|
601
570
|
dataType = element.getAttribute('data-type') || 'script';
|
602
571
|
if (matches(element, Rails.formSubmitSelector)) {
|
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:
|
4
|
+
version: 7.0.0.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-15 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:
|
19
|
+
version: 7.0.0.alpha1
|
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:
|
26
|
+
version: 7.0.0.alpha1
|
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:
|
95
|
+
version: 7.0.0.alpha1
|
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:
|
102
|
+
version: 7.0.0.alpha1
|
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:
|
109
|
+
version: 7.0.0.alpha1
|
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:
|
116
|
+
version: 7.0.0.alpha1
|
117
117
|
description: Simple, battle-tested conventions and helpers for building web pages.
|
118
118
|
email: david@loudthinking.com
|
119
119
|
executables: []
|
@@ -129,6 +129,8 @@ files:
|
|
129
129
|
- lib/action_view/cache_expiry.rb
|
130
130
|
- lib/action_view/context.rb
|
131
131
|
- lib/action_view/dependency_tracker.rb
|
132
|
+
- lib/action_view/dependency_tracker/erb_tracker.rb
|
133
|
+
- lib/action_view/dependency_tracker/ripper_tracker.rb
|
132
134
|
- lib/action_view/digestor.rb
|
133
135
|
- lib/action_view/flows.rb
|
134
136
|
- lib/action_view/gem_version.rb
|
@@ -189,6 +191,7 @@ files:
|
|
189
191
|
- lib/action_view/helpers/tags/translator.rb
|
190
192
|
- lib/action_view/helpers/tags/url_field.rb
|
191
193
|
- lib/action_view/helpers/tags/week_field.rb
|
194
|
+
- lib/action_view/helpers/tags/weekday_select.rb
|
192
195
|
- lib/action_view/helpers/text_helper.rb
|
193
196
|
- lib/action_view/helpers/translation_helper.rb
|
194
197
|
- lib/action_view/helpers/url_helper.rb
|
@@ -200,6 +203,7 @@ files:
|
|
200
203
|
- lib/action_view/path_set.rb
|
201
204
|
- lib/action_view/railtie.rb
|
202
205
|
- lib/action_view/record_identifier.rb
|
206
|
+
- lib/action_view/render_parser.rb
|
203
207
|
- lib/action_view/renderer/abstract_renderer.rb
|
204
208
|
- lib/action_view/renderer/collection_renderer.rb
|
205
209
|
- lib/action_view/renderer/object_renderer.rb
|
@@ -209,6 +213,7 @@ files:
|
|
209
213
|
- lib/action_view/renderer/streaming_template_renderer.rb
|
210
214
|
- lib/action_view/renderer/template_renderer.rb
|
211
215
|
- lib/action_view/rendering.rb
|
216
|
+
- lib/action_view/ripper_ast_parser.rb
|
212
217
|
- lib/action_view/routing_url_for.rb
|
213
218
|
- lib/action_view/tasks/cache_digests.rake
|
214
219
|
- lib/action_view/template.rb
|
@@ -228,6 +233,8 @@ files:
|
|
228
233
|
- lib/action_view/template/sources/file.rb
|
229
234
|
- lib/action_view/template/text.rb
|
230
235
|
- lib/action_view/template/types.rb
|
236
|
+
- lib/action_view/template_details.rb
|
237
|
+
- lib/action_view/template_path.rb
|
231
238
|
- lib/action_view/test_case.rb
|
232
239
|
- lib/action_view/testing/resolvers.rb
|
233
240
|
- lib/action_view/unbound_template.rb
|
@@ -239,11 +246,10 @@ licenses:
|
|
239
246
|
- MIT
|
240
247
|
metadata:
|
241
248
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
242
|
-
changelog_uri: https://github.com/rails/rails/blob/
|
243
|
-
documentation_uri: https://api.rubyonrails.org/
|
249
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.0.0.alpha1/actionview/CHANGELOG.md
|
250
|
+
documentation_uri: https://api.rubyonrails.org/v7.0.0.alpha1/
|
244
251
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
245
|
-
source_code_uri: https://github.com/rails/rails/tree/
|
246
|
-
rubygems_mfa_required: 'true'
|
252
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.0.0.alpha1/actionview
|
247
253
|
post_install_message:
|
248
254
|
rdoc_options: []
|
249
255
|
require_paths:
|
@@ -252,15 +258,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
252
258
|
requirements:
|
253
259
|
- - ">="
|
254
260
|
- !ruby/object:Gem::Version
|
255
|
-
version: 2.
|
261
|
+
version: 2.7.0
|
256
262
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
257
263
|
requirements:
|
258
|
-
- - "
|
264
|
+
- - ">"
|
259
265
|
- !ruby/object:Gem::Version
|
260
|
-
version:
|
266
|
+
version: 1.3.1
|
261
267
|
requirements:
|
262
268
|
- none
|
263
|
-
rubygems_version: 3.
|
269
|
+
rubygems_version: 3.1.6
|
264
270
|
signing_key:
|
265
271
|
specification_version: 4
|
266
272
|
summary: Rendering framework putting the V in MVC (part of Rails).
|