lib/wrap_it/sections.rb in wrap_it-0.2.0 vs lib/wrap_it/sections.rb in wrap_it-1.0.0
- old
+ new
@@ -1,44 +1,114 @@
module WrapIt
#
- # Adds sections functionality
+ # Sections is a smart way to make complex components with inheritance.
#
+ # Sections is just array of named HTML markup pieces. You can place any
+ # section before or after another at class level and change their content
+ # at instance level.
+ #
+ # Each component have three stages. First is initialization, then sections
+ # capturing and rendering. You can change any sections content until
+ # rendering stage begins. Finally, renderer joins all sections in order,
+ # that they have at render time.
+ #
+ # {WrapIt::Base} provides following sections: main section is `:content`.
+ # All text from block captured there. `:render_arguments` and `:render_block`
+ # also provided, so arguments and block passed to render method captured
+ # here.
+ #
+ # Access to sections at instance level performed throw hash-like getter and
+ # setter ([] and []=) of self.
+ #
+ # With this functionality you can easy organize you inheritance, so any
+ # descendant can change sections order or any section content without
+ # changes to unrelated sections.
+ #
+ # @example sections usage
+ # class IconedButton < WrapIt::Base
+ # include TextContainer
+ # html_class 'btn'
+ # section :icon
+ # place :icon, before: :content
+ #
+ # after_capture do
+ # self[:icon] = html_safe('<i class="my-icon"></i>')
+ # end
+ # end
+ #
+ # class RightIconedButton < IconedButton
+ # place :icon, after: :content
+ # end
+ #
+ # b1 = IconedButton.new(template, 'text')
+ # b2 = RightIconedButton.new(template, 'text')
+ # b1.render # => '<div class="btn"><i class="my-icon"></i>text</div>'
+ # b2.render # => '<div class="btn">text<i class="my-icon"></i></div>'
+ #
# @author Alexey Ovchinnikov <alexiss@cybernetlab.ru>
#
module Sections
+ # Documentation includes
+ # @!parse extend Sections::ClassMethods
+
+ # module implementation
+
extend DerivedAttributes
+ #
def self.included(base)
base == Base || fail(
TypeError,
"#{self.class.name} can be included only into WrapIt::Base"
)
base.extend ClassMethods
end
+ #
+ # Retrieves specified section content
+ # @param name [Symbol] section name
+ #
+ # @return [String] section content
def [](name)
@section_names ||= self.class.sections
return nil unless @section_names.include?(name)
@sections ||= {}
@sections[name] ||= empty_html
end
+ #
+ # Sets specified section content
+ # @param name [Symbol] section name
+ # @param value [String] content
+ #
+ # @return [String] section content
def []=(name, value)
@section_names ||= self.class.sections
return unless @section_names.include?(name)
@sections ||= {}
@sections[name] = value
end
#
- # Class methods to include
+ # {Sections} class methods
#
module ClassMethods
+ #
+ # Retrieves all sections, including ancestors
+ #
+ # @return [Array<Symbol>] array of sections
def sections
collect_derived(:@sections)
end
+ #
+ # Defines new section or sections. Places its to end of section list
+ #
+ # @overload section([name, ...])
+ # @param name [Symbol, String] section name
+ #
+ # @return [void]
def section(*args)
@sections ||= []
args.flatten.each do |name|
name.is_a?(String) && name = name.to_sym
next unless name.is_a?(Symbol)
@@ -47,19 +117,37 @@
placement << name unless placement.include?(name)
place name, before: :end
end
end
+ #
+ # Retrieves section names in current order
+ #
+ # @return [Array<Symbol>] ordered sections array
def placement
@placement ||=
if self == Base
sections.clone
else
parent = ancestors[1..-1].find { |a| a.respond_to?(:placement) }
parent.nil? ? sections.clone : parent.placement.clone
end
end
+ #
+ # Places specific section in specified place
+ #
+ # @overload place(src, to)
+ # @param src [Symbol] section name to place
+ # @param to [Hash] single key-value hash. Key can be `:before` or
+ # `after`, value can be `:begin`, `:end` or section name
+ #
+ # @overload place(src, at, dst)
+ # @param src [Symbol] section name to place
+ # @param at [Symbol] can be `:before` or `:after`
+ # @param dst [Symbol] can be `:begin`, `:end` or section name
+ #
+ # @return [void]
def place(src, at, dst = nil)
if dst == nil && at.is_a?(Hash) && at.keys.size == 1
dst = at.values[0]
at = at.keys[0]
end