From f3fd105b40afa0ee3c6e313123abcb7cfb8b5b68 Mon Sep 17 00:00:00 2001 From: Nick Quaranto Date: Fri, 24 Apr 2009 22:21:55 -0400 Subject: [PATCH 1/5] Starting feature for permalinks --- features/permalinks.feature | 54 +++++++++++++++++++++++++++++ features/site_configuration.feature | 20 ----------- 2 files changed, 54 insertions(+), 20 deletions(-) create mode 100644 features/permalinks.feature diff --git a/features/permalinks.feature b/features/permalinks.feature new file mode 100644 index 00000000..61a58360 --- /dev/null +++ b/features/permalinks.feature @@ -0,0 +1,54 @@ +Feature: Fancy permalinks + As a hacker who likes to blog + I want to be able to set permalinks + In order to make my blog URLs awesome + + Scenario: Use none permalink schema + Given I have a _posts directory + And I have the following post: + | title | date | content | + | None Permalink Schema | 3/27/2009 | Totally nothing. | + And I have a configuration file with "permalink" set to "none" + When I run jekyll + Then the _site directory should exist + And I should see "Totally nothing." in "_site/none-permalink-schema.html" + + Scenario: Use pretty permalink schema + Given I have a _posts directory + And I have the following post: + | title | date | content | + | Pretty Permalink Schema | 3/27/2009 | Totally wordpress. | + And I have a configuration file with "permalink" set to "pretty" + When I run jekyll + 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 prefix + Given I have a _posts directory + And I have the following post: + | title | category | date | content | + | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | + And I have a configuration file with "permalink" set to "blog/:year/:month/:day/:title" + When I run jekyll + Then the _site directory should exist + And I should see "Totally custom." in "_site/posts/2009/03/27/custom-permalink-scheme/index.html" + + Scenario: Use custom permalink schema with category + Given I have a _posts directory + And I have the following post: + | title | category | date | content | + | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | + And I have a configuration file with "permalink" set to ":category/:title.html" + When I run jekyll + Then the _site directory should exist + And I should see "Totally custom." in "_site/stuff/custom-permalink-scheme.html" + + Scenario: Use custom permalink schema with squished date + Given I have a _posts directory + And I have the following post: + | title | category | date | content | + | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | + And I have a configuration file with "permalink" set to ":month-:day-:year/:title.html" + When I run jekyll + Then the _site directory should exist + And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-scheme.html" diff --git a/features/site_configuration.feature b/features/site_configuration.feature index e2395b76..7d8a3885 100644 --- a/features/site_configuration.feature +++ b/features/site_configuration.feature @@ -32,26 +32,6 @@ Feature: Site configuration Then the _site directory should exist And I should see "Google" in "_site/index.html" - Scenario: Use none permalink schema - Given I have a _posts directory - And I have the following post: - | title | date | content | - | None Permalink Schema | 3/27/2009 | Totally nothing. | - And I have a configuration file with "permalink" set to "none" - When I run jekyll - Then the _site directory should exist - And I should see "Totally nothing." in "_site/none-permalink-schema.html" - - Scenario: Use pretty permalink schema - Given I have a _posts directory - And I have the following post: - | title | date | content | - | Pretty Permalink Schema | 3/27/2009 | Totally wordpress. | - And I have a configuration file with "permalink" set to "pretty" - When I run jekyll - Then the _site directory should exist - And I should see "Totally wordpress." in "_site/2009/03/27/pretty-permalink-schema/index.html" - Scenario: Highlight code with pygments Given I have an "index.html" file that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}" And I have a configuration file with "pygments" set to "true" From 73fa7dcad41be24e0d5f32856361c07b5622d7f3 Mon Sep 17 00:00:00 2001 From: Nick Quaranto Date: Fri, 24 Apr 2009 23:19:13 -0400 Subject: [PATCH 2/5] Actually testing existing permalink_style and its effect on posts --- test/test_post.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/test_post.rb b/test/test_post.rb index 815e4f36..c4e0c9db 100644 --- a/test/test_post.rb +++ b/test/test_post.rb @@ -49,6 +49,7 @@ class TestPost < Test::Unit::TestCase assert_equal "/2008/10/19/foo-bar.html", @post.url end + should "respect permalink" do file = "2008-12-03-permalinked-post.textile" @post.process(file) @@ -59,6 +60,30 @@ class TestPost < Test::Unit::TestCase assert_equal "my_category/permalinked-post", @post.url end + context "with permalink style of none" do + setup do + @post.site.permalink_style = :none + @post.categories = [] + @post.process(@fake_file) + end + + should "process the url correctly" do + assert_equal "/foo-bar.html", @post.url + end + end + + context "with permalink style of pretty" do + setup do + @post.site.permalink_style = :pretty + @post.categories = [] + @post.process(@fake_file) + end + + should "process the url correctly" do + assert_equal "/2008/10/19/foo-bar", @post.url + end + end + should "read yaml front-matter" do @post.read_yaml(@source, @real_file) From 288d5045d2fbb278505d120259bc29a6b6b9b74f Mon Sep 17 00:00:00 2001 From: Nick Quaranto Date: Sat, 25 Apr 2009 00:17:10 -0400 Subject: [PATCH 3/5] Changing to the template permalink system, only test_post passing so far --- lib/jekyll/post.rb | 25 +++++++++++++++++-- test/test_post.rb | 61 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb index 5fac0988..4d439592 100644 --- a/lib/jekyll/post.rb +++ b/lib/jekyll/post.rb @@ -109,13 +109,34 @@ module Jekyll self.data && self.data['permalink'] end + def template + case self.site.permalink_style + when :pretty + "/:year/:month/:day/:title" + when :none + "/:title.html" + when :date + "/:year/:month/:day/:title.html" + else + self.site.permalink_style + end + end + # The generated relative url of this post # e.g. /2008/11/05/my-awesome-post.html # # Returns def url - ext = self.site.permalink_style == :pretty ? '' : '.html' - permalink || self.id + ext + return permalink if permalink + + { + "year" => date.strftime("%Y"), + "month" => date.strftime("%m"), + "day" => date.strftime("%d"), + "title" => slug + }.inject(template) { |result, token| + result.gsub(/:#{token.first}/, token.last) + } end # The UID for this post (useful in feeds) diff --git a/test/test_post.rb b/test/test_post.rb index c4e0c9db..e6d08747 100644 --- a/test/test_post.rb +++ b/test/test_post.rb @@ -49,8 +49,7 @@ class TestPost < Test::Unit::TestCase assert_equal "/2008/10/19/foo-bar.html", @post.url end - - should "respect permalink" do + should "respect permalink in yaml front matter" do file = "2008-12-03-permalinked-post.textile" @post.process(file) @post.read_yaml(@source, file) @@ -60,27 +59,57 @@ class TestPost < Test::Unit::TestCase assert_equal "my_category/permalinked-post", @post.url end - context "with permalink style of none" do + + context "with site wide permalink" do setup do - @post.site.permalink_style = :none @post.categories = [] - @post.process(@fake_file) end - should "process the url correctly" do - assert_equal "/foo-bar.html", @post.url - end - end + context "with unspecified (date) style" do + setup do + @post.process(@fake_file) + end - context "with permalink style of pretty" do - setup do - @post.site.permalink_style = :pretty - @post.categories = [] - @post.process(@fake_file) + should "process the url correctly" do + assert_equal "/:year/:month/:day/:title.html", @post.template + assert_equal "/2008/10/19/foo-bar.html", @post.url + end end - should "process the url correctly" do - assert_equal "/2008/10/19/foo-bar", @post.url + context "with none style" do + setup do + @post.site.permalink_style = :none + @post.process(@fake_file) + end + + should "process the url correctly" do + assert_equal "/:title.html", @post.template + assert_equal "/foo-bar.html", @post.url + end + end + + context "with pretty style" do + setup do + @post.site.permalink_style = :pretty + @post.process(@fake_file) + end + + should "process the url correctly" do + assert_equal "/:year/:month/:day/:title", @post.template + assert_equal "/2008/10/19/foo-bar", @post.url + end + end + + context "with prefix style and no extension" do + setup do + @post.site.permalink_style = "/prefix/:title" + @post.process(@fake_file) + end + + should "process the url correctly" do + assert_equal "/prefix/:title", @post.template + assert_equal "/prefix/foo-bar", @post.url + end end end From 9da140fcb2277c6201e50980a8a6f774dac4cf29 Mon Sep 17 00:00:00 2001 From: Nick Quaranto Date: Sat, 25 Apr 2009 00:58:28 -0400 Subject: [PATCH 4/5] Getting there, prefixes work great --- features/permalinks.feature | 6 ++--- features/support/env.rb | 2 +- lib/jekyll/post.rb | 43 +++++++++++++++------------------ test/test_post.rb | 47 +++++++++++++++++++++++++++++++++---- 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/features/permalinks.feature b/features/permalinks.feature index 61a58360..defc75db 100644 --- a/features/permalinks.feature +++ b/features/permalinks.feature @@ -31,7 +31,7 @@ Feature: Fancy permalinks And I have a configuration file with "permalink" set to "blog/:year/:month/:day/:title" When I run jekyll Then the _site directory should exist - And I should see "Totally custom." in "_site/posts/2009/03/27/custom-permalink-scheme/index.html" + And I should see "Totally custom." in "_site/blog/2009/03/27/custom-permalink-schema/index.html" Scenario: Use custom permalink schema with category Given I have a _posts directory @@ -41,7 +41,7 @@ Feature: Fancy permalinks And I have a configuration file with "permalink" set to ":category/:title.html" When I run jekyll Then the _site directory should exist - And I should see "Totally custom." in "_site/stuff/custom-permalink-scheme.html" + And I should see "Totally custom." in "_site/stuff/custom-permalink-schema.html" Scenario: Use custom permalink schema with squished date Given I have a _posts directory @@ -51,4 +51,4 @@ Feature: Fancy permalinks And I have a configuration file with "permalink" set to ":month-:day-:year/:title.html" When I run jekyll Then the _site directory should exist - And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-scheme.html" + And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html" diff --git a/features/support/env.rb b/features/support/env.rb index 91734f08..c5ba09b3 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -14,5 +14,5 @@ def run_jekyll(opts = {}) bg = '&' end - system "#{JEKYLL_PATH} >> /dev/null" + system "#{JEKYLL_PATH}" #>> /dev/null" end diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb index 4d439592..928ef7e3 100644 --- a/lib/jekyll/post.rb +++ b/lib/jekyll/post.rb @@ -18,9 +18,12 @@ module Jekyll name =~ MATCHER end - attr_accessor :site - attr_accessor :date, :slug, :ext, :categories, :topics, :published - attr_accessor :data, :content, :output + attr_accessor :site, :date, :slug, :ext, :topics, :published, :data, :content, :output + attr_writer :categories + + def categories + @categories ||= [] + end # Initialize this Post instance. # +site+ is the Site @@ -88,16 +91,7 @@ module Jekyll # # Returns def dir - if permalink - permalink.to_s.split("/")[0..-2].join("/") + '/' - else - prefix = self.categories.empty? ? '' : '/' + self.categories.join('/') - if [:date, :pretty].include?(self.site.permalink_style) - prefix + date.strftime("/%Y/%m/%d/") - else - prefix + '/' - end - end + File.dirname(url) end # The full path and filename of the post. @@ -112,13 +106,13 @@ module Jekyll def template case self.site.permalink_style when :pretty - "/:year/:month/:day/:title" + "/:categories/:year/:month/:day/:title" when :none - "/:title.html" + "/:categories/:title.html" when :date - "/:year/:month/:day/:title.html" + "/:categories/:year/:month/:day/:title.html" else - self.site.permalink_style + self.site.permalink_style.to_s end end @@ -130,13 +124,14 @@ module Jekyll return permalink if permalink { - "year" => date.strftime("%Y"), - "month" => date.strftime("%m"), - "day" => date.strftime("%d"), - "title" => slug + "year" => date.strftime("%Y"), + "month" => date.strftime("%m"), + "day" => date.strftime("%d"), + "title" => slug, + "categories" => categories.sort.join('/') }.inject(template) { |result, token| result.gsub(/:#{token.first}/, token.last) - } + }.gsub(/\/\//, "/") end # The UID for this post (useful in feeds) @@ -144,7 +139,7 @@ module Jekyll # # Returns def id - self.dir + self.slug + File.join(self.dir, self.slug) end # Calculate related posts. @@ -195,7 +190,7 @@ module Jekyll path = File.join(dest, self.url) - if self.site.permalink_style == :pretty + if template[/\.html$/].nil? FileUtils.mkdir_p(path) path = File.join(path, "index.html") end diff --git a/test/test_post.rb b/test/test_post.rb index e6d08747..e01243d4 100644 --- a/test/test_post.rb +++ b/test/test_post.rb @@ -25,6 +25,7 @@ class TestPost < Test::Unit::TestCase assert !Post.valid?("blah") end + context "processing posts" do setup do @post = Post.allocate @@ -41,6 +42,8 @@ class TestPost < Test::Unit::TestCase assert_equal Time.parse("2008-10-19"), @post.date assert_equal "foo-bar", @post.slug assert_equal ".textile", @post.ext + assert_equal "/2008/10/19", @post.dir + assert_equal "/2008/10/19/foo-bar", @post.id end should "create url based on date and title" do @@ -55,11 +58,10 @@ class TestPost < Test::Unit::TestCase @post.read_yaml(@source, file) assert_equal "my_category/permalinked-post", @post.permalink - assert_equal "my_category/", @post.dir + assert_equal "my_category", @post.dir assert_equal "my_category/permalinked-post", @post.url end - context "with site wide permalink" do setup do @post.categories = [] @@ -71,11 +73,36 @@ class TestPost < Test::Unit::TestCase end should "process the url correctly" do - assert_equal "/:year/:month/:day/:title.html", @post.template + assert_equal "/:categories/:year/:month/:day/:title.html", @post.template assert_equal "/2008/10/19/foo-bar.html", @post.url end end + context "with unspecified (date) style and a category" do + setup do + @post.categories << "beer" + @post.process(@fake_file) + end + + should "process the url correctly" do + assert_equal "/:categories/:year/:month/:day/:title.html", @post.template + assert_equal "/beer/2008/10/19/foo-bar.html", @post.url + end + end + + context "with unspecified (date) style and categories" do + setup do + @post.categories << "food" + @post.categories << "beer" + @post.process(@fake_file) + end + + should "process the url correctly" do + assert_equal "/:categories/:year/:month/:day/:title.html", @post.template + assert_equal "/beer/food/2008/10/19/foo-bar.html", @post.url + end + end + context "with none style" do setup do @post.site.permalink_style = :none @@ -83,7 +110,7 @@ class TestPost < Test::Unit::TestCase end should "process the url correctly" do - assert_equal "/:title.html", @post.template + assert_equal "/:categories/:title.html", @post.template assert_equal "/foo-bar.html", @post.url end end @@ -95,7 +122,7 @@ class TestPost < Test::Unit::TestCase end should "process the url correctly" do - assert_equal "/:year/:month/:day/:title", @post.template + assert_equal "/:categories/:year/:month/:day/:title", @post.template assert_equal "/2008/10/19/foo-bar", @post.url end end @@ -198,6 +225,16 @@ class TestPost < Test::Unit::TestCase assert File.exists?(File.join(dest_dir, '2008', '10', '18', 'foo-bar.html')) end + should "write properly without html extension" do + post = setup_post("2008-10-18-foo-bar.textile") + post.site.permalink_style = ":title" + do_render(post) + post.write(dest_dir) + + assert File.directory?(dest_dir) + assert File.exists?(File.join(dest_dir, 'foo-bar', 'index.html')) + end + should "insert data" do post = setup_post("2008-11-21-complex.textile") do_render(post) From 080108b0f0a5cc50aa1eefdc80dc2d03897baef7 Mon Sep 17 00:00:00 2001 From: Nick Quaranto Date: Sat, 25 Apr 2009 01:07:05 -0400 Subject: [PATCH 5/5] Making sure permalinks were set right, and only generating the url once --- features/permalinks.feature | 6 +++--- features/support/env.rb | 2 +- lib/jekyll/post.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/features/permalinks.feature b/features/permalinks.feature index defc75db..9bd7c848 100644 --- a/features/permalinks.feature +++ b/features/permalinks.feature @@ -28,7 +28,7 @@ Feature: Fancy permalinks And I have the following post: | title | category | date | content | | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | - And I have a configuration file with "permalink" set to "blog/:year/:month/:day/:title" + And I have a configuration file with "permalink" set to "/blog/:year/:month/:day/:title" When I run jekyll Then the _site directory should exist And I should see "Totally custom." in "_site/blog/2009/03/27/custom-permalink-schema/index.html" @@ -38,7 +38,7 @@ Feature: Fancy permalinks And I have the following post: | title | category | date | content | | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | - And I have a configuration file with "permalink" set to ":category/:title.html" + And I have a configuration file with "permalink" set to "/:categories/:title.html" When I run jekyll Then the _site directory should exist And I should see "Totally custom." in "_site/stuff/custom-permalink-schema.html" @@ -48,7 +48,7 @@ Feature: Fancy permalinks And I have the following post: | title | category | date | content | | Custom Permalink Schema | stuff | 3/27/2009 | Totally custom. | - And I have a configuration file with "permalink" set to ":month-:day-:year/:title.html" + And I have a configuration file with "permalink" set to "/:month-:day-:year/:title.html" When I run jekyll Then the _site directory should exist And I should see "Totally custom." in "_site/03-27-2009/custom-permalink-schema.html" diff --git a/features/support/env.rb b/features/support/env.rb index c5ba09b3..91734f08 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -14,5 +14,5 @@ def run_jekyll(opts = {}) bg = '&' end - system "#{JEKYLL_PATH}" #>> /dev/null" + system "#{JEKYLL_PATH} >> /dev/null" end diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb index 928ef7e3..dfd1fc31 100644 --- a/lib/jekyll/post.rb +++ b/lib/jekyll/post.rb @@ -123,7 +123,7 @@ module Jekyll def url return permalink if permalink - { + @url ||= { "year" => date.strftime("%Y"), "month" => date.strftime("%m"), "day" => date.strftime("%d"),