class Blocks::Builder
Attributes
A HashWithIndifferentAccess of block names to BlockDefinition
mappings
Options provided during initialization of builder
A pointer to the view context
Public Class Methods
# File lib/blocks/builders/builder.rb, line 22 def initialize(view, options=nil) self.view = view self.block_definitions = HashWithIndifferentAccess.new do |hash, key| hash[key] = BlockDefinition.new(key); hash[key] end self.anonymous_block_number = 0 self.options = options end
Public Instance Methods
# File lib/blocks/builders/builder.rb, line 61 def block_defined?(block_name) block_definitions.key?(block_name) end
# File lib/blocks/builders/builder.rb, line 44 def block_for(block_name) block_definitions[block_name] if block_defined?(block_name) end
# File lib/blocks/builders/builder.rb, line 52 def capture(*args, &block) if block.arity >= 0 args = args[0, block.arity] end with_output_buffer do output_buffer << view.capture(*args, &block) end end
TODO: move this logic elsewhere
# File lib/blocks/builders/builder.rb, line 131 def concatenating_merge(options, options2, *args) options = call_each_hash_value_with_params(options, *args) || {} options2 = call_each_hash_value_with_params(options2, *args) || {} options.merge(options2) do |key, v1, v2| if v1.is_a?(String) && v2.is_a?(String) "#{v1} #{v2}" else v2 end end end
Blocks::Builder#content_tag
extends ActionView’s content_tag
method
by allowing itself to be used as a wrapper, hook, or called directly, while also not requiring the content tag name (defaults to :div).
# File lib/blocks/builders/builder.rb, line 147 def content_tag(*args, &block) options = args.extract_options! escape = options.key?(:escape) ? options.delete(:escape) : true if wrapper_type = options.delete(:wrapper_type) html_option = options["#{wrapper_type}_html_option".to_sym] || options[:html_option] wrapper_html = if html_option.is_a?(Array) html_option.map { |html_attribute| options[html_attribute] }.compact.first elsif html_option.present? options[html_option] end wrapper_html = concatenating_merge(options["#{wrapper_type}_html".to_sym] || options[:html], wrapper_html, *args, options) wrapper_tag = options["#{wrapper_type}_tag".to_sym] end wrapper_html ||= call_each_hash_value_with_params(options[:html], options).presence || options wrapper_tag ||= options.delete(:tag) if !wrapper_tag first_arg = args.first wrapper_tag = if first_arg.is_a?(String) || first_arg.is_a?(Symbol) args.shift else :div end end content_tag_args = [wrapper_tag] if !block_given? content_tag_args << (wrapper_html.delete(:content) || options[:content] || args.shift) end content_tag_args << wrapper_html content_tag_args << escape view.content_tag *content_tag_args, &block end
# File lib/blocks/builders/builder.rb, line 40 def deferred_render(*args, &block) renderer_class.deferred_render(self, *args, &block) end
Define a block, unless a block by the same name is already defined.
<%= blocks.define :some_block_name, :parameter1 => "1", :parameter2 => "2" do |options| %> <%= options[:parameter1] %> and <%= options[:parameter2] %> <% end %>
Options:
name
-
The name of the block being defined (either a string or a symbol)
options
-
The default options for the block definition. Any or all of these options may be overridden by whomever calls “blocks.render” on this block.
block
-
The block that is to be rendered when “blocks.render” is called for this block.
# File lib/blocks/builders/builder.rb, line 78 def define(*args, &block) options = args.extract_options! name = if args.first args.shift else anonymous = true self.anonymous_block_number += 1 "anonymous_block_#{anonymous_block_number}" end block_definitions[name].tap do |block_definition| block_definition.reverse_merge! options, &block block_definition.anonymous = !!anonymous end end
# File lib/blocks/builders/builder.rb, line 48 def hooks_for(block_name, hook_name) block_for(block_name).try(:hooks_for, hook_name) || [] end
# File lib/blocks/builders/builder.rb, line 31 def render(*args, &block) renderer_class.render(self, *args, &block) end
# File lib/blocks/builders/builder.rb, line 35 def render_with_overrides(*args, &block) warn "[DEPRECATION] `render_with_overrides` is deprecated. Please use `render` instead." render(*args, &block) end
Define a block, replacing an existing block by the same name if it is already defined.
<%= blocks.define :some_block_name, :parameter1 => "1", :parameter2 => "2" do |options| %> <%= options[:parameter1] %> and <%= options[:parameter2] %> <% end %> <%= blocks.replace :some_block_name, :parameter3 => "3", :parameter4 => "4" do |options| %> <%= options[:parameter3] %> and <%= options[:parameter4] %> <% end %>
Options:
name
-
The name of the block being defined (either a string or a symbol)
options
-
The default options for the block definition. Any or all of these options may be overridden by whomever calls “blocks.render” on this block.
block
-
The block that is to be rendered when “blocks.render” is called for this block.
# File lib/blocks/builders/builder.rb, line 111 def replace(name, options={}, &block) block_definitions.delete(name) define(name, options, &block) end
# File lib/blocks/builders/builder.rb, line 116 def skip(name, completely=false) block_definitions[name].skip(completely) end
# File lib/blocks/builders/builder.rb, line 120 def skip_completely(name) skip(name, true) end
Protected Instance Methods
# File lib/blocks/builders/builder.rb, line 196 def call_each_hash_value_with_params(*args) return {} if args.empty? options = args.shift || {} if options.is_a?(Proc) call_with_params(options, *args) else options.inject(Hash.new) { |hash, (k, v)| hash[k] = call_with_params(v, *args); hash} end end
# File lib/blocks/builders/builder.rb, line 190 def call_with_params(*args) return nil if args.empty? v = args.shift v.is_a?(Proc) ? v.call(*(args[0, v.arity.abs])) : v end
# File lib/blocks/builders/builder.rb, line 186 def renderer_class @renderer_class ||= Blocks.renderer_class end