jekyll-timeago 0.5.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,20 +1,20 @@
1
- Jekyll-Timeago
2
- ==============
1
+ # Jekyll-Timeago
3
2
 
4
3
  [![Gem Version](https://badge.fury.io/rb/jekyll-timeago.svg)](http://badge.fury.io/rb/jekyll-timeago)
5
4
 
6
5
  Custom and simple implementation of `timeago` date filter. Main features:
7
6
 
8
- * Localization
7
+ * Distance of dates in words
9
8
  * Future time
9
+ * Usage via Filter or Tag
10
+ * Localization
10
11
  * Level of detail
11
12
 
12
- In fact, `jekyll-timeago` is an extension of [Liquid](https://github.com/Shopify/liquid) filters, so you can use it in all your Liquid templates (Octopress as well).
13
+ In fact, `jekyll-timeago` is an extension of [Liquid](https://github.com/Shopify/liquid) Filters and Tags, so you can use it in other Liquid templates (like Octopress).
13
14
 
14
15
 
15
16
  ## Installation
16
-
17
- You have 3 options for installing the plugin:
17
+ You have 3 options to install the plugin:
18
18
 
19
19
  **Via Jekyll plugin system**
20
20
 
@@ -27,7 +27,7 @@ gem install jekyll-timeago
27
27
  In your `_config.yml` file, add a new array with the key gems and the values of the gem names of the plugins you’d like to use. In this case:
28
28
 
29
29
  ```
30
- gems: [jekyll/timeago]
30
+ gems: [jekyll-timeago]
31
31
  ```
32
32
 
33
33
  **Via Bundler**
@@ -38,18 +38,24 @@ Add this gem to your `Gemfile` and run `bundle`:
38
38
  gem 'jekyll-timeago'
39
39
  ```
40
40
 
41
- To use this filter, just add the following to the top of another plugin (found under `_plugins/`):
41
+ Then load the plugin adding the following into some file under `_plugins/` folder:
42
42
 
43
43
  ```ruby
44
- require 'jekyll/timeago'
44
+ # _plugins/ext.rb
45
+ require 'rubygems'
46
+ require 'bundler/setup'
47
+ Bundler.require(:default)
45
48
  ```
46
49
 
47
50
  **Manually**
48
51
 
49
- Alternatively, you can simply copy [this file](https://github.com/markets/jekyll-timeago/blob/master/lib/jekyll/timeago.rb) directly into your `_plugins/` directory! :)
52
+ Alternatively, you can simply copy [this file](lib/jekyll-timeago/filter.rb) and [this file](lib/jekyll-timeago/tag.rb) directly into your `_plugins/` directory!
50
53
 
51
54
 
52
55
  ## Usage
56
+ By default `timeago` computes distance of dates from passed date to current date (using `Date.today`). But you are able to modify this range passing a second argument in order to compute the distance of these dates in words.
57
+
58
+ **Filter example**:
53
59
 
54
60
  ```html
55
61
  <span>{{ page.date | timeago }}</span>
@@ -60,20 +66,31 @@ Alternatively, you can simply copy [this file](https://github.com/markets/jekyll
60
66
  </div>
61
67
  ```
62
68
 
63
- ### Customization
69
+ Passing a parameter:
70
+
71
+ ```html
72
+ <span>{{ page.date | timeago: '2020-1-1' }}</span>
73
+ ```
74
+
75
+ **Tag example**:
76
+
77
+ ```html
78
+ <p>{% timeago 2000-1-1 %}</p>
79
+ ```
64
80
 
65
- You can personalize the level of detail (from 1 up to 4, 2 by default) passing a parameter:
81
+ Passing a second parameter:
66
82
 
67
83
  ```html
68
- <span>{{ page.date | timeago: 4 }}</span>
84
+ <p>{% timeago 2000-1-1 20010-1-1 %}</p>
69
85
  ```
70
86
 
71
- ## Localization
72
87
 
73
- This plugin allows you to localize the strings needed to build the time ago sentences. For do this, you must add some extra keys to your `_config.yml`. You can simply copy them from [this example file](https://github.com/markets/jekyll-timeago/blob/master/_config.yml.example) and translate it to your site's language. Sample:
88
+ ## Localization
89
+ The plugin allows you to localize the strings needed to build the time ago sentences. For do this, you must add some extra keys to your `_config.yml`. You can simply copy them from [this example file](_config.yml.example) and translate it to your site's language. Sample:
74
90
 
75
91
  ```
76
92
  jekyll_timeago:
93
+ depth: 2 # Level of detail
77
94
  today: 'today'
78
95
  yesterday: 'yesterday'
79
96
  tomorrow: 'tomorrow'
@@ -92,42 +109,39 @@ jekyll_timeago:
92
109
  day: 'day'
93
110
  ```
94
111
 
95
- ## Output Examples
96
112
 
97
- Default behavior:
113
+ ## Level of detail (Depth)
114
+ You are able to change the level of detail (from 1 up to 4, 2 by default) to get higher or lower granularity. This option is setted via the `config` file (see sample in previous section). Examples:
115
+
116
+ * Depht => 1 `1 year ago`
117
+ * Depht => 2 `1 year and 4 months ago` (default)
118
+ * Depht => 3 `1 year, 4 months and 1 week ago`
119
+ * Depht => 4 `1 year, 4 months, 1 week and 4 days ago`
120
+
121
+
122
+ ## Output Examples
123
+ Run `script/console` to start a custom IRB session and play with `timeago` method:
98
124
 
99
125
  ```ruby
100
- > timeago(Date.today)
126
+ >> timeago(Date.today)
101
127
  => "today"
102
- > timeago(Date.today - 1.day)
128
+ >> timeago(Date.today - 1.day)
103
129
  => "yesterday"
104
- > timeago(Date.today - 10.days)
130
+ >> timeago(Date.today - 10.days)
105
131
  => "1 week and 3 days ago"
106
- > timeago(Date.today - 100.days)
132
+ >> timeago(Date.today - 100.days)
107
133
  => "3 months and 1 week ago"
108
- > timeago(Date.today - 500.days)
134
+ >> timeago(Date.today - 500.days)
109
135
  => "1 year and 4 months ago"
110
- > timeago(Date.today + 1.days)
136
+ >> timeago('2010-1-1', '2012-1-1')
137
+ => "2 years ago"
138
+ >> timeago(Date.today + 1.days)
111
139
  => "tomorrow"
112
- > timeago(Date.today + 7.days)
140
+ >> timeago(Date.today + 7.days)
113
141
  => "in 1 week"
114
- > timeago(Date.today + 1000.days)
142
+ >> timeago(Date.today + 1000.days)
115
143
  => "in 2 years and 8 months"
116
144
  ```
117
145
 
118
- Change level of detail to get higher or lower granularity:
119
-
120
- ```ruby
121
- > timeago(Date.today - 500.days) # default
122
- => "1 year and 4 months ago"
123
- > timeago(Date.today - 500.days, 3)
124
- => "1 year, 4 months and 1 week ago"
125
- > timeago(Date.today - 500.days, 4)
126
- => "1 year, 4 months, 1 week and 4 days ago"
127
- > timeago(Date.today - 500.days, 1)
128
- => "1 year ago"
129
- ```
130
-
131
146
  ## License
132
-
133
147
  Copyright (c) 2013-2014 Marc Anguera. Jekyll-Timeago is released under the [MIT](LICENSE) License.
data/_config.yml.example CHANGED
@@ -1,4 +1,5 @@
1
1
  jekyll_timeago:
2
+ depth: 2 # Level of detail
2
3
  today: 'today'
3
4
  yesterday: 'yesterday'
4
5
  tomorrow: 'tomorrow'
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'jekyll/timeago/version'
4
+ require 'jekyll-timeago/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "jekyll-timeago"
@@ -0,0 +1,140 @@
1
+ require 'date'
2
+
3
+ module Jekyll
4
+ module Timeago
5
+ module Filter
6
+
7
+ DAYS_PER = {
8
+ :days => 1,
9
+ :weeks => 7,
10
+ :months => 30,
11
+ :years => 365
12
+ }
13
+
14
+ # Max level of detail
15
+ # years > months > weeks > days
16
+ # 1 year and 7 months and 2 weeks and 6 days
17
+ MAX_DEPTH_LEVEL = 4
18
+
19
+ # Default level of detail
20
+ # 1 month and 5 days, 3 weeks and 2 days, 2 years and 6 months
21
+ DEFAULT_DEPTH_LEVEL = 2
22
+
23
+ def timeago(from, to = Date.today)
24
+ from = validate_date!(from)
25
+ to = validate_date!(to)
26
+ depth = validate_depth!(options[:depth])
27
+
28
+ time_ago_to_now(from, to, depth)
29
+ end
30
+
31
+ private
32
+
33
+ def validate_date!(date)
34
+ Date.parse(date.to_s)
35
+ end
36
+
37
+ def validate_depth!(depth)
38
+ (1..MAX_DEPTH_LEVEL).include?(depth) or raise("Invalid depth level: #{depth.inspect}")
39
+ depth
40
+ end
41
+
42
+ # Get plugin configuration from site. Returns an empty hash if not provided.
43
+ def config
44
+ @config ||= Jekyll.configuration({}).fetch('jekyll_timeago', {}) rescue {}
45
+ end
46
+
47
+ def options
48
+ @options ||= {
49
+ :depth => config['depth'] || DEFAULT_DEPTH_LEVEL,
50
+ :today => config['day'] || 'today',
51
+ :yesterday => config['yesterday'] || 'yesterday',
52
+ :tomorrow => config['tomorrow'] || 'tomorrow',
53
+ :and => config['and'] ||'and',
54
+ :suffix => config['suffix'] || 'ago',
55
+ :prefix => config['prefix'] || '',
56
+ :suffix_future => config['suffix_future'] || '',
57
+ :prefix_future => config['prefix_future'] || 'in',
58
+ :years => config['years'] || 'years',
59
+ :year => config['year'] || 'year',
60
+ :months => config['months'] || 'months',
61
+ :month => config['month'] || 'month',
62
+ :weeks => config['weeks'] || 'weeks',
63
+ :week => config['week'] || 'week',
64
+ :days => config['days'] || 'days',
65
+ :day => config['day'] || 'day'
66
+ }
67
+ end
68
+
69
+ def translate(key)
70
+ options[key.to_sym]
71
+ end
72
+ alias_method :t, :translate
73
+
74
+ # Days passed to time ago sentence
75
+ def time_ago_to_now(from, to, depth)
76
+ days_passed = (to - from).to_i
77
+
78
+ return t(:today) if days_passed == 0
79
+ return t(:yesterday) if days_passed == 1
80
+ return t(:tomorrow) if days_passed == -1
81
+
82
+ future = days_passed < 0
83
+ slots = build_time_ago_slots(days_passed.abs, depth)
84
+ sentence = to_sentence(slots)
85
+
86
+ if future
87
+ "#{t(:prefix_future)} #{sentence} #{t(:suffix_future)}".strip
88
+ else
89
+ "#{t(:prefix)} #{sentence} #{t(:suffix)}".strip
90
+ end
91
+ end
92
+
93
+ # Builds time ranges: ['1 month', '5 days']
94
+ # - days_passed: integer in absolute
95
+ # - depth: level of detail
96
+ # - current_slots: built time slots
97
+ def build_time_ago_slots(days_passed, depth, current_slots = [])
98
+ return current_slots if depth == 0 || days_passed == 0
99
+
100
+ time_range = days_to_time_range(days_passed)
101
+ days = DAYS_PER[time_range]
102
+ num_elems = days_passed / days
103
+ range_type = if num_elems == 1
104
+ t(time_range[0...-1]) # singularize key
105
+ else
106
+ t(time_range)
107
+ end
108
+
109
+ current_slots << "#{num_elems} #{range_type}"
110
+ pending_days = days_passed - (num_elems*days)
111
+ build_time_ago_slots(pending_days, depth - 1, current_slots)
112
+ end
113
+
114
+ # Number of days to minimum period time which can be grouped
115
+ def days_to_time_range(days_passed)
116
+ case days_passed.abs
117
+ when 0...7
118
+ :days
119
+ when 7...31
120
+ :weeks
121
+ when 31...365
122
+ :months
123
+ else
124
+ :years
125
+ end
126
+ end
127
+
128
+ # Array to sentence: ['1 month', '1 week', '5 days'] => "1 month, 1 week and 5 days"
129
+ def to_sentence(slots)
130
+ if slots.length == 1
131
+ slots[0]
132
+ else
133
+ "#{slots[0...-1].join(', ')} #{t(:and)} #{slots[-1]}"
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ Liquid::Template.register_filter(Jekyll::Timeago::Filter) if defined?(Liquid)
@@ -0,0 +1,24 @@
1
+ module Jekyll
2
+ module Timeago
3
+ class Tag < Liquid::Tag
4
+ include Jekyll::Timeago::Filter
5
+
6
+ def initialize(tag_name, dates, tokens)
7
+ super
8
+ @dates = dates.strip.split(' ')
9
+ end
10
+
11
+ def render(context)
12
+ from, to = @dates[0], @dates[1]
13
+
14
+ if to
15
+ timeago(from, to)
16
+ else
17
+ timeago(from)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ Liquid::Template.register_tag('timeago', Jekyll::Timeago::Tag) if defined?(Liquid)
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  module Timeago
3
- VERSION = "0.5.2"
3
+ VERSION = "0.7.0"
4
4
  end
5
5
  end
@@ -0,0 +1,3 @@
1
+ require 'jekyll-timeago/filter'
2
+ require 'jekyll-timeago/tag'
3
+ require 'jekyll-timeago/version'
data/script/console ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'jekyll-timeago/filter'
7
+ include Jekyll::Timeago::Filter
8
+
9
+ require 'active_support/core_ext'
10
+
11
+ require 'irb'
12
+ ARGV.clear
13
+ IRB.start
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-timeago
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-22 00:00:00.000000000 Z
12
+ date: 2014-05-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -58,8 +58,11 @@ files:
58
58
  - Rakefile
59
59
  - _config.yml.example
60
60
  - jekyll-timeago.gemspec
61
- - lib/jekyll/timeago.rb
62
- - lib/jekyll/timeago/version.rb
61
+ - lib/jekyll-timeago.rb
62
+ - lib/jekyll-timeago/filter.rb
63
+ - lib/jekyll-timeago/tag.rb
64
+ - lib/jekyll-timeago/version.rb
65
+ - script/console
63
66
  homepage: https://github.com/markets/jekyll-timeago
64
67
  licenses:
65
68
  - MIT
@@ -1,142 +0,0 @@
1
- begin; require "jekyll/timeago/version"; rescue LoadError; end
2
-
3
- module Jekyll
4
- module Timeago
5
-
6
- DAYS_PER = {
7
- :days => 1,
8
- :weeks => 7,
9
- :months => 30,
10
- :years => 365
11
- }
12
-
13
- # Max level of detail
14
- # years > months > weeks > days
15
- # 1 year and 7 months and 2 weeks and 6 days
16
- MAX_DEPTH_LEVEL = 4
17
-
18
- # Default level of detail
19
- # 1 month and 5 days, 3 weeks and 2 days, 2 years and 6 months
20
- DEFAULT_DEPTH_LEVEL = 2
21
-
22
- def timeago(input, depth = DEFAULT_DEPTH_LEVEL)
23
- validate!(input, depth)
24
-
25
- time_ago_to_now(input, depth)
26
- end
27
-
28
- private
29
-
30
- # Validates inputs
31
- def validate!(input, depth)
32
- unless depth_allowed?(depth)
33
- raise "Invalid depth level: #{depth.inspect}"
34
- end
35
-
36
- unless input.is_a?(Date) || input.is_a?(Time)
37
- raise "Invalid input type: #{input.inspect}"
38
- end
39
- end
40
-
41
- # Get plugin configuration from site. Returns an empty hash if not provided.
42
- def config
43
- @config ||= Jekyll.configuration({}).fetch('jekyll_timeago', {})
44
- end
45
-
46
- def strings
47
- {
48
- :today => config['day'] || 'today',
49
- :yesterday => config['yesterday'] || 'yesterday',
50
- :tomorrow => config['tomorrow'] || 'tomorrow',
51
- :and => config['and'] ||'and',
52
- :suffix => config['suffix'] || 'ago',
53
- :prefix => config['prefix'] || '',
54
- :suffix_future => config['suffix_future'] || '',
55
- :prefix_future => config['prefix_future'] || 'in',
56
- :years => config['years'] || 'years',
57
- :year => config['year'] || 'year',
58
- :months => config['months'] || 'months',
59
- :month => config['month'] || 'month',
60
- :weeks => config['weeks'] || 'weeks',
61
- :week => config['week'] || 'week',
62
- :days => config['days'] || 'days',
63
- :day => config['day'] || 'day'
64
- }
65
- end
66
-
67
- def translate(key)
68
- strings[key.to_sym]
69
- end
70
- alias_method :t, :translate
71
-
72
- # Days passed to time ago sentence
73
- def time_ago_to_now(input_date, depth)
74
- days_passed = (Date.today - Date.parse(input_date.to_s)).to_i
75
-
76
- return t(:today) if days_passed == 0
77
- return t(:yesterday) if days_passed == 1
78
- return t(:tomorrow) if days_passed == -1
79
-
80
- future = days_passed < 0
81
- slots = build_time_ago_slots(days_passed.abs, depth)
82
- sentence = to_sentence(slots)
83
-
84
- if future
85
- "#{t(:prefix_future)} #{sentence} #{t(:suffix_future)}".strip
86
- else
87
- "#{t(:prefix)} #{sentence} #{t(:suffix)}".strip
88
- end
89
- end
90
-
91
- # Builds time ranges: ['1 month', '5 days']
92
- # - days_passed: integer in absolute
93
- # - depth: level of detail
94
- # - current_slots: built time slots
95
- def build_time_ago_slots(days_passed, depth, current_slots = [])
96
- return current_slots if depth == 0 || days_passed == 0
97
-
98
- time_range = days_to_time_range(days_passed)
99
- days = DAYS_PER[time_range]
100
- num_elems = days_passed / days
101
- range_type = if num_elems == 1
102
- t(time_range[0...-1]) # singularize key
103
- else
104
- t(time_range)
105
- end
106
-
107
- current_slots << "#{num_elems} #{range_type}"
108
- pending_days = days_passed - (num_elems*days)
109
- build_time_ago_slots(pending_days, depth - 1, current_slots)
110
- end
111
-
112
- # Number of days to minimum period time which can be grouped
113
- def days_to_time_range(days_passed)
114
- case days_passed.abs
115
- when 0...7
116
- :days
117
- when 7...31
118
- :weeks
119
- when 31...365
120
- :months
121
- else
122
- :years
123
- end
124
- end
125
-
126
- # Validate if allowed level of detail
127
- def depth_allowed?(depth)
128
- (1..MAX_DEPTH_LEVEL).include?(depth)
129
- end
130
-
131
- # Array to sentence: ['1 month', '1 week', '5 days'] => "1 month, 1 week and 5 days"
132
- def to_sentence(slots)
133
- if slots.length == 1
134
- slots[0]
135
- else
136
- "#{slots[0...-1].join(', ')} #{t(:and)} #{slots[-1]}"
137
- end
138
- end
139
- end
140
- end
141
-
142
- Liquid::Template.register_filter(Jekyll::Timeago) if defined?(Liquid)