blocks 3.0.4 → 4.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.ruby-version +1 -1
- data/.travis.yml +61 -17
- data/CHANGELOG.rdoc +27 -0
- data/Gemfile +11 -10
- data/Guardfile +1 -0
- data/README.md +2 -0
- data/bin/deploy_docs +1 -1
- data/blocks.gemspec +3 -1
- data/docs/_includes/configuration.md +3 -6
- data/docs/_includes/defining.md +7 -7
- data/docs/_includes/{introduction.md → features.md} +2 -2
- data/docs/_includes/helper-blocks.md +5 -0
- data/docs/_includes/helper-blocks/content_tag.md +44 -0
- data/docs/_includes/installation.md +16 -2
- data/docs/_includes/overview.md +21 -0
- data/docs/_includes/templating.md +1 -1
- data/docs/_includes/templating/bootstrap_4_cards.md +9 -9
- data/docs/_layouts/slate.html +11 -9
- data/docs/index.md +3 -1
- data/gemfiles/Gemfile.rails-3-0-stable +1 -0
- data/gemfiles/Gemfile.rails-3-1-stable +1 -0
- data/gemfiles/Gemfile.rails-3-2-stable +1 -0
- data/gemfiles/Gemfile.rails-4-0-stable +2 -1
- data/gemfiles/Gemfile.rails-4-1-stable +2 -1
- data/gemfiles/Gemfile.rails-4-2-stable +2 -1
- data/gemfiles/Gemfile.rails-5-0-stable +4 -3
- data/gemfiles/Gemfile.rails-5-1-stable +4 -3
- data/gemfiles/Gemfile.rails-5-2-stable +13 -0
- data/lib/blocks.rb +37 -29
- data/lib/blocks/builders/block_definition.rb +45 -43
- data/lib/blocks/builders/builder.rb +96 -60
- data/lib/blocks/builders/hook_definition.rb +19 -4
- data/lib/blocks/engine.rb +14 -0
- data/lib/blocks/helpers/controller_extensions.rb +13 -0
- data/lib/blocks/helpers/haml_capture.rb +44 -0
- data/lib/blocks/{action_view_extensions → helpers}/view_extensions.rb +10 -4
- data/lib/blocks/renderers/adjacent_blocks_renderer.rb +9 -7
- data/lib/blocks/renderers/block_placeholder.rb +2 -0
- data/lib/blocks/renderers/block_renderer.rb +26 -5
- data/lib/blocks/renderers/block_with_hooks_renderer.rb +29 -19
- data/lib/blocks/renderers/collection_renderer.rb +19 -6
- data/lib/blocks/renderers/nesting_blocks_renderer.rb +9 -11
- data/lib/blocks/renderers/partial_renderer.rb +16 -14
- data/lib/blocks/renderers/renderer.rb +9 -24
- data/lib/blocks/renderers/runtime_context.rb +174 -152
- data/lib/blocks/renderers/wrapper_renderer.rb +21 -10
- data/lib/blocks/utilities/configurator.rb +30 -6
- data/lib/blocks/utilities/hash_with_caller.rb +36 -32
- data/lib/blocks/utilities/hash_with_render_strategy.rb +67 -19
- data/lib/blocks/utilities/options_set.rb +38 -63
- data/lib/blocks/version.rb +3 -1
- metadata +22 -21
- data/docs/_includes/wip.md +0 -34
- data/lib/blocks/experimental/builder_permissions.rb +0 -52
- data/lib/blocks/experimental/invalid_permissions_handler.rb +0 -27
- data/lib/blocks/renderers/abstract_renderer.rb +0 -69
- data/lib/blocks/utilities/dynamic_configuration.rb +0 -71
@@ -1,18 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Blocks
|
2
|
-
class WrapperRenderer
|
3
|
-
def render(wrapper, runtime_context)
|
4
|
-
|
4
|
+
class WrapperRenderer
|
5
|
+
def self.render(wrapper, wrapper_type, runtime_context)
|
6
|
+
output_buffer = runtime_context.output_buffer
|
7
|
+
|
5
8
|
if wrapper.nil?
|
6
9
|
yield
|
10
|
+
|
7
11
|
elsif wrapper.is_a?(Proc)
|
8
|
-
output_buffer << capture(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
output_buffer << runtime_context.capture(
|
13
|
+
Proc.new { runtime_context.with_output_buffer { yield } },
|
14
|
+
*(runtime_context.runtime_args),
|
15
|
+
runtime_context.to_hash.merge(wrapper_type: wrapper_type),
|
16
|
+
&wrapper
|
17
|
+
)
|
18
|
+
|
14
19
|
else
|
15
|
-
|
20
|
+
wrapper_runtime_context = runtime_context.extend_from_definition(
|
21
|
+
wrapper,
|
22
|
+
wrapper_type: wrapper_type
|
23
|
+
) do
|
24
|
+
runtime_context.with_output_buffer { yield }
|
25
|
+
end
|
26
|
+
output_buffer << BlockWithHooksRenderer.render(wrapper_runtime_context)
|
16
27
|
end
|
17
28
|
end
|
18
29
|
end
|
@@ -1,14 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Blocks
|
2
4
|
module Configurator
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
included do
|
6
|
-
|
8
|
+
mattr_accessor :builder_class
|
9
|
+
mattr_accessor :renderer_class
|
10
|
+
mattr_accessor :global_options
|
11
|
+
mattr_accessor :lookup_caller_location
|
12
|
+
mattr_accessor :track_caller
|
13
|
+
# TODO: add default_defintions option
|
14
|
+
# TODO: add submodules / extensions option
|
15
|
+
# TODO: add option to specify render order for nesting hooks
|
16
|
+
|
17
|
+
# Specifies whether the default options specified for a render call will take priority over ones specified as block default options
|
18
|
+
# Legacy versions of Blocks had default render options always take precedence over block-level default options
|
19
|
+
mattr_accessor :default_render_options_take_precedence_over_block_defaults
|
20
|
+
|
21
|
+
# Specifies whether a block defined with a proc will receive a collection item as its first argument when rendering collections
|
22
|
+
# Legacy versions of Blocks assumed that the collection item would be the first argument
|
23
|
+
mattr_accessor :collection_item_passed_to_block_as_first_arg
|
7
24
|
|
8
|
-
add_config :builder_class
|
9
|
-
add_config :renderer_class
|
10
|
-
add_config :global_options_set
|
11
|
-
add_config :lookup_caller_location, instance_predicate: true
|
12
25
|
reset_config
|
13
26
|
end
|
14
27
|
|
@@ -18,7 +31,18 @@ module Blocks
|
|
18
31
|
config.builder_class = Builder
|
19
32
|
config.renderer_class = Renderer
|
20
33
|
config.lookup_caller_location = false
|
21
|
-
config.
|
34
|
+
config.track_caller = false
|
35
|
+
config.global_options = nil
|
36
|
+
config.default_render_options_take_precedence_over_block_defaults = false
|
37
|
+
config.collection_item_passed_to_block_as_first_arg = false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def configure
|
42
|
+
yield self
|
43
|
+
self.track_caller = true if lookup_caller_location
|
44
|
+
if track_caller
|
45
|
+
HashWithRenderStrategy.send(:prepend, HashWithCaller)
|
22
46
|
end
|
23
47
|
end
|
24
48
|
end
|
@@ -1,41 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Blocks
|
2
|
-
|
4
|
+
module HashWithCaller
|
3
5
|
attr_accessor :callers
|
4
6
|
|
5
7
|
def initialize(*args)
|
6
|
-
self.callers =
|
7
|
-
|
8
|
-
add_options(args.first, options)
|
9
|
-
super &nil
|
8
|
+
self.callers = {}
|
9
|
+
super
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
description << "{"
|
16
|
-
description << map do |key, value|
|
17
|
-
value_display = case value
|
18
|
-
when Symbol
|
19
|
-
":#{value}"
|
20
|
-
when String
|
21
|
-
"\"#{value}\""
|
22
|
-
when Proc
|
23
|
-
"Proc"
|
24
|
-
else
|
25
|
-
value
|
26
|
-
end
|
27
|
-
"\"#{key}\" => #{value_display}, # [#{callers[key]}]"
|
28
|
-
end.join(",\n")
|
29
|
-
description << "}"
|
30
|
-
description.join("\n")
|
12
|
+
def initialize_copy(original)
|
13
|
+
super
|
14
|
+
self.callers = original.callers.clone
|
31
15
|
end
|
32
16
|
|
33
|
-
|
17
|
+
# TODO: implement inspect
|
18
|
+
|
19
|
+
# TODO: fix and test this implementation
|
20
|
+
# def to_s
|
21
|
+
# description = []
|
22
|
+
#
|
23
|
+
# description << "{"
|
24
|
+
# description << map do |key, value|
|
25
|
+
# value_display = case value
|
26
|
+
# when Symbol
|
27
|
+
# ":#{value}"
|
28
|
+
# when String
|
29
|
+
# "\"#{value}\""
|
30
|
+
# when Proc
|
31
|
+
# "Proc"
|
32
|
+
# else
|
33
|
+
# value
|
34
|
+
# end
|
35
|
+
# "\"#{key}\" => #{value_display}, # [#{callers[key]}]"
|
36
|
+
# end.join(",\n")
|
37
|
+
# description << "}"
|
38
|
+
# description.join("\n")
|
39
|
+
# end
|
40
|
+
|
41
|
+
def reverse_merge!(*args)
|
34
42
|
options = args.extract_options!
|
35
43
|
|
36
44
|
caller_id = args.first.to_s.presence || ""
|
37
45
|
|
38
|
-
if !options.is_a?(HashWithCaller) && Blocks.lookup_caller_location
|
46
|
+
if !options.is_a?(HashWithCaller) && Blocks.lookup_caller_location
|
39
47
|
caller_location = caller.detect do |c|
|
40
48
|
!c.include?("/lib/blocks") &&
|
41
49
|
!c.include?("/lib/ruby") &&
|
@@ -55,19 +63,15 @@ module Blocks
|
|
55
63
|
end
|
56
64
|
|
57
65
|
if !self.key?(key)
|
58
|
-
self[key] = value
|
59
66
|
callers[key] = setter
|
60
67
|
|
61
68
|
elsif current_value.is_a?(Hash) && value.is_a?(Hash)
|
62
|
-
self[key] = value.deep_merge(current_value)
|
69
|
+
# self[key] = value.deep_merge(current_value)
|
63
70
|
callers[key] = "#{callers[key]}, #{setter}"
|
64
|
-
# TODO: handle attribute merges here
|
65
71
|
end
|
66
72
|
end
|
67
|
-
end
|
68
73
|
|
69
|
-
|
70
|
-
self
|
74
|
+
super options
|
71
75
|
end
|
72
76
|
end
|
73
77
|
end
|
@@ -1,36 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Blocks
|
2
|
-
class HashWithRenderStrategy <
|
4
|
+
class HashWithRenderStrategy < Hash
|
3
5
|
attr_accessor :render_strategy
|
4
6
|
|
5
7
|
RENDER_WITH_PROXY = :with
|
6
8
|
RENDER_WITH_BLOCK = :block
|
7
9
|
RENDER_WITH_PARTIAL = :partial
|
8
10
|
|
9
|
-
RENDERING_STRATEGIES = [RENDER_WITH_PROXY,
|
11
|
+
RENDERING_STRATEGIES = [RENDER_WITH_PROXY, RENDER_WITH_PARTIAL, RENDER_WITH_BLOCK]
|
10
12
|
|
11
|
-
def
|
12
|
-
super
|
13
|
-
|
14
|
-
|
15
|
-
RENDERING_STRATEGIES.each do |rs|
|
16
|
-
self.delete(rs)
|
17
|
-
end
|
13
|
+
def initialize(*args, &block)
|
14
|
+
super &nil
|
15
|
+
options = args.extract_options!
|
16
|
+
reverse_merge!(args.first, options, &block)
|
18
17
|
end
|
19
18
|
|
20
|
-
|
19
|
+
def to_hash
|
20
|
+
{}.update(self)
|
21
|
+
end
|
21
22
|
|
22
|
-
def
|
23
|
-
self.
|
23
|
+
def slice(*keys)
|
24
|
+
self.class.new(super)
|
24
25
|
end
|
25
26
|
|
26
|
-
|
27
|
-
|
27
|
+
def except(*keys)
|
28
|
+
slice(*self.keys - keys)
|
29
|
+
end
|
28
30
|
|
29
|
-
def
|
31
|
+
def reverse_merge!(*args, &block)
|
30
32
|
options = args.extract_options!
|
31
|
-
if !options.is_a?(HashWithIndifferentAccess)
|
32
|
-
options = options.with_indifferent_access
|
33
|
-
end
|
34
33
|
options[:block] = block if block
|
35
34
|
if render_strategy.nil?
|
36
35
|
self.render_strategy = if options.is_a?(HashWithRenderStrategy)
|
@@ -40,11 +39,60 @@ module Blocks
|
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
|
-
|
42
|
+
options.each do |key, value|
|
43
|
+
current_value = self[key]
|
44
|
+
|
45
|
+
if !self.key?(key)
|
46
|
+
self[key] = value
|
47
|
+
elsif current_value.is_a?(Hash) && value.is_a?(Hash)
|
48
|
+
# TODO: handle attribute merges here
|
49
|
+
self[key] = value.deep_merge(current_value)
|
50
|
+
end
|
51
|
+
end
|
44
52
|
end
|
45
53
|
|
46
54
|
def render_strategy_and_item
|
47
55
|
[render_strategy, self[render_strategy]] if render_strategy
|
48
56
|
end
|
57
|
+
|
58
|
+
def render_strategy_item
|
59
|
+
self[render_strategy] if render_strategy
|
60
|
+
end
|
61
|
+
|
62
|
+
def renders_with_proxy?
|
63
|
+
render_strategy == RENDER_WITH_PROXY
|
64
|
+
end
|
65
|
+
|
66
|
+
def nested_under_indifferent_access
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
|
71
|
+
# this class.
|
72
|
+
def extractable_options?
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_s
|
77
|
+
description = []
|
78
|
+
|
79
|
+
description << "{"
|
80
|
+
description << map do |key, value|
|
81
|
+
value_display = case value
|
82
|
+
when Symbol
|
83
|
+
":#{value}"
|
84
|
+
when String
|
85
|
+
"\"#{value}\""
|
86
|
+
when Proc
|
87
|
+
"Proc"
|
88
|
+
else
|
89
|
+
value
|
90
|
+
end
|
91
|
+
# "\"#{key}\" => #{value_display}, # [#{callers[key]}]"
|
92
|
+
"\"#{key}\" => #{value_display}"
|
93
|
+
end.join(",\n")
|
94
|
+
description << "}"
|
95
|
+
description.join("\n")
|
96
|
+
end
|
49
97
|
end
|
50
98
|
end
|
@@ -1,95 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Blocks
|
2
|
-
class OptionsSet <
|
4
|
+
class OptionsSet < HashWithRenderStrategy
|
3
5
|
attr_accessor :name
|
4
|
-
|
5
|
-
attr_accessor :runtime_options
|
6
|
-
attr_accessor :standard_options
|
7
6
|
attr_accessor :default_options
|
8
7
|
|
9
8
|
def initialize(*args, &block)
|
10
|
-
options = args.extract_options!
|
11
|
-
self.name = args.first
|
12
|
-
reset
|
13
|
-
add_options options, &block
|
14
|
-
super(&nil)
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize_copy(original)
|
18
9
|
super
|
19
|
-
|
20
|
-
RuntimeContext::CONTROL_VARIABLES.keys +
|
21
|
-
RuntimeContext::CONTROL_VARIABLES.values
|
22
|
-
).flatten.compact
|
23
|
-
self.runtime_options = original.runtime_options.clone.except(*control_fields)
|
24
|
-
self.default_options = original.default_options.clone.except(*control_fields)
|
25
|
-
self.standard_options = original.standard_options.clone.except(*control_fields)
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_s
|
29
|
-
description = []
|
30
|
-
description << "Block Name: #{name}"
|
31
|
-
description << "------------------------------"
|
32
|
-
description << "Runtime Options:"
|
33
|
-
description << runtime_options.to_s
|
34
|
-
description << "------------------------------"
|
35
|
-
description << "Standard Options:"
|
36
|
-
description << standard_options.to_s
|
37
|
-
description << "------------------------------"
|
38
|
-
description << "Default Options:"
|
39
|
-
description << default_options.to_s
|
40
|
-
description.join("\n")
|
10
|
+
self.name = args.first
|
41
11
|
end
|
42
12
|
|
13
|
+
# def to_s
|
14
|
+
# description = []
|
15
|
+
# description << "Block Name: #{name}"
|
16
|
+
# description << "------------------------------"
|
17
|
+
# description << "Standard Options:"
|
18
|
+
# description << standard_options.to_s
|
19
|
+
# description << "------------------------------"
|
20
|
+
# description << "Default Options:"
|
21
|
+
# description << default_options.to_s
|
22
|
+
# description.join("\n")
|
23
|
+
# end
|
24
|
+
#
|
43
25
|
def inspect
|
44
|
-
hash =
|
45
|
-
hash[:defaults] = default_options if default_options.present?
|
46
|
-
hash[:runtime] = runtime_options if runtime_options.present?
|
26
|
+
hash = to_hash
|
27
|
+
hash[:defaults] = default_options.to_hash if default_options.present?
|
47
28
|
hash
|
48
29
|
end
|
49
30
|
|
50
|
-
def
|
31
|
+
def reverse_merge!(*args, &block)
|
51
32
|
options = args.extract_options!
|
52
33
|
caller_id = args.first
|
53
34
|
|
54
|
-
|
35
|
+
defaults, standard = if options.is_a?(OptionsSet)
|
55
36
|
caller_id ||= options.name
|
56
|
-
[options.
|
37
|
+
[options.default_options, options]
|
57
38
|
else
|
58
|
-
|
59
|
-
options = options.with_indifferent_access
|
60
|
-
end
|
61
|
-
[options.delete(:runtime), options.delete(:defaults), options]
|
39
|
+
[options.delete(:defaults), options]
|
62
40
|
end
|
63
41
|
|
64
42
|
caller_id ||= self.name
|
65
43
|
|
66
|
-
|
67
|
-
|
68
|
-
|
44
|
+
if standard.present? || block
|
45
|
+
super caller_id, standard, &block
|
46
|
+
end
|
69
47
|
|
70
|
-
|
71
|
-
|
48
|
+
if defaults.present?
|
49
|
+
if !default_options
|
50
|
+
self.default_options = HashWithRenderStrategy.new "#{name} Default Options"
|
51
|
+
end
|
52
|
+
default_options.reverse_merge! caller_id, defaults
|
53
|
+
end
|
72
54
|
|
73
|
-
|
74
|
-
self.runtime_options = HashWithRenderStrategy.new "#{name} Runtime Options"
|
75
|
-
self.standard_options = HashWithRenderStrategy.new "#{name} Standard Options"
|
76
|
-
self.default_options = HashWithRenderStrategy.new "#{name} Default Options"
|
55
|
+
self
|
77
56
|
end
|
78
57
|
|
79
|
-
def
|
80
|
-
|
58
|
+
def renders_with_proxy?
|
59
|
+
render_strategy == HashWithRenderStrategy::RENDER_WITH_PROXY
|
81
60
|
end
|
82
61
|
|
83
|
-
def
|
84
|
-
|
85
|
-
runtime_options.render_strategy_and_item,
|
86
|
-
standard_options.render_strategy_and_item,
|
87
|
-
default_options.render_strategy_and_item
|
88
|
-
]
|
62
|
+
def render_strategy
|
63
|
+
super || default_options.try(:render_strategy)
|
89
64
|
end
|
90
65
|
|
91
|
-
def
|
92
|
-
|
66
|
+
def render_strategy_item
|
67
|
+
super || default_options.try(:render_strategy_item)
|
93
68
|
end
|
94
69
|
end
|
95
70
|
end
|
data/lib/blocks/version.rb
CHANGED