Module: ExpressTemplates::Components::Capabilities::Iteration

Included in:
Presenters::All
Defined in:
lib/express_templates/components/capabilities/iteration.rb

Overview

Provides iteration to components that iterate over a collection.

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 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