jekyll_all_collections 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,141 +0,0 @@
1
- require 'jekyll_draft'
2
- require 'jekyll_plugin_logger'
3
- require 'jekyll_plugin_support'
4
- require 'securerandom'
5
-
6
- # See https://stackoverflow.com/a/75389679/553865
7
- class NullBinding < BasicObject
8
- def min_binding
9
- ::Kernel
10
- .instance_method(:binding)
11
- .bind_call(self)
12
- end
13
- end
14
-
15
- # @author Copyright 2020 Michael Slinn
16
- # @license SPDX-License-Identifier: Apache-2.0
17
- module AllCollectionsTag
18
- PLUGIN_NAME = 'all_collections'.freeze
19
- CRITERIA = %w[date destination draft label last_modified last_modified_at path relative_path title type url].freeze
20
- DRAFT_HTML = '<i class="jekyll_draft">Draft</i>'.freeze
21
-
22
- class AllCollectionsTag < JekyllSupport::JekyllTag
23
- include JekyllAllCollectionsVersion
24
-
25
- # Method prescribed by JekyllTag.
26
- # @return [String]
27
- def render_impl
28
- AllCollectionsHooks.compute(@site) unless @site.class.method_defined? :all_collections
29
-
30
- @date_column = @helper.parameter_specified?('date_column') || 'date'
31
- unless %w[date last_modified].include?(@date_column)
32
- # TODO: should this just issue a warning and return instead of dieing?
33
- abort "Error: the date_column attribute must either have value 'date' or 'last_modified', " \
34
- "but '#{@date_column}' was specified"
35
- end
36
- @id = @helper.parameter_specified?('id') || SecureRandom.hex(10)
37
- sort_by_param = @helper.parameter_specified? 'sort_by'
38
- sort_by = (sort_by_param&.delete(' ')&.split(',') if sort_by_param != false) || ['-date']
39
- @heading = @helper.parameter_specified?('heading') || self.class.default_head(sort_by)
40
- sort_lambda_string = self.class.create_lambda_string(sort_by)
41
- @logger.debug do
42
- "#{@page['path']} sort_by_param=#{sort_by_param} " \
43
- "sort_lambda_string = #{sort_lambda_string}\n"
44
- end
45
- sort_lambda = self.class.evaluate sort_lambda_string
46
- generate_output sort_lambda
47
- end
48
-
49
- def self.default_head(sort_by)
50
- criteria = (sort_by.map do |x|
51
- reverse = x.start_with? '-'
52
- criterion = x.delete_prefix('-').capitalize
53
- criterion += reverse ? ' (Newest to Oldest)' : ' (Oldest to Newest)'
54
- criterion
55
- end).join(', ')
56
- "All Posts in All Categories Sorted By #{criteria}"
57
- end
58
-
59
- # Descending sort keys reverse the order of comparison
60
- def self.create_lambda_string(criteria)
61
- criteria_lhs_array = []
62
- criteria_rhs_array = []
63
- verify_sort_by_type(criteria).each do |c|
64
- descending_sort = c.start_with? '-'
65
- c.delete_prefix! '-'
66
- abort("Error: '#{c}' is not a valid sort field. Valid field names are: #{CRITERIA.join ', '}") \
67
- unless CRITERIA.include?(c)
68
- criteria_lhs_array << (descending_sort ? "b.#{c}" : "a.#{c}")
69
- criteria_rhs_array << (descending_sort ? "a.#{c}" : "b.#{c}")
70
- end
71
- # Examples:
72
- # "->(a, b) { [a.last_modified] <=> [b.last_modified] }"
73
- # "->(a, b) { [b.last_modified] <=> [a.last_modified] }" (descending)
74
- # "->(a, b) { [a.last_modified, a.date] <=> [b.last_modified, b.date] }" (descending last_modified, ascending date)
75
- # "->(a, b) { [a.last_modified, b.date] <=> [b.last_modified, a.date] }" (ascending last_modified, descending date)
76
- "->(a, b) { [#{criteria_lhs_array.join(', ')}] <=> [#{criteria_rhs_array.join(', ')}] }"
77
- end
78
-
79
- def self.evaluate(string)
80
- self.eval string, binding, __FILE__, __LINE__
81
- rescue StandardError => e
82
- warn_short_trace e.red
83
- end
84
-
85
- def self.verify_sort_by_type(sort_by)
86
- if @sort_by.is_a? Array
87
- sort_by
88
- elsif sort_by.is_a? Enumerable
89
- sort_by.to_a
90
- elsif sort_by.is_a? Date
91
- [sort_by.to_i]
92
- elsif sort_by.is_a? String
93
- [sort_by]
94
- else
95
- abort "Error: sort_by was specified as '#{sort_by}'; it must either be a string or an array of strings"
96
- end
97
- end
98
-
99
- private
100
-
101
- def last_modified_value(post)
102
- @logger.debug do
103
- " post.last_modified='#{post.last_modified}'; " \
104
- "post.last_modified_at='#{post.last_modified_at}'; " \
105
- "@date_column='#{@date_column}'"
106
- end
107
- last_modified = if @date_column == 'last_modified' && post.respond_to?(:last_modified)
108
- post.last_modified
109
- elsif post.respond_to? :last_modified_at
110
- post.last_modified_at
111
- else
112
- post.date
113
- end
114
- last_modified ||= post.date || Date.today
115
- last_modified
116
- end
117
-
118
- def generate_output(sort_lambda)
119
- id = @id.to_s.strip.empty? ? '' : " id='#{@id}'"
120
- heading = @heading.strip.to_s.empty? ? '' : "<h2#{id}>#{@heading}</h2>"
121
- collection = @site.all_collections.sort(&sort_lambda)
122
- <<~END_TEXT
123
- #{heading}
124
- <div class="posts">
125
- #{(collection.map do |post|
126
- last_modified = last_modified_value post
127
- date = last_modified.strftime '%Y-%m-%d'
128
- draft = post.draft ? DRAFT_HTML : ''
129
- href = "<a href='#{post.url}'>#{post.title}</a>"
130
- @logger.debug { " date='#{date}' #{post.title}\n" }
131
- " <span>#{date}</span><span>#{href}#{draft}</span>"
132
- end).join "\n"}
133
- </div>
134
- END_TEXT
135
- rescue ArgumentError => e
136
- warn_short_trace e
137
- end
138
-
139
- JekyllSupport::JekyllPluginHelper.register(self, PLUGIN_NAME)
140
- end
141
- end