Class: Yarrow::Content::TreeExpansion

Inherits:
Expansion
  • Object
show all
Defined in:
lib/yarrow/content/tree_expansion.rb

Instance Attribute Summary

Attributes inherited from Expansion

#graph

Instance Method Summary collapse

Methods inherited from Expansion

#extract_metadata, #initialize, #process_content

Methods included from Tools::FrontMatter

#extract_split_content, #read_split_content

Constructor Details

This class inherits a constructor from Yarrow::Content::Expansion

Instance Method Details

#expand(content_type) ⇒ Object



4
5
6
7
8
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/yarrow/content/tree_expansion.rb', line 4

def expand(content_type)
  type = content_type.collection
  exts = content_type.extensions

  # If match path represents entire content dir, then include the entire
  # content dir instead of scanning from a subfolder matching the name of
  # the collection.
  start_node = if content_type.match_path == "."
    graph.n(:root)
  else
    graph.n(:root).out(name: type.to_s)
  end

  # Extract metadata from given start node
   = (start_node, type)

  # Collect all nested collections in the subgraph for this content type
  subcollections = {}
  item_links = []
  index = nil

  # Scan and collect all nested files from the root
  start_node.depth_first.each do |node|
    if node.label == :directory
      # Create a collection node representing a collection of documents
      index = graph.create_node do |collection_node|
        collection_node.label = :collection
        collection_node.props[:type] = type
        collection_node.props[:name] = node.props[:name]

        # TODO: title needs to be defined from metadata
        collection_node.props[:title] = node.props[:name].capitalize
      end

      # Add this collection id to the lookup table for edge construction
      subcollections[node.props[:path]] = index

      # Join the collection to its parent
      unless node.props[:slug] == type.to_s || !subcollections.key?(node.props[:entry].parent.to_s)
        graph.create_edge do |edge|
          edge.label = :child
          edge.from = subcollections[node.props[:entry].parent.to_s].id
          edge.to = index.id
        end
      end
    elsif node.label == :file
      body, meta = process_content(node.props[:entry])

      # Create an item node representing a file mapped to a unique content object
      item = graph.create_node do |item_node|
        item_node.label = :item
        item_node.props[:type] = content_type.entity
        item_node.props[:name] = node.props[:entry].basename(node.props[:entry].extname).to_s
        item_node.props[:body] = body if body
        item_node.props[:title] = meta[:title] if meta
        # TODO: better handling of metadata on node props
      end

      # We may not have an expanded node for the parent collection if this is a
      # preorder traversal so save it for later
      item_links << {
        parent_path: node.props[:entry].parent.to_s,
        item_id: item.id
      }
    end
  end

  # Once all files and directories have been expanded, connect all the child
  # edges between collections and items
  item_links.each do |item_link|
    graph.create_edge do |edge|
      edge.label = :child
      edge.from = subcollections[item_link[:parent_path]].id
      edge.to = item_link[:item_id]
    end
  end
end