class Blocks::Builder

Attributes

anonymous_block_number[RW]
block_definitions[RW]

A HashWithIndifferentAccess of block names to BlockDefinition mappings

options[RW]

Options provided during initialization of builder

view[RW]

A pointer to the view context

Public Class Methods

new(view, options=nil) click to toggle source
# 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

block_defined?(block_name) click to toggle source
# File lib/blocks/builders/builder.rb, line 61
def block_defined?(block_name)
  block_definitions.key?(block_name)
end
block_for(block_name) click to toggle source
# File lib/blocks/builders/builder.rb, line 44
def block_for(block_name)
  block_definitions[block_name] if block_defined?(block_name)
end
capture(*args, &block) click to toggle source
# 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
concatenating_merge(options, options2, *args) click to toggle source

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
content_tag(*args, &block) click to toggle source

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
deferred_render(*args, &block) click to toggle source
# File lib/blocks/builders/builder.rb, line 40
def deferred_render(*args, &block)
  renderer_class.deferred_render(self, *args, &block)
end
define(*args, &block) click to toggle source

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
hooks_for(block_name, hook_name) click to toggle source
# 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
render(*args, &block) click to toggle source
# File lib/blocks/builders/builder.rb, line 31
def render(*args, &block)
  renderer_class.render(self, *args, &block)
end
render_with_overrides(*args, &block) click to toggle source
# 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
replace(name, options={}, &block) click to toggle source

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
skip(name, completely=false) click to toggle source
# File lib/blocks/builders/builder.rb, line 116
def skip(name, completely=false)
  block_definitions[name].skip(completely)
end
skip_completely(name) click to toggle source
# File lib/blocks/builders/builder.rb, line 120
def skip_completely(name)
  skip(name, true)
end

Protected Instance Methods

call_each_hash_value_with_params(*args) click to toggle source
# 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
call_with_params(*args) click to toggle source
# 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
renderer_class() click to toggle source
# File lib/blocks/builders/builder.rb, line 186
def renderer_class
  @renderer_class ||= Blocks.renderer_class
end