diff --git a/docs/_docs/configuration.md b/docs/_docs/configuration.md
index 63ebd047440..6f00ab535de 100644
--- a/docs/_docs/configuration.md
+++ b/docs/_docs/configuration.md
@@ -549,7 +549,9 @@ defaults:
In this example, the `layout` is set to `default` inside the
[collection](../collections/) with the name `my_collection`.
-It is also possible to use glob patterns when matching defaults. For example, it is possible to set specific layout for each `special-page.html` in any subfolder of `section` folder. {%- include docs_version_badge.html version="3.7.0" -%}
+### Glob patterns in Front Matter defaults
+
+It is also possible to use glob patterns (currently limited to patterns that contain `*`) when matching defaults. For example, it is possible to set specific layout for each `special-page.html` in any subfolder of `section` folder. {%- include docs_version_badge.html version="3.7.0" -%}
```yaml
collections:
@@ -564,6 +566,17 @@ defaults:
layout: "specific-layout"
```
+
+
Globbing and Performance
+
+ Please note that globbing a path is known to have a negative effect on
+ performance and is currently not optimized, especially on Windows.
+ Globbing a path will increase your build times in proportion to the size
+ of the associated collection directory.
+
+
+
+
### Precedence
Jekyll will apply all of the configuration settings you specify in the `defaults` section of your `_config.yml` file. However, you can choose to override settings from other scope/values pair by specifying a more specific path for the scope.
diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb
index f6b89f6bb60..be749384c6b 100644
--- a/lib/jekyll/frontmatter_defaults.rb
+++ b/lib/jekyll/frontmatter_defaults.rb
@@ -97,21 +97,27 @@ def applies?(scope, path, type)
applies_path?(scope, path) && applies_type?(scope, type)
end
+ # rubocop:disable Metrics/AbcSize
def applies_path?(scope, path)
return true if !scope.key?("path") || scope["path"].empty?
sanitized_path = Pathname.new(sanitize_path(path))
-
- site_path = Pathname.new(@site.source)
+ site_path = Pathname.new(@site.source)
rel_scope_path = Pathname.new(scope["path"])
abs_scope_path = File.join(@site.source, rel_scope_path)
- Dir.glob(abs_scope_path).each do |scope_path|
- scope_path = Pathname.new(scope_path).relative_path_from site_path
- return true if path_is_subpath?(sanitized_path, scope_path)
- end
- path_is_subpath?(sanitized_path, rel_scope_path)
+ if scope["path"].to_s.include?("*")
+ Dir.glob(abs_scope_path).each do |scope_path|
+ scope_path = Pathname.new(scope_path).relative_path_from site_path
+ Jekyll.logger.debug "Globbed Scope Path:", scope_path
+ return true if path_is_subpath?(sanitized_path, scope_path)
+ end
+ false
+ else
+ path_is_subpath?(sanitized_path, rel_scope_path)
+ end
end
+ # rubocop:enable Metrics/AbcSize
def path_is_subpath?(path, parent_path)
path.ascend do |ascended_path|
diff --git a/test/test_front_matter_defaults.rb b/test/test_front_matter_defaults.rb
index b1773ba0ecb..2f996a9f303 100644
--- a/test/test_front_matter_defaults.rb
+++ b/test/test_front_matter_defaults.rb
@@ -16,7 +16,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
},
},],
})
- @site.process
+ @output = capture_output { @site.process }
@affected = @site.pages.find { |page| page.relative_path == "contacts/bar.html" }
@not_affected = @site.pages.find { |page| page.relative_path == "about.html" }
end
@@ -25,6 +25,10 @@ class TestFrontMatterDefaults < JekyllUnitTest
assert_equal @affected.data["key"], "val"
assert_nil @not_affected.data["key"]
end
+
+ should "not call Dir.glob block" do
+ refute_includes @output, "Globbed Scope Path:"
+ end
end
context "A site with full front matter defaults (glob)" do
@@ -40,7 +44,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
},
},],
})
- @site.process
+ @output = capture_output { @site.process }
@affected = @site.pages.find { |page| page.relative_path == "contacts/bar.html" }
@not_affected = @site.pages.find { |page| page.relative_path == "about.html" }
end
@@ -49,6 +53,10 @@ class TestFrontMatterDefaults < JekyllUnitTest
assert_equal @affected.data["key"], "val"
assert_nil @not_affected.data["key"]
end
+
+ should "call Dir.glob block" do
+ assert_includes @output, "Globbed Scope Path:"
+ end
end
context "A site with front matter type pages and an extension" do