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.
- checksums.yaml +4 -4
- data/.rubocop.yml +19 -1
- data/CHANGELOG.md +34 -8
- data/README.md +208 -105
- data/jekyll_all_collections.gemspec +11 -14
- data/lib/hooks/a_page.rb +69 -0
- data/lib/hooks/all_collections_hooks.rb +59 -0
- data/lib/hooks/all_files.rb +46 -0
- data/lib/hooks/class_methods.rb +50 -0
- data/lib/jekyll_all_collections/version.rb +1 -1
- data/lib/jekyll_all_collections.rb +14 -2
- data/lib/tag/all_collections_tag.rb +158 -0
- data/lib/util/mslinn_binary_search.rb +152 -0
- data/lib/util/send_chain.rb +58 -0
- data/spec/all_collections_tag/all_collections_tag_sort_spec.rb +1 -0
- data/spec/bsearch_spec.rb +50 -0
- data/spec/date_sort_spec.rb +8 -6
- data/spec/mslinn_binary_search_spec.rb +47 -0
- data/spec/send_chain_spec.rb +72 -0
- data/spec/send_spec.rb +28 -0
- data/spec/sorted_lru_files_spec.rb +82 -0
- data/spec/spec_helper.rb +1 -3
- data/spec/status_persistence.txt +32 -22
- data/spec/testable_spec.rb +38 -0
- metadata +33 -11
- data/lib/all_collections_hooks.rb +0 -118
- data/lib/all_collections_tag.rb +0 -139
data/lib/all_collections_tag.rb
DELETED
@@ -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
|