module ExpressTemplates::Components::Capabilities::Iteration

Provides iteration to components that iterate over a collection.

Public Class Methods

included(base) click to toggle source
# File lib/express_templates/components/capabilities/iteration.rb, line 9
def self.included(base)
  base.class_eval do

    has_option :collection, "An optional object implementing Enumerable or a proc returning an Enumerable.", type: [:proc, :array]

    # Iterates over the collection calling the block provided to emit markup.
    #
    # The collection (symbol) must be available as a method on the component
    # or as a local (assigns) value in the rendering context.
    #
    # The collection name is singularized and a local value is set
    # for each item in the collection.

    def for_all(collection_name, &block)
      @collection_name = collection_name
      _normalized_collection.each do |item|
        old_value = assigns[singular_item_name]
        assigns[singular_item_name] = item
        block.call
        assigns[singular_item_name] = old_value
      end
    end

    protected

      def collection_name
        @collection_name
      end

      def singular_item_name
        collection_name.to_s.singularize.to_sym
      end

      def item
        assigns[singular_item_name]
      end

    private
      def _normalized_collection
        case
        when config[:collection].respond_to?(:call)
          config[:collection].call()
        when config[:collection].respond_to?(:each)
          config[:collection]
        else
          raise "#{collection_name} is not a collection" unless self.send(collection_name).respond_to?(:each)
          self.send(collection_name)
        end
      end

  end
end

Public Instance Methods

_normalized_collection() click to toggle source
# File lib/express_templates/components/capabilities/iteration.rb, line 47
def _normalized_collection
  case
  when config[:collection].respond_to?(:call)
    config[:collection].call()
  when config[:collection].respond_to?(:each)
    config[:collection]
  else
    raise "#{collection_name} is not a collection" unless self.send(collection_name).respond_to?(:each)
    self.send(collection_name)
  end
end
collection_name() click to toggle source
# File lib/express_templates/components/capabilities/iteration.rb, line 34
def collection_name
  @collection_name
end
for_all(collection_name, &block) click to toggle source

Iterates over the collection calling the block provided to emit markup.

The collection (symbol) must be available as a method on the component or as a local (assigns) value in the rendering context.

The collection name is singularized and a local value is set for each item in the collection.

# File lib/express_templates/components/capabilities/iteration.rb, line 22
def for_all(collection_name, &block)
  @collection_name = collection_name
  _normalized_collection.each do |item|
    old_value = assigns[singular_item_name]
    assigns[singular_item_name] = item
    block.call
    assigns[singular_item_name] = old_value
  end
end
item() click to toggle source
# File lib/express_templates/components/capabilities/iteration.rb, line 42
def item
  assigns[singular_item_name]
end
singular_item_name() click to toggle source
# File lib/express_templates/components/capabilities/iteration.rb, line 38
def singular_item_name
  collection_name.to_s.singularize.to_sym
end