blocks 3.0.4 → 4.0.0.rc1
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 +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