在深入研究了 Middleman 的代码之后,我发现了一个 Cucumber 测试,它描述了#parent
、#children
和#siblings
方法。
中间人/中间人核心/功能/sitemap_traversal.feature:
Feature: Step through sitemap as a tree
Scenario: Root
Given the Server is running at "traversal-app"
When I go to "/index.html"
Then I should see "Path: index.html"
Then I should not see "Parent: index.html"
Then I should see "Child: sub/index.html"
Then I should see "Child: root.html"
Then I should not see "Child: proxied.html"
...continued...
- 简而言之,似乎可以在文件名“index.html”的上一级找到父资源,所以如果您正在查看
/foo/bar/some_resource.html
,它的父资源可以在/foo/index.html
.
- 它的兄弟姐妹与请求处于同一级别(请注意,“同名目录”被转换为“索引文件”,例如
/foo/bar/
become /foo/bar.html
,使其兄弟姐妹处于同一/foo/*
级别。)
- 它的孩子在下面的级别。
通过将任何文件放置在文件层次结构中的相应位置,您应该能够通过调用#parent
、#children
或引用该文件或包含该文件的集合#siblings
。
在阅读测试时请注意,在配置文件中设置了几个“假”路由(/sub/fake.html
andfake2.html
和/directory-indexed/fake.html
and ) 。fake2.html
更深的潜水
如果你不能从表面上接受 Cucumber 测试(我不怪你),还有更多!毕竟,这是什么,“我应该看到”和“我不应该看到”的废话?嗯,有一个答案。
在测试的夹具( middleman/middleman -core/fixtures/traversal-app/)中,layout.erb是唯一包含任何内容的文件。在其中,您可以看到在 html 文档的正文中打印出 Child、Parent 和 Sibling 路径。
中间人/中间人核心/固定装置/遍历应用程序/源/ layout.erb:
Path: <%= current_page.path %>
Source: <%= current_page.source_file.sub(root + "/", "") %>
<% if current_page.parent %>
Parent: <%= current_page.parent.path %>
<% end %>
...continued...
这有助于解释测试,这些测试只是在响应正文中查找来自布局的字符串。您可以在 Cucumber 步骤定义 ( middleman / middleman-core / lib / middleman-core / step_definitions / )中看到测试的确切行为。
最后,布局使用我们首先要描述的方法,#parent
,#children
, 和#siblings
,它们在 middleman-core 中定义。
在middleman/middleman-core/lib/middleman-core/sitemap/extensions/traversal.rb 中:
module Traversal
# This resource's parent resource
# @return [Middleman::Sitemap::Resource, nil]
def parent
parts = path.split("/")
parts.pop if path.include?(app.index_file)
return nil if parts.length < 1
parts.pop
parts << app.index_file
parent_path = "/" + parts.join("/")
store.find_resource_by_destination_path(parent_path)
end
# This resource's child resources
# @return [Array<Middleman::Sitemap::Resource>]
def children
return [] unless directory_index?
if eponymous_directory?
base_path = eponymous_directory_path
prefix = %r|^#{base_path.sub("/", "\\/")}|
else
base_path = path.sub("#{app.index_file}", "")
prefix = %r|^#{base_path.sub("/", "\\/")}|
end
store.resources.select do |sub_resource|
if sub_resource.path == self.path || sub_resource.path !~ prefix
false
else
inner_path = sub_resource.path.sub(prefix, "")
parts = inner_path.split("/")
if parts.length == 1
true
elsif parts.length == 2
parts.last == app.index_file
else
false
end
end
end
end
# This resource's sibling resources
# @return [Array<Middleman::Sitemap::Resource>]
def siblings
return [] unless parent
parent.children.reject { |p| p == self }
end
...continued...
end
我将不再解释 Ruby 代码,因为我得赶紧上班了。如果您希望我进一步调查,请在评论中告诉我,我会回复的。