From 19e704f408268f037e9d612ae85adbf253583254 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Mon, 5 May 2014 10:26:46 +0200
Subject: [PATCH 01/14] Override the sort filter
---
lib/jekyll/filters.rb | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb
index 997a0f5d..ced9623f 100644
--- a/lib/jekyll/filters.rb
+++ b/lib/jekyll/filters.rb
@@ -190,6 +190,29 @@ module Jekyll
input.select { |object| object[key] == value }
end
+ # Sort an array of objects
+ #
+ # input - the object array
+ # key - key within each object to filter by
+ # nils_last - nils appear after non-nil values in the sort ordering
+ #
+ # Returns the filtered array of objects
+ def sort(input, key = nil, nils_last = false)
+ if key.nil?
+ input.sort
+ else
+ input.sort { |a, b|
+ if a[key].nil? and !b[key].nil?
+ nils_last ? +1 : -1
+ elsif !a[key].nil? and b[key].nil?
+ nils_last ? -1 : +1
+ else
+ a[key] <=> b[key]
+ end
+ }
+ end
+ end
+
private
def time(input)
case input
From 3517b9f4e2d2f7d38d448d49b9bb59f2419f875e Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Mon, 5 May 2014 10:35:19 +0200
Subject: [PATCH 02/14] Add scenario
---
features/embed_filters.feature | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/features/embed_filters.feature b/features/embed_filters.feature
index 27f5f1df..e0d85cbd 100644
--- a/features/embed_filters.feature
+++ b/features/embed_filters.feature
@@ -73,3 +73,19 @@ Feature: Embed filters
Then the _site directory should exist
And I should see exactly "Page-2, Page-1" in "_site/page-1.html"
And I should see exactly "Page-2, Page-1" in "_site/page-2.html"
+
+ Scenario: Sort pages by the title
+ Given I have a _layouts directory
+ And I have the following page:
+ | title | layout | content |
+ | Dog | default | Run |
+ And I have the following page:
+ | title | layout | content |
+ | Bird | default | Fly |
+ And I have the following page:
+ | layout | content |
+ | default | Jump |
+ And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title' %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
+ When I run jekyll build
+ Then the _site directory should exist
+ And I should see exactly "The rule of 3: Jump, Fly, Run," in "_site/bird.html"
From 367a818c267408f364427e0e7eba1d2a4ea9ea14 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Mon, 5 May 2014 10:37:21 +0200
Subject: [PATCH 03/14] Fallback title based on time
---
features/support/env.rb | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/features/support/env.rb b/features/support/env.rb
index 80020690..29875629 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -28,7 +28,11 @@ def run_jekyll(args)
end
def slug(title)
- title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
+ if title
+ title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
+ else
+ Time.now.strftime("%s%9N") # nanoseconds since the Epoch
+ end
end
def location(folder, direction)
From 12d9f8b02bffb0cc779d78216d302758c7a4eb09 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Mon, 5 May 2014 10:49:29 +0200
Subject: [PATCH 04/14] Add scenario for ordering pages without title last
---
features/embed_filters.feature | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/features/embed_filters.feature b/features/embed_filters.feature
index e0d85cbd..b1a420f5 100644
--- a/features/embed_filters.feature
+++ b/features/embed_filters.feature
@@ -89,3 +89,19 @@ Feature: Embed filters
When I run jekyll build
Then the _site directory should exist
And I should see exactly "The rule of 3: Jump, Fly, Run," in "_site/bird.html"
+
+ Scenario: Sort pages by the title ordering pages without title last
+ Given I have a _layouts directory
+ And I have the following page:
+ | title | layout | content |
+ | Dog | default | Run |
+ And I have the following page:
+ | title | layout | content |
+ | Bird | default | Fly |
+ And I have the following page:
+ | layout | content |
+ | default | Jump |
+ And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title', true %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
+ When I run jekyll build
+ Then the _site directory should exist
+ And I should see exactly "The rule of 3: Fly, Run, Jump," in "_site/bird.html"
From cc80aab1919ece7872af24f1ca735dea1e500464 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Mon, 5 May 2014 11:14:07 +0200
Subject: [PATCH 05/14] Add generic tests
---
test/test_filters.rb | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/test/test_filters.rb b/test/test_filters.rb
index 67bcd096..0d3d8def 100644
--- a/test/test_filters.rb
+++ b/test/test_filters.rb
@@ -152,5 +152,24 @@ class TestFilters < Test::Unit::TestCase
end
end
+ context "sort filter" do
+ should "return sorted array" do
+ assert_equal [1, 2, 3, 4], @filter.sort([4, 3, 2, 1])
+ end
+ should "return sorted by property array" do
+ assert_equal [{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}],
+ @filter.sort([{"a" => 4}, {"a" => 3}, {"a" => 1}, {"a" => 2}], "a")
+ end
+ should "return sorted by property array with nils first" do
+ ary = [{"a" => 2}, {"b" => 1}, {"a" => 1}]
+ assert_equal [{"b" => 1}, {"a" => 1}, {"a" => 2}], @filter.sort(ary, "a")
+ assert_equal @filter.sort(ary, "a"), @filter.sort(ary, "a", false)
+ end
+ should "return sorted by property array with nils last" do
+ assert_equal [{"a" => 1}, {"a" => 2}, {"b" => 1}],
+ @filter.sort([{"a" => 2}, {"b" => 1}, {"a" => 1}], "a", true)
+ end
+ end
+
end
end
From 9c9e96cfa7bfe73f41e2d35a71f822907000c554 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 07:48:33 +0200
Subject: [PATCH 06/14] Add lexicographical sort test
---
test/test_filters.rb | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/test/test_filters.rb b/test/test_filters.rb
index 0d3d8def..94093259 100644
--- a/test/test_filters.rb
+++ b/test/test_filters.rb
@@ -169,6 +169,12 @@ class TestFilters < Test::Unit::TestCase
assert_equal [{"a" => 1}, {"a" => 2}, {"b" => 1}],
@filter.sort([{"a" => 2}, {"b" => 1}, {"a" => 1}], "a", true)
end
+ should "return lexicographical sorted array" do
+ assert_equal [2, 10], @filter.sort([10, 2])
+ assert_equal [{"a" => 2}, {"a" => 10}], @filter.sort([{"a" => 10}, {"a" => 2}], "a")
+ assert_equal ["10", "2"], @filter.sort(["10", "2"])
+ assert_equal [{"a" => "10"}, {"a" => "2"}], @filter.sort([{"a" => "10"}, {"a" => "2"}], "a")
+ end
end
end
From 558d0e8ac9ae48719a71eac48ffc5cb06fbd33c4 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 21:07:09 +0200
Subject: [PATCH 07/14] Add more strings tests
---
test/test_filters.rb | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/test/test_filters.rb b/test/test_filters.rb
index 94093259..66db980e 100644
--- a/test/test_filters.rb
+++ b/test/test_filters.rb
@@ -153,8 +153,14 @@ class TestFilters < Test::Unit::TestCase
end
context "sort filter" do
- should "return sorted array" do
- assert_equal [1, 2, 3, 4], @filter.sort([4, 3, 2, 1])
+ should "return sorted numbers" do
+ assert_equal [1, 2, 2.2, 3], @filter.sort([3, 2.2, 2, 1])
+ end
+ should "return sorted strings" do
+ assert_equal ["10", "2"], @filter.sort(["10", "2"])
+ assert_equal [{"a" => "10"}, {"a" => "2"}], @filter.sort([{"a" => "10"}, {"a" => "2"}], "a")
+ assert_equal ["FOO", "Foo", "foo"], @filter.sort(["foo", "Foo", "FOO"])
+ assert_equal ["_foo", "foo", "foo_"], @filter.sort(["foo_", "_foo", "foo"])
end
should "return sorted by property array" do
assert_equal [{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}],
@@ -169,12 +175,6 @@ class TestFilters < Test::Unit::TestCase
assert_equal [{"a" => 1}, {"a" => 2}, {"b" => 1}],
@filter.sort([{"a" => 2}, {"b" => 1}, {"a" => 1}], "a", true)
end
- should "return lexicographical sorted array" do
- assert_equal [2, 10], @filter.sort([10, 2])
- assert_equal [{"a" => 2}, {"a" => 10}], @filter.sort([{"a" => 10}, {"a" => 2}], "a")
- assert_equal ["10", "2"], @filter.sort(["10", "2"])
- assert_equal [{"a" => "10"}, {"a" => "2"}], @filter.sort([{"a" => "10"}, {"a" => "2"}], "a")
- end
end
end
From 14e0abc4e2c4a2931199a39c88699a123d40e349 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 21:21:04 +0200
Subject: [PATCH 08/14] Add documentation
---
site/docs/templates.md | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/site/docs/templates.md b/site/docs/templates.md
index a4c79184..460e4d32 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -184,6 +184,18 @@ common tasks easier.
+
+
+ Sort
+ Sort array. Optional arguments: property, nils last.
+ |
+
+
+ {% raw %}{{ page.tags | sort }}{% endraw %}
+ {% raw %}{{ site.pages | sort: 'title', true }}{% endraw %}
+
+ |
+
From 7c1709fab4b0ef1ce9957cbcc6635f538850ae3c Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 21:36:13 +0200
Subject: [PATCH 09/14] Change nils argument to string
---
features/embed_filters.feature | 2 +-
lib/jekyll/filters.rb | 8 ++++----
site/docs/templates.md | 5 +++--
test/test_filters.rb | 4 ++--
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/features/embed_filters.feature b/features/embed_filters.feature
index b1a420f5..889a1fc7 100644
--- a/features/embed_filters.feature
+++ b/features/embed_filters.feature
@@ -101,7 +101,7 @@ Feature: Embed filters
And I have the following page:
| layout | content |
| default | Jump |
- And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title', true %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
+ And I have a default layout that contains "{% assign sorted_pages = site.pages | sort: 'title', 'last' %}The rule of {{ sorted_pages.size }}: {% for p in sorted_pages %}{{ p.content | strip_html | strip_newlines }}, {% endfor %}"
When I run jekyll build
Then the _site directory should exist
And I should see exactly "The rule of 3: Fly, Run, Jump," in "_site/bird.html"
diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb
index ced9623f..fe438834 100644
--- a/lib/jekyll/filters.rb
+++ b/lib/jekyll/filters.rb
@@ -194,18 +194,18 @@ module Jekyll
#
# input - the object array
# key - key within each object to filter by
- # nils_last - nils appear after non-nil values in the sort ordering
+ # nils ('first' | 'last') - nils appear before or after non-nil values
#
# Returns the filtered array of objects
- def sort(input, key = nil, nils_last = false)
+ def sort(input, key = nil, nils = 'first')
if key.nil?
input.sort
else
input.sort { |a, b|
if a[key].nil? and !b[key].nil?
- nils_last ? +1 : -1
+ nils == 'first' ? -1 : +1
elsif !a[key].nil? and b[key].nil?
- nils_last ? -1 : +1
+ nils == 'first' ? +1 : -1
else
a[key] <=> b[key]
end
diff --git a/site/docs/templates.md b/site/docs/templates.md
index 460e4d32..dd8c8107 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -187,12 +187,13 @@ common tasks easier.
Sort
- Sort array. Optional arguments: property, nils last.
+ Sort array. Optional arguments: property name; nils order (*first* or *last*).
|
{% raw %}{{ page.tags | sort }}{% endraw %}
- {% raw %}{{ site.pages | sort: 'title', true }}{% endraw %}
+ {% raw %}{{ site.posts | sort: 'author' }}{% endraw %}
+ {% raw %}{{ site.pages | sort: 'title', 'last' }}{% endraw %}
|
diff --git a/test/test_filters.rb b/test/test_filters.rb
index 66db980e..2f54538a 100644
--- a/test/test_filters.rb
+++ b/test/test_filters.rb
@@ -169,11 +169,11 @@ class TestFilters < Test::Unit::TestCase
should "return sorted by property array with nils first" do
ary = [{"a" => 2}, {"b" => 1}, {"a" => 1}]
assert_equal [{"b" => 1}, {"a" => 1}, {"a" => 2}], @filter.sort(ary, "a")
- assert_equal @filter.sort(ary, "a"), @filter.sort(ary, "a", false)
+ assert_equal @filter.sort(ary, "a"), @filter.sort(ary, "a", "first")
end
should "return sorted by property array with nils last" do
assert_equal [{"a" => 1}, {"a" => 2}, {"b" => 1}],
- @filter.sort([{"a" => 2}, {"b" => 1}, {"a" => 1}], "a", true)
+ @filter.sort([{"a" => 2}, {"b" => 1}, {"a" => 1}], "a", "last")
end
end
From dc0e577b44193a8761c44c14812a65da96011152 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 21:40:52 +0200
Subject: [PATCH 10/14] Fix markup
---
site/docs/templates.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/site/docs/templates.md b/site/docs/templates.md
index dd8c8107..8e025779 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -187,7 +187,7 @@ common tasks easier.
Sort
- Sort array. Optional arguments: property name; nils order (*first* or *last*).
+ Sort array. Optional arguments: property name; nils order ('first' or 'last' ).
|
From 2ee7e735318db0448ab45a7f1f69f8487363785f Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 21:50:33 +0200
Subject: [PATCH 11/14] Improve the description
---
site/docs/templates.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/site/docs/templates.md b/site/docs/templates.md
index 8e025779..03a42eec 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -187,7 +187,7 @@ common tasks easier.
Sort
- Sort array. Optional arguments: property name; nils order ('first' or 'last' ).
+ Sort an array. Optional arguments for hashes: 1. property name (string) 2. nils order (string first or last).
|
From 3a1c18ede202385ce74cff7d8b2d6139fe81cd6a Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 21:54:12 +0200
Subject: [PATCH 12/14] Remove the hint aout type
---
site/docs/templates.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/site/docs/templates.md b/site/docs/templates.md
index 03a42eec..f7b58d84 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -187,7 +187,7 @@ common tasks easier.
Sort
- Sort an array. Optional arguments for hashes: 1. property name (string) 2. nils order (string first or last).
+ Sort an array. Optional arguments for hashes: 1. property name 2. nils order (first or last).
|
From 19b0fe97812b2b31ce26b47fd73a07cc1f3264d4 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 22:00:28 +0200
Subject: [PATCH 13/14] Separate example codes [ci skip]
---
site/docs/templates.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/site/docs/templates.md b/site/docs/templates.md
index f7b58d84..81201339 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -192,7 +192,11 @@ common tasks easier.
{% raw %}{{ page.tags | sort }}{% endraw %}
+
+
{% raw %}{{ site.posts | sort: 'author' }}{% endraw %}
+
+
{% raw %}{{ site.pages | sort: 'title', 'last' }}{% endraw %}
|
From 1e0d9f899b5f81da7e2dbe7c324e34352dba4fd9 Mon Sep 17 00:00:00 2001
From: Anatol Broder
Date: Tue, 6 May 2014 22:49:49 +0200
Subject: [PATCH 14/14] Follow Ruby Styleguide
---
lib/jekyll/filters.rb | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb
index fe438834..10c1aa41 100644
--- a/lib/jekyll/filters.rb
+++ b/lib/jekyll/filters.rb
@@ -197,15 +197,26 @@ module Jekyll
# nils ('first' | 'last') - nils appear before or after non-nil values
#
# Returns the filtered array of objects
- def sort(input, key = nil, nils = 'first')
+ def sort(input, key = nil, nils = "first")
if key.nil?
input.sort
else
+ case
+ when nils == "first"
+ order = - 1
+ when nils == "last"
+ order = + 1
+ else
+ Jekyll.logger.error "Invalid nils order:",
+ "'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
+ exit(1)
+ end
+
input.sort { |a, b|
- if a[key].nil? and !b[key].nil?
- nils == 'first' ? -1 : +1
- elsif !a[key].nil? and b[key].nil?
- nils == 'first' ? +1 : -1
+ if !a[key].nil? && b[key].nil?
+ - order
+ elsif a[key].nil? && !b[key].nil?
+ + order
else
a[key] <=> b[key]
end
| | |