From 81c25b9502e7354196035908ce48a421a201dbe7 Mon Sep 17 00:00:00 2001
From: Matthias Kretschmann
Date: Sat, 30 Nov 2013 02:37:58 +0100
Subject: [PATCH] relative time
---
_src/_layouts/link.html | 2 +-
_src/_layouts/photo.html | 2 +-
_src/_layouts/post.html | 4 +-
_src/_plugins/timeago.rb | 109 +++++++++++++++++++++++++++++++++++++++
4 files changed, 113 insertions(+), 4 deletions(-)
create mode 100644 _src/_plugins/timeago.rb
diff --git a/_src/_layouts/link.html b/_src/_layouts/link.html
index e2a4a63e..4f827621 100644
--- a/_src/_layouts/link.html
+++ b/_src/_layouts/link.html
@@ -28,7 +28,7 @@ layout: base
by {{ page.author }}
- {{ page.date | date_to_string }}
+ {{ page.date | timeago }}
diff --git a/_src/_layouts/photo.html b/_src/_layouts/photo.html
index 7702e836..631584c3 100644
--- a/_src/_layouts/photo.html
+++ b/_src/_layouts/photo.html
@@ -23,7 +23,7 @@ layout: base
{{ page.categories | category_links }}
by {{ page.author }}
- {{ page.date | date_to_string }}
+ {{ page.date | timeago }}
diff --git a/_src/_layouts/post.html b/_src/_layouts/post.html
index 4ee0912a..9329203e 100644
--- a/_src/_layouts/post.html
+++ b/_src/_layouts/post.html
@@ -23,9 +23,9 @@ layout: base
{{ page.categories | category_links }}
-
{{ page.date | date_to_string }}
+
{{ page.date | timeago }}
{% if page.moddate %}
-
updated: {{ page.moddate | date_to_string }}
+
updated: {{ page.moddate | timeago }}
{% endif %}
diff --git a/_src/_plugins/timeago.rb b/_src/_plugins/timeago.rb
new file mode 100644
index 00000000..17b50dcf
--- /dev/null
+++ b/_src/_plugins/timeago.rb
@@ -0,0 +1,109 @@
+#
+# jekyll-timeago
+#
+# https://github.com/markets/jekyll-timeago
+#
+
+module Jekyll
+ module Timeago
+
+ DAYS_PER = {
+ :days => 1,
+ :weeks => 7,
+ :months => 31,
+ :years => 365,
+ }
+
+ # Max level of detail
+ # years > months > weeks > days
+ # 1 year and 7 months and 2 weeks and 6 days
+ MAX_DEPTH_LEVEL = 4
+
+ # Default level of detail
+ # 1 month and 5 days, 3 weeks and 2 days, 2 years and 6 months
+ DEFAULT_DEPTH_LEVEL = 2
+
+ def timeago(input, depth = DEFAULT_DEPTH_LEVEL)
+ unless depth_allowed?(depth)
+ raise "Invalid depth level: #{depth.inspect}"
+ end
+
+ unless input.is_a?(Date) || input.is_a?(Time)
+ raise "Invalid input type: #{input.inspect}"
+ end
+
+ days_passed = (Date.today - Date.parse(input.to_s)).to_i
+ time_ago_to_now(days_passed, depth)
+ end
+
+ private
+
+ # Days passed to time ago sentence
+ def time_ago_to_now(days_passed, depth)
+ return "today" if days_passed == 0
+ return "yesterday" if days_passed == 1
+ return "tomorrow" if days_passed == -1
+
+ future = days_passed < 0
+ slots = build_time_ago_slots(days_passed.abs, depth)
+ sentence = to_sentence(slots)
+
+ if future
+ "in #{sentence}"
+ else
+ "#{sentence} ago"
+ end
+ end
+
+ # Builds time ranges: ['1 month', '5 days']
+ # - days_passed: integer in absolute
+ # - depth: level of detail
+ # - current_slots: built time slots
+ def build_time_ago_slots(days_passed, depth, current_slots = [])
+ return current_slots if depth == 0 || days_passed == 0
+
+ time_range = days_to_time_range(days_passed)
+ days = DAYS_PER[time_range]
+ num_elems = days_passed / days
+ range_type = if num_elems == 1
+ time_range.to_s[0...-1] # singularize
+ else
+ time_range.to_s
+ end
+
+ current_slots << "#{num_elems} #{range_type}"
+ pending_days = days_passed - (num_elems*days)
+ build_time_ago_slots(pending_days, depth - 1, current_slots)
+ end
+
+ # Number of days to minimum period time which can be grouped
+ def days_to_time_range(days_passed)
+ case days_passed.abs
+ when 0...7
+ :days
+ when 7...31
+ :weeks
+ when 31...365
+ :months
+ else
+ :years
+ end
+ end
+
+ # Validate if allowed level of detail
+ def depth_allowed?(depth)
+ (1..MAX_DEPTH_LEVEL).include?(depth)
+ end
+
+ # Array to sentence: ['1 month', '1 week', '5 days'] => "1 month, 1 week and 5 days"
+ def to_sentence(slots)
+ if slots.length == 1
+ slots[0]
+ else
+ "#{slots[0...-1].join(', ')} and #{slots[-1]}"
+ end
+ end
+ end
+end
+
+Liquid::Template.register_filter(Jekyll::Timeago)
\ No newline at end of file