From 6a98ab2a1569f7d515bafcc9067bf7e8dd5c4ee6 Mon Sep 17 00:00:00 2001 From: rebornix Date: Wed, 18 Nov 2015 10:43:13 +0800 Subject: [PATCH] Make `:title` cased for backwards compability and add `:slug` for uncased usage. --- features/permalinks.feature | 24 +++++++++++++++++ lib/jekyll/document.rb | 4 ++- lib/jekyll/filters.rb | 2 +- lib/jekyll/utils.rb | 27 +++++++++++++------ site/_docs/permalinks.md | 16 +++++++++-- .../_slides/example-slide-Upper-Cased.html | 6 +++++ test/test_document.rb | 24 +++++++++++++++-- test/test_utils.rb | 25 +++++++++++++---- 8 files changed, 109 insertions(+), 19 deletions(-) create mode 100644 test/source/_slides/example-slide-Upper-Cased.html diff --git a/features/permalinks.feature b/features/permalinks.feature index bc13de88..74f2e409 100644 --- a/features/permalinks.feature +++ b/features/permalinks.feature @@ -96,3 +96,27 @@ Feature: Fancy permalinks Then the _site directory should exist And the _site/custom/posts directory should exist And I should see "bla bla" in "_site/custom/posts/some.html" + + Scenario: Use pretty permalink schema with cased file name + Given I have a _posts directory + And I have an "_posts/2009-03-27-Pretty-Permalink-Schema.md" page that contains "Totally wordpress" + And I have a configuration file with "permalink" set to "pretty" + When I run jekyll build + Then the _site directory should exist + And I should see "Totally wordpress." in "_site/2009/03/27/Pretty-Permalink-Schema/index.html" + + Scenario: Use custom permalink schema with cased file name + Given I have a _posts directory + And I have an "_posts/2009-03-27-Custom-Schema.md" page with title "Custom Schema" that contains "Totally awesome" + And I have a configuration file with "permalink" set to "/:year/:month/:day/:slug/" + When I run jekyll build + Then the _site directory should exist + And I should see "Totally awesome" in "_site/2009/03/27/custom-schema/index.html" + + Scenario: Use pretty permalink schema with title containing underscore + Given I have a _posts directory + And I have an "_posts/2009-03-27-Custom_Schema.md" page with title "Custom Schema" that contains "Totally awesome" + And I have a configuration file with "permalink" set to "pretty" + When I run jekyll build + Then the _site directory should exist + And I should see "Totally awesome" in "_site/2009/03/27/Custom_Schema/index.html" diff --git a/lib/jekyll/document.rb b/lib/jekyll/document.rb index 5af8d610..528fed68 100644 --- a/lib/jekyll/document.rb +++ b/lib/jekyll/document.rb @@ -186,7 +186,9 @@ module Jekyll path: cleaned_relative_path, output_ext: output_ext, name: Utils.slugify(basename_without_ext), - title: Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext), + title: Utils.slugify(data['slug'], mode: "pretty", cased: true) || Utils + .slugify(basename_without_ext, mode: "pretty", cased: true), + slug: Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext), year: date.strftime("%Y"), month: date.strftime("%m"), day: date.strftime("%d"), diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb index 72c332ad..7e2d30f3 100644 --- a/lib/jekyll/filters.rb +++ b/lib/jekyll/filters.rb @@ -45,7 +45,7 @@ module Jekyll # Returns the given filename or title as a lowercase URL String. # See Utils.slugify for more detail. def slugify(input, mode=nil) - Utils.slugify(input, mode) + Utils.slugify(input, mode: mode) end # Format a date in short format e.g. "27 Jan 2011". diff --git a/lib/jekyll/utils.rb b/lib/jekyll/utils.rb index c30a986a..7d2490a6 100644 --- a/lib/jekyll/utils.rb +++ b/lib/jekyll/utils.rb @@ -121,10 +121,12 @@ module Jekyll # # string - the filename or title to slugify # mode - how string is slugified + # cased - whether to replace all uppercase letters with their + # lowercase counterparts # - # When mode is "none", return the given string in lowercase. + # When mode is "none", return the given string. # - # When mode is "raw", return the given string in lowercase, + # When mode is "raw", return the given string, # with every sequence of spaces characters replaced with a hyphen. # # When mode is "default" or nil, non-alphabetic characters are @@ -133,6 +135,9 @@ module Jekyll # When mode is "pretty", some non-alphabetic characters (._~!$&'()+,;=@) # are not replaced with hyphen. # + # If cased is true, all uppercase letters in the result string are + # replaced with their lowercase counterparts. + # # Examples: # slugify("The _config.yml file") # # => "the-config-yml-file" @@ -140,11 +145,17 @@ module Jekyll # slugify("The _config.yml file", "pretty") # # => "the-_config.yml-file" # + # slugify("The _config.yml file", "pretty", true) + # # => "The-_config.yml file" + # # Returns the slugified string. - def slugify(string, mode=nil) + def slugify(string, mode: nil, cased: false) mode ||= 'default' return nil if string.nil? - return string.downcase unless SLUGIFY_MODES.include?(mode) + + unless SLUGIFY_MODES.include?(mode) + return cased ? string : string.downcase + end # Replace each character sequence with a hyphen re = case mode @@ -158,13 +169,13 @@ module Jekyll SLUGIFY_PRETTY_REGEXP end - string. + slug = string. # Strip according to the mode gsub(re, '-'). # Remove leading/trailing hyphen - gsub(/^\-|\-$/i, ''). - # Downcase - downcase + gsub(/^\-|\-$/i, '') + + cased ? slug : slug.downcase end # Add an appropriate suffix to template so that it matches the specified diff --git a/site/_docs/permalinks.md b/site/_docs/permalinks.md index e82ecf6d..5aa0449a 100644 --- a/site/_docs/permalinks.md +++ b/site/_docs/permalinks.md @@ -109,8 +109,20 @@ permalink is defined according to the format `/:categories/:year/:month/:day/:ti

- Title from the document’s filename. May be overridden via the - document’s slug YAML front matter. + Title from the document’s filename. May be overridden via + the document’s slug YAML front matter. +

+ + + + +

slug

+ + +

+ Slugified title from the document’s filename ( any character + except numbers and letters is replaced as hyphen ). May be + overridden via the document’s slug YAML front matter.

diff --git a/test/source/_slides/example-slide-Upper-Cased.html b/test/source/_slides/example-slide-Upper-Cased.html new file mode 100644 index 00000000..24aee8e7 --- /dev/null +++ b/test/source/_slides/example-slide-Upper-Cased.html @@ -0,0 +1,6 @@ +--- + title: Example Slide + layout: slide +--- + +Cased! diff --git a/test/test_document.rb b/test/test_document.rb index a1e0c9cd..6689e506 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -234,6 +234,26 @@ class TestDocument < JekyllUnitTest end end + context "a document in a collection with cased file name" do + setup do + @site = fixture_site({ + "collections" => { + "slides" => { + "output" => true, + } + }, + }) + @site.permalink_style = :pretty + @site.process + @document = @site.collections["slides"].docs[6] + @dest_file = dest_dir("slides/example-slide-Upper-Cased/index.html") + end + + should "produce the right cased URL" do + assert_equal "/slides/example-slide-Upper-Cased/", @document.url + end + end + context "documents in a collection with custom title permalinks" do setup do @site = fixture_site({ @@ -267,10 +287,10 @@ class TestDocument < JekyllUnitTest end should "produce the right URL if they have a wild slug" do - assert_equal "/slides/well-so-what-is-jekyll-then", @document_with_strange_slug.url + assert_equal "/slides/Well,-so-what-is-Jekyll,-then", @document_with_strange_slug.url end should "produce the right destination file if they have a wild slug" do - dest_file = dest_dir("/slides/well-so-what-is-jekyll-then.html") + dest_file = dest_dir("/slides/Well,-so-what-is-Jekyll,-then.html") assert_equal dest_file, @document_with_strange_slug.destination(dest_dir) end end diff --git a/test/test_utils.rb b/test/test_utils.rb index 9d4a5a4d..d1ec2ece 100644 --- a/test/test_utils.rb +++ b/test/test_utils.rb @@ -146,23 +146,38 @@ class TestUtils < JekyllUnitTest end should "not change behaviour if mode is default" do - assert_equal "the-config-yml-file", Utils.slugify("The _config.yml file?", "default") + assert_equal "the-config-yml-file", Utils.slugify("The _config.yml file?", mode: "default") end should "not change behaviour if mode is nil" do - assert_equal "the-config-yml-file", Utils.slugify("The _config.yml file?", nil) + assert_equal "the-config-yml-file", Utils.slugify("The _config.yml file?") end should "not replace period and underscore if mode is pretty" do - assert_equal "the-_config.yml-file", Utils.slugify("The _config.yml file?", "pretty") + assert_equal "the-_config.yml-file", Utils.slugify("The _config.yml file?", mode: "pretty") end should "only replace whitespace if mode is raw" do - assert_equal "the-_config.yml-file?", Utils.slugify("The _config.yml file?", "raw") + assert_equal "the-_config.yml-file?", Utils.slugify("The _config.yml file?", mode: "raw") end should "return the given string if mode is none" do - assert_equal "the _config.yml file?", Utils.slugify("The _config.yml file?", "none") + assert_equal "the _config.yml file?", Utils.slugify("The _config.yml file?", mode: "none") + end + + should "Keep all uppercase letters if cased is true" do + assert_equal "Working-with-drafts", Utils.slugify("Working with drafts", cased: true) + assert_equal "Basic-Usage", Utils.slugify("Basic Usage", cased: true) + assert_equal "Working-with-drafts", Utils.slugify(" Working with drafts ", cased: true) + assert_equal "So-what-is-Jekyll-exactly", Utils.slugify("So what is Jekyll, exactly?", cased: true) + assert_equal "Pre-releases", Utils.slugify("Pre-releases", cased: true) + assert_equal "The-config-yml-file", Utils.slugify("The _config.yml file", cased: true) + assert_equal "Customizing-Git-Git-Hooks", Utils.slugify("Customizing Git - Git Hooks", cased: true) + assert_equal "The-config-yml-file", Utils.slugify("The _config.yml file?", mode: "default", cased: true) + assert_equal "The-config-yml-file", Utils.slugify("The _config.yml file?", cased: true) + assert_equal "The-_config.yml-file", Utils.slugify("The _config.yml file?", mode: "pretty", cased: true) + assert_equal "The-_config.yml-file?", Utils.slugify("The _config.yml file?", mode: "raw", cased: true) + assert_equal "The _config.yml file?", Utils.slugify("The _config.yml file?", mode: "none", cased: true) end end