1
0
Fork 0
mirror of https://github.com/middleman/middleman.git synced 2022-11-09 12:20:27 -05:00

Fix localisation and recursion issues of Traversal::parent. (#2188)

This commit is contained in:
Chris 2018-09-10 18:31:32 +00:00 committed by Thomas Reynolds
parent 38e6ac3f8e
commit 5426f9dff9
4 changed files with 97 additions and 17 deletions

View file

@ -37,3 +37,11 @@ Feature: i18n merging path trees
When I go to "/es/b/sub.html"
Then I should see "Current locale: es"
Then I should see "path: is-localized Home # b/index.html.erb # b/sub.html.erb"
When I go to "/c/d/index.html"
Then I should see "Current locale: en"
Then I should see "path: is-localized Home # c/d/index.html.erb"
When I go to "/es/c/d/index.html"
Then I should see "Current locale: es"
Then I should see "path: is-localized Home # c/d/index.html.erb"

View file

@ -0,0 +1,9 @@
---
title: c/d/index.html.erb
---
Current locale: <%= I18n.locale %>
path: <%=
hierarchy = [current_page]
hierarchy.unshift hierarchy.first.parent true while hierarchy.first.parent true
hierarchy.collect {|page| page.data.title }.join(" # ")
%>

View file

@ -0,0 +1,9 @@
---
title: c/d/index.html.erb
---
Current locale: <%= I18n.locale %>
path: <%=
hierarchy = [current_page]
hierarchy.unshift hierarchy.first.parent true while hierarchy.first.parent true
hierarchy.collect {|page| page.data.title }.join(" # ")
%>

View file

@ -14,29 +14,84 @@ module Middleman
# This resource's parent resource
# @return [Middleman::Sitemap::Resource, nil]
def parent
root = path.sub(/^#{::Regexp.escape(traversal_root)}/, '')
parts = root.split('/')
def parent(recurse=false)
max_recursion = @app.config[:max_traversal_recursion] || 99
_parent(path, max_recursion)
end
tail = parts.pop
is_index = (tail == @app.config[:index_file])
def _parent(_path, max_recursion)
# What is the configured format for index pages.
index_file = @app.config[:index_file]
parts = _path.split('/')
# Reduce the path by the current page to get the parent level path.
current_page = parts.pop
# Does the current page has the name of an index file?
is_index = current_page == index_file
# Is the `current_page` in the traversal root?
# Note: `traversal_root` is `/` for non localised pages and `/[lang]/` for
# localised pages.
at_traversal_root = !(_path =~ /^#{traversal_root}#{current_page}$/).nil?
if parts.empty?
return is_index ? nil : @store.find_resource_by_path(@app.config[:index_file])
# Check that we have any path parts left after the pop because if we
# don't, `current_page` is either root or another file under root.
# Also, if we are `at_traversal_root`, we consider this root.
if parts.empty? || at_traversal_root
# If this `is_index`, the `current_page` is root and there is no parent.
if is_index
return nil
else
# `current_page` must be a page under root, let's return the root
# index page of the `traversal_root` (`/` or `/[lang]/`).
return @store.find_resource_by_path("#{traversal_root}#{index_file}")
end
end
test_expr = parts.join('\\/')
# eponymous reverse-lookup
found = @store.resources.find do |candidate|
candidate.path =~ %r{^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$}
# Get the index file for the parent path parts, e.g.: `/blog/index.html`
# for `/blog/`.
index_by_parts = Proc.new do |parts|
found = @store.find_resource_by_destination_path("#{parts.join('/')}/#{index_file}")
return found unless found.nil?
end
if found
found
else
parts.pop if is_index
@store.find_resource_by_destination_path("#{parts.join('/')}/#{@app.config[:index_file]}")
# Get a file that has the name of the parent path parts e.g.:
# `/blog.html` for `/blog/`.
file_by_parts = Proc.new do |parts|
test_expr = Regexp.escape(parts.join('/'))
# eponymous reverse-lookup
found = @store.resources.find do |candidate|
candidate.path =~ %r{^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$}
end
return found unless found.nil?
end
# Try to find a file matching the parent path name and return it.
# E.g. `parts == ['en', 'blog']`, we try to find: `/en/blog.html`
file_by_parts.call(parts)
# Try to find an non-localised parent instead if `traversal_root`
# indicates the path is localised and there are still more parts
# remaining, and return it.
# E.g. `parts == ['en', 'blog']`, we try to find: `/blog.html`
if traversal_root != "/" && parts.length > 1
file_by_parts.call(parts[1..-1])
end
# Now let's drop the last part of the path to try to find an index
# file in the path above `current_page`'s path and return it.
# E.g. `parts == ['en', 'blog']`, we try to find: `/en/index.html`
parts.pop if is_index
index_by_parts.call(parts)
# Lastly, check for an non-localised index index file in the path
# above `current_page`'s path and return it.
# E.g. `parts == ['en', 'blog']`, we try to find: `/index.html`
if traversal_root == "#{parts.first}/"
index_by_parts.call(parts[1..-1] || "")
end
if !parts.empty? && max_recursion > 0
return _parent parts.join('/'), max_recursion - 1
end
return nil
end
# This resource's child resources
@ -68,7 +123,6 @@ module Middleman
end
end
end
# This resource's sibling resources
# @return [Array<Middleman::Sitemap::Resource>]
def siblings