jekyll_all_collections 0.3.6 → 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,139 +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
- eval string, NullBinding.new.min_binding, __FILE__, __LINE__ # rubocop:disable Security/Eval
81
- end
82
-
83
- def self.verify_sort_by_type(sort_by)
84
- if @sort_by.is_a? Array
85
- sort_by
86
- elsif sort_by.is_a? Enumerable
87
- sort_by.to_a
88
- elsif sort_by.is_a? Date
89
- [sort_by.to_i]
90
- elsif sort_by.is_a? String
91
- [sort_by]
92
- else
93
- abort "Error: sort_by was specified as '#{sort_by}'; it must either be a string or an array of strings"
94
- end
95
- end
96
-
97
- private
98
-
99
- def last_modified_value(post)
100
- @logger.debug do
101
- " post.last_modified='#{post.last_modified}'; " \
102
- "post.last_modified_at='#{post.last_modified_at}'; " \
103
- "@date_column='#{@date_column}'"
104
- end
105
- last_modified = if @date_column == 'last_modified' && post.respond_to?(:last_modified)
106
- post.last_modified
107
- elsif post.respond_to? :last_modified_at
108
- post.last_modified_at
109
- else
110
- post.date
111
- end
112
- last_modified ||= post.date || Date.today
113
- last_modified
114
- end
115
-
116
- def generate_output(sort_lambda)
117
- id = @id.to_s.strip.empty? ? '' : " id='#{@id}'"
118
- heading = @heading.strip.to_s.empty? ? '' : "<h2#{id}>#{@heading}</h2>"
119
- collection = @site.all_collections.sort(&sort_lambda)
120
- <<~END_TEXT
121
- #{heading}
122
- <div class="posts">
123
- #{(collection.map do |post|
124
- last_modified = last_modified_value post
125
- date = last_modified.strftime '%Y-%m-%d'
126
- draft = post.draft ? DRAFT_HTML : ''
127
- href = "<a href='#{post.url}'>#{post.title}</a>"
128
- @logger.debug { " date='#{date}' #{post.title}\n" }
129
- " <span>#{date}</span><span>#{href}#{draft}</span>"
130
- end).join "\n"}
131
- </div>
132
- END_TEXT
133
- rescue ArgumentError => e
134
- warn_short_trace e
135
- end
136
-
137
- JekyllSupport::JekyllPluginHelper.register(self, PLUGIN_NAME)
138
- end
139
- end