Skip to content

Commit

Permalink
Merge pull request #1367 from nanoc/breadcrumb-trail-end-in-item-itself
Browse files Browse the repository at this point in the history
Ensure breadcrumb trail always ends in item itself
  • Loading branch information
denisdefreyne committed Oct 8, 2018
2 parents 439fcd0 + 34e42eb commit 2efe0fd
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
35 changes: 32 additions & 3 deletions nanoc/lib/nanoc/helpers/breadcrumbs.rb
Expand Up @@ -33,23 +33,52 @@ def self.patterns_for_prefix(prefix)

# @return [Array]
def breadcrumbs_trail
# 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] }

if @item.identifier.legacy?
prefixes.map { |pr| @items[Nanoc::Identifier.new('/' + pr, type: :legacy)] }
else
prefixes
.reject { |pr| pr =~ /^\/index\./ }
.map do |pr|
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| @items[pat] }.find(&:itself)
end
end
ancestral_items + [item]
end
end
end
Expand Down
23 changes: 23 additions & 0 deletions nanoc/spec/nanoc/helpers/breadcrumbs_spec.rb
Expand Up @@ -176,6 +176,29 @@
)
end
end

context 'child with multiple extensions' do
before do
ctx.create_item('grandchild1', {}, Nanoc::Identifier.new('/foo/stuff.zip'))
ctx.create_item('grandchild2', {}, Nanoc::Identifier.new('/foo/stuff.md'))
ctx.create_item('grandchild3', {}, Nanoc::Identifier.new('/foo/stuff.png'))
ctx.create_item('child', {}, Nanoc::Identifier.new('/foo.md'))
ctx.create_item('root', {}, Nanoc::Identifier.new('/index.md'))

ctx.item = ctx.items['/foo/stuff.md']
end

it 'picks the best parent' do
expect(subject)
.to eql(
[
ctx.items['/index.md'],
ctx.items['/foo.md'],
ctx.items['/foo/stuff.md'],
],
)
end
end
end
end
end

0 comments on commit 2efe0fd

Please sign in to comment.