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:
parent
38e6ac3f8e
commit
5426f9dff9
4 changed files with 97 additions and 17 deletions
|
@ -37,3 +37,11 @@ Feature: i18n merging path trees
|
||||||
When I go to "/es/b/sub.html"
|
When I go to "/es/b/sub.html"
|
||||||
Then I should see "Current locale: es"
|
Then I should see "Current locale: es"
|
||||||
Then I should see "path: is-localized Home # b/index.html.erb # b/sub.html.erb"
|
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"
|
||||||
|
|
|
@ -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(" # ")
|
||||||
|
%>
|
|
@ -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(" # ")
|
||||||
|
%>
|
|
@ -14,29 +14,84 @@ module Middleman
|
||||||
|
|
||||||
# This resource's parent resource
|
# This resource's parent resource
|
||||||
# @return [Middleman::Sitemap::Resource, nil]
|
# @return [Middleman::Sitemap::Resource, nil]
|
||||||
def parent
|
def parent(recurse=false)
|
||||||
root = path.sub(/^#{::Regexp.escape(traversal_root)}/, '')
|
max_recursion = @app.config[:max_traversal_recursion] || 99
|
||||||
parts = root.split('/')
|
_parent(path, max_recursion)
|
||||||
|
end
|
||||||
|
|
||||||
tail = parts.pop
|
def _parent(_path, max_recursion)
|
||||||
is_index = (tail == @app.config[:index_file])
|
# 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?
|
# Check that we have any path parts left after the pop because if we
|
||||||
return is_index ? nil : @store.find_resource_by_path(@app.config[:index_file])
|
# 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
|
end
|
||||||
|
|
||||||
test_expr = parts.join('\\/')
|
# Get the index file for the parent path parts, e.g.: `/blog/index.html`
|
||||||
# eponymous reverse-lookup
|
# for `/blog/`.
|
||||||
found = @store.resources.find do |candidate|
|
index_by_parts = Proc.new do |parts|
|
||||||
candidate.path =~ %r{^#{test_expr}(?:\.[a-zA-Z0-9]+|\/)$}
|
found = @store.find_resource_by_destination_path("#{parts.join('/')}/#{index_file}")
|
||||||
|
return found unless found.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
if found
|
# Get a file that has the name of the parent path parts e.g.:
|
||||||
found
|
# `/blog.html` for `/blog/`.
|
||||||
else
|
file_by_parts = Proc.new do |parts|
|
||||||
parts.pop if is_index
|
test_expr = Regexp.escape(parts.join('/'))
|
||||||
@store.find_resource_by_destination_path("#{parts.join('/')}/#{@app.config[:index_file]}")
|
# 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
|
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
|
end
|
||||||
|
|
||||||
# This resource's child resources
|
# This resource's child resources
|
||||||
|
@ -68,7 +123,6 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# This resource's sibling resources
|
# This resource's sibling resources
|
||||||
# @return [Array<Middleman::Sitemap::Resource>]
|
# @return [Array<Middleman::Sitemap::Resource>]
|
||||||
def siblings
|
def siblings
|
||||||
|
|
Loading…
Reference in a new issue