Merge pull request #5572 from jekyll/fix-underscore-in-permalink

Merge pull request 5572
This commit is contained in:
jekyllbot 2016-11-14 14:28:36 -08:00 committed by GitHub
commit 88a338d345
3 changed files with 53 additions and 31 deletions

View File

@ -84,17 +84,36 @@ module Jekyll
end end
end end
# We include underscores in keys to allow for 'i_month' and so forth.
# This poses a problem for keys which are followed by an underscore
# but the underscore is not part of the key, e.g. '/:month_:day'.
# That should be :month and :day, but our key extraction regexp isn't
# smart enough to know that so we have to make it an explicit
# possibility.
def possible_keys(key)
if key.end_with?("_")
[key, key.chomp("_")]
else
[key]
end
end
def generate_url_from_drop(template) def generate_url_from_drop(template)
template.gsub(%r!:([a-z_]+)!) do |match| template.gsub(%r!:([a-z_]+)!) do |match|
key = match.sub(":".freeze, "".freeze) pool = possible_keys(match.sub(":".freeze, "".freeze))
unless @placeholders.key?(key)
raise NoMethodError, "The URL template key #{key} doesn't exist!" winner = pool.find { |key| @placeholders.key?(key) }
end if winner.nil?
if @placeholders[key].nil? raise NoMethodError,
"".freeze "The URL template doesn't have #{pool.join(" or ")} keys. "\
else "Check your permalink template!"
self.class.escape_path(@placeholders[key])
end end
value = @placeholders[winner]
value = "" if value.nil?
replacement = self.class.escape_path(value)
match.sub(":#{winner}", replacement)
end.gsub(%r!//!, "/".freeze) end.gsub(%r!//!, "/".freeze)
end end

View File

@ -103,6 +103,21 @@ class JekyllUnitTest < Minitest::Test
RSpec::Mocks.teardown RSpec::Mocks.teardown
end end
def fixture_document(relative_path)
site = fixture_site({
"collections" => {
"methods" => {
"output" => true
}
}
})
site.read
matching_doc = site.collections["methods"].docs.find do |doc|
doc.relative_path == relative_path
end
[site, matching_doc]
end
def fixture_site(overrides = {}) def fixture_site(overrides = {})
Jekyll::Site.new(site_configuration(overrides)) Jekyll::Site.new(site_configuration(overrides))
end end

View File

@ -54,17 +54,7 @@ class TestURL < JekyllUnitTest
end end
should "handle UrlDrop as a placeholder in addition to a hash" do should "handle UrlDrop as a placeholder in addition to a hash" do
site = fixture_site({ _, matching_doc = fixture_document("_methods/escape-+ #%20[].md")
"collections" => {
"methods" => {
"output" => true
}
}
})
site.read
matching_doc = site.collections["methods"].docs.find do |doc|
doc.relative_path == "_methods/escape-+ #%20[].md"
end
assert_equal "/methods/escape-+-20/escape-20.html", URL.new( assert_equal "/methods/escape-+-20/escape-20.html", URL.new(
:template => "/methods/:title/:name:output_ext", :template => "/methods/:title/:name:output_ext",
:placeholders => matching_doc.url_placeholders :placeholders => matching_doc.url_placeholders
@ -81,18 +71,16 @@ class TestURL < JekyllUnitTest
end end
end end
should "ignore NoMethodErrors when a placeholder is not found" do should "check for key without trailing underscore" do
site = fixture_site({ _, matching_doc = fixture_document("_methods/configuration.md")
"collections" => { assert_equal "/methods/configuration-configuration_methods_configuration", URL.new(
"methods" => { :template => "/methods/:name-:slug_:collection_:title",
"output" => true :placeholders => matching_doc.url_placeholders
} ).to_s
} end
})
site.read should "raise custom error when URL placeholder doesn't have key" do
matching_doc = site.collections["methods"].docs.find do |doc| _, matching_doc = fixture_document("_methods/escape-+ #%20[].md")
doc.relative_path == "_methods/escape-+ #%20[].md"
end
assert_raises NoMethodError do assert_raises NoMethodError do
URL.new( URL.new(
:template => "/methods/:headline", :template => "/methods/:headline",