Module: Nanoc::Helpers::Breadcrumbs

Defined in:
lib/nanoc/helpers/breadcrumbs.rb

Overview

Defined Under Namespace

Modules: Int Classes: AmbiguousAncestorError

Instance Method Summary collapse

Instance Method Details

Returns:

  • (Array)


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/nanoc/helpers/breadcrumbs.rb', line 77

def breadcrumbs_trail(tiebreaker: Int::DEFAULT_TIEBREAKER)
  # The design of this function is a little complicated.
  #
  # We can’t use #parent_of from the ChildParent helper, because the
  # breadcrumb trail can have gaps. For example, the breadcrumbs trail for
  # /software/oink.md might be /index.md -> nil -> /software/oink.md if
  # there is no item matching /software.* or /software/index.*.
  #
  # What this function does instead is something more complicated:
  #
  # 1.  It creates an ordered prefix list, based on the identifier of the
  #     item to create a breadcrumbs trail for. For example,
  #     /software/oink.md might have the prefix list
  #     ['', '/software', '/software/oink.md'].
  #
  # 2.  For each of the elements in that list, it will create a list of
  #     patterns could match zero or more items. For example, the element
  #     '/software' would correspond to the pattern '/software.*'.
  #
  # 3.  For each of the elements in that list, and for each pattern for that
  #     element, it will find any matching element. For example, the
  #     pattern '/software.*' (coming from the prefix /software) would match
  #     the item /software.md.
  #
  # 4.  Return the list of items, with the last element replaced by the item
  #     for which the breadcrumb is generated for -- while ancestral items
  #     in the breadcrumbs trail can have a bit of ambiguity, the item for
  #     which to generate the breadcrumbs trail is fixed.

  # e.g. ['', '/foo', '/foo/bar']
  components = item.identifier.components
  prefixes = components.inject(['']) { |acc, elem| acc + [acc.last + '/' + elem] }

  tiebreaker = Int::ERROR_TIEBREAKER if tiebreaker == :error

  if @item.identifier.legacy?
    prefixes.map { |pr| @items[Nanoc::Core::Identifier.new('/' + pr, type: :legacy)] }
  else
    ancestral_prefixes = prefixes.reject { |pr| pr =~ /^\/index\./ }[0..-2]
    ancestral_items =
      ancestral_prefixes.map do |pr|
        if pr == ''
          @items['/index.*']
        else
          prefix_patterns = Int.patterns_for_prefix(pr)
          prefix_patterns.lazy.map { |pat| Int.find_one(@items, pat, tiebreaker) }.find(&:itself)
        end
      end
    ancestral_items + [item]
  end
end