jekyll_all_collections 0.1.1 → 0.2.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 +27 -10
- data/CHANGELOG.md +5 -0
- data/README.md +225 -24
- data/jekyll_all_collections.gemspec +20 -24
- data/lib/all_collections_hooks.rb +113 -0
- data/lib/all_collections_tag.rb +122 -0
- data/lib/jekyll_all_collections/version.rb +1 -3
- data/lib/jekyll_all_collections.rb +4 -25
- data/spec/date_sort_spec.rb +82 -0
- data/spec/lambda_sort_spec.rb +117 -0
- data/spec/spec_helper.rb +5 -9
- data/spec/status_persistence.txt +23 -5
- metadata +22 -33
- data/spec/jekyll_all_collections_spec.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0028eabf4e3d4acb900fb4f8896aa40511b30c455aac9f8fe8fcd8f01705b8cc'
|
4
|
+
data.tar.gz: cdd9c792fb62ee38e902d211d8860a2dd97dde34ed4268011f24269d752c71dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 667804cdfa3f061556503396219dd6e849da04420d1b778bd47c084828e7ef491dcfcb632198131913207a3f97c39ee123933b63d5922c86866c59dd210a1713
|
7
|
+
data.tar.gz: 6363d5ad42d2f3b61a548ebace5c0e54e15867c48066848d821cbf004d22ef80ec3a95ae0009d1896effed76d35ec441a64bbc6d0ca0b140833043be5e32a7d1
|
data/.rubocop.yml
CHANGED
@@ -1,21 +1,14 @@
|
|
1
|
-
# require: rubocop-jekyll
|
2
|
-
# inherit_gem:
|
3
|
-
# rubocop-jekyll: .rubocop.yml
|
4
|
-
|
5
1
|
AllCops:
|
6
2
|
Exclude:
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
- vendor/**/*
|
4
|
+
- Gemfile*
|
5
|
+
- '*.gemspec'
|
10
6
|
NewCops: enable
|
11
7
|
TargetRubyVersion: 2.6
|
12
8
|
|
13
9
|
# Gemspec/RequireMFA:
|
14
10
|
# Enabled: false
|
15
11
|
|
16
|
-
# Jekyll/NoPutsAllowed:
|
17
|
-
# Enabled: false
|
18
|
-
|
19
12
|
Layout/HashAlignment:
|
20
13
|
EnforcedHashRocketStyle: table
|
21
14
|
|
@@ -23,13 +16,37 @@ Layout/LineLength:
|
|
23
16
|
Max: 150
|
24
17
|
|
25
18
|
Metrics/BlockLength:
|
19
|
+
Exclude:
|
20
|
+
- spec/**/*
|
26
21
|
Max: 50
|
27
22
|
|
23
|
+
Metrics/AbcSize:
|
24
|
+
Max: 42
|
25
|
+
|
26
|
+
Metrics/CyclomaticComplexity:
|
27
|
+
Max: 25
|
28
|
+
|
28
29
|
Metrics/MethodLength:
|
29
30
|
Max: 40
|
30
31
|
|
31
32
|
Metrics/ModuleLength:
|
32
33
|
Enabled: false
|
33
34
|
|
35
|
+
Metrics/PerceivedComplexity:
|
36
|
+
Max: 20
|
37
|
+
|
38
|
+
Style/Documentation:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Style/FrozenStringLiteralComment:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
Style/LineEndConcatenation:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
Style/StringConcatenation:
|
48
|
+
Exclude:
|
49
|
+
- spec/**/*
|
50
|
+
|
34
51
|
Style/StringLiterals:
|
35
52
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.2.0 / 2023-02-04
|
2
|
+
* Returns Array[APage] instead of a collection of different types of objects.
|
3
|
+
* Converted the plugin to a `:site, :post_read` hook instead of a tag,
|
4
|
+
so explicit initialization is no longer required.
|
5
|
+
|
1
6
|
## 0.1.1 / 2022-04-27
|
2
7
|
* Changed invocation from a `:site` hook to an idempotent method invocation.
|
3
8
|
|
data/README.md
CHANGED
@@ -2,31 +2,237 @@
|
|
2
2
|
[](https://badge.fury.io/rb/jekyll_all_collections)
|
3
3
|
===========
|
4
4
|
|
5
|
-
`
|
5
|
+
`Jekyll_all_collections` is a Jekyll plugin that adds a new property called `all_collections` to `site`.
|
6
|
+
It also provides a new Jekyll tag called `all_collections`,
|
7
|
+
which creates a formatted listing of all posts and documents from all collections,
|
8
|
+
sorted by age, newest to oldest.
|
9
|
+
|
10
|
+
The collection consists of an array of objects with the following properties:
|
11
|
+
`content` (HTML or Markdown), `data` (array), `date` (Ruby Date), `description`, `destination`,
|
12
|
+
`draft` (Boolean), `excerpt` (HTML or Markdown), `ext`, `label`, `last_modified` or `last_modified_at` (Ruby Date),
|
13
|
+
`layout`, `path`, `relative_path`, `tags`, `title`, `type`, and `url`.
|
14
|
+
|
15
|
+
Pages that are not in any collection are not included.
|
16
|
+
|
17
|
+
|
18
|
+
## Requirements
|
19
|
+
All the pages in the Jekyll website must have an implicit date (for example, all posts are assigned this property by Jekyll),
|
20
|
+
or an explicit `date` set in front matter, like this:
|
21
|
+
```
|
22
|
+
---
|
23
|
+
date=2022-01-01
|
24
|
+
---
|
25
|
+
```
|
26
|
+
If a front matter variable called `last_modified` or `last_modified_at` exists, its value will be converted to a Ruby `Date`:
|
27
|
+
```
|
28
|
+
---
|
29
|
+
last_modified=2023-01-01
|
30
|
+
---
|
31
|
+
```
|
32
|
+
|
33
|
+
Or:
|
34
|
+
```
|
35
|
+
---
|
36
|
+
last_modified_at=2023-01-01
|
37
|
+
---
|
38
|
+
```
|
39
|
+
|
40
|
+
Otherwise, if `last_modified` or `last_modified_at` is not present in the front matter for a page, the `date` value will be used last modified date value.
|
41
|
+
|
42
|
+
## Usage
|
43
|
+
|
44
|
+
### `Site.all_collections`
|
45
|
+
No explicit initialization or setup is required.
|
46
|
+
Jekyll plugins can access the value of `site.all_collections`, however Liquid code in Jekyll pages and documents cannot.
|
47
|
+
|
48
|
+
|
49
|
+
### `All_collections` Tag
|
50
|
+
Add the following CSS to your stylesheet:
|
51
|
+
```css
|
52
|
+
.posts {
|
53
|
+
display: flex;
|
54
|
+
flex-wrap: wrap;
|
55
|
+
justify-content: space-between;
|
56
|
+
line-height: 170%;
|
57
|
+
}
|
58
|
+
|
59
|
+
.posts > *:nth-child(odd) {
|
60
|
+
width: 120px;
|
61
|
+
font-family: Monaco,"Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
|
62
|
+
font-stretch: semi-condensed;
|
63
|
+
font-size: 10pt;
|
64
|
+
}
|
65
|
+
|
66
|
+
.posts > *:nth-child(even) {
|
67
|
+
width: calc(100% - 120px);
|
68
|
+
}
|
69
|
+
```
|
6
70
|
|
71
|
+
#### Excluding Pages
|
72
|
+
Adding the following entry to a page's front matter `` causes that page to be excluded from the collection created by this plugin:
|
73
|
+
```
|
74
|
+
---
|
75
|
+
exclude_from_all: true
|
76
|
+
---
|
77
|
+
```
|
7
78
|
|
79
|
+
#### General Form
|
80
|
+
The general form of the Jekyll tag is:
|
81
|
+
```
|
82
|
+
{% all_collections date_column='date|last_modified' id='asdf' heading='All Posts' sort_by='SORT_KEYS' %}
|
83
|
+
```
|
8
84
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
85
|
+
#### `date_column` Attribute
|
86
|
+
One of two date columns can be displayed in the generated HTML:
|
87
|
+
either `date` (when the article was originally written),
|
88
|
+
or `last_modified`.
|
89
|
+
The default value for the `date_column` attribute is `date`.
|
90
|
+
|
91
|
+
|
92
|
+
#### `id` Attribute
|
93
|
+
If your Jekyll layout employs [`jekyll-toc`](https://github.com/allejo/jekyll-toc), then `id` attributes are important.
|
94
|
+
The `jekyll-toc` include checks for `id` attributes in `h2` ... `h6` tags, and if found, and if the attribute value is enclosed in double quotes (`id="my_id"`, not `id='my_id'`),
|
95
|
+
then the heading is included in the table of contents.
|
96
|
+
|
97
|
+
To suppress an `id` from being generated,
|
98
|
+
and thereby preventing the heading from appearing in the automatically generated table of contents from `jekyll-toc`,
|
99
|
+
specify an empty string for the value of `id`, like this:
|
100
|
+
```
|
101
|
+
{% all_collections id='' %}
|
102
|
+
```
|
103
|
+
|
104
|
+
|
105
|
+
#### `heading` Attribute
|
106
|
+
If no `heading` attribute is specified, a heading will automatically be generated, which contains the `sort_by` values, for example:
|
107
|
+
```
|
108
|
+
{% all_collections id='abcdef' sort_by="last_modified" %}
|
109
|
+
```
|
110
|
+
Generates a heading like:
|
111
|
+
```
|
112
|
+
<h2 id="abcdef">All Posts Sorted By -last_modified</h2>
|
113
|
+
```
|
114
|
+
|
115
|
+
To suppress both a `h2` heading (and the enclosed `id`) from being generated,
|
116
|
+
specify an empty string for the value of `heading`:
|
117
|
+
```
|
118
|
+
{% all_collections heading='' %}
|
119
|
+
```
|
120
|
+
|
121
|
+
|
122
|
+
#### `SORT_KEYS` Values
|
123
|
+
`SORT_KEYS` specifies how to sort the collection.
|
124
|
+
Values can include one or more of the following attributes:
|
125
|
+
`date`, `destination`, `draft`, `label`, `last_modified`, `path`, `relative_path`, `title`, `type`, and `url`.
|
126
|
+
Ascending sorts are the default, however a descending sort can be achieved by prepending `-` before an attribute.
|
127
|
+
|
128
|
+
To specify more than one sort key, provide an array of values.
|
129
|
+
|
130
|
+
|
131
|
+
#### Usage Examples
|
132
|
+
Here is a short Jekyll page, including front matter,
|
133
|
+
demonstrating this plugin being invoked with all default attribute values:
|
134
|
+
```
|
135
|
+
---
|
136
|
+
description: "
|
137
|
+
Dump of all collections, sorted by date originally written, newest to oldest.
|
138
|
+
The heading text will be <code>All Posts Sorted By -date</code>
|
139
|
+
"
|
140
|
+
layout: default
|
141
|
+
title: Testing, 1, 2, 3
|
142
|
+
---
|
143
|
+
{% all_collections %}
|
18
144
|
```
|
19
|
-
|
20
|
-
|
145
|
+
|
146
|
+
Explicitly express the default sort
|
147
|
+
(sort by the date originally written, newest to oldest):
|
148
|
+
```
|
149
|
+
{% all_collections sort_by="-date" %}
|
150
|
+
```
|
151
|
+
|
152
|
+
Sort by date, from oldest to newest:
|
153
|
+
```
|
154
|
+
{% all_collections sort_by="date" %}
|
155
|
+
```
|
156
|
+
|
157
|
+
Sort by the date last modified, oldest to newest:
|
158
|
+
```
|
159
|
+
{% all_collections sort_by="last_modified" %}
|
160
|
+
```
|
161
|
+
|
162
|
+
Sort by the date last modified, newest to oldest:
|
163
|
+
```
|
164
|
+
{% all_collections sort_by="-last_modified" %}
|
165
|
+
```
|
166
|
+
|
167
|
+
Several attributes can be specified as sort criteria by passing them as a comma-delimited string.
|
168
|
+
Included spaces are ignored:
|
169
|
+
```
|
170
|
+
{% all_collections sort_by="-last_modified, -date" %}
|
171
|
+
{% all_collections sort_by="-last_modified, title" %}
|
172
|
+
{% all_collections sort_by="-last_modified, -date, title" %}
|
173
|
+
```
|
174
|
+
|
175
|
+
The following two examples produce the same output:
|
176
|
+
```
|
177
|
+
{% all_collections sort_by="-last_modified,-date" %}
|
178
|
+
{% all_collections sort_by="-last_modified, -date" %}
|
179
|
+
```
|
180
|
+
|
181
|
+
|
182
|
+
## Demo
|
183
|
+
The [`demo`](./demo) directory contains a demonstration website, which uses the plugin.
|
184
|
+
To run, type:
|
185
|
+
```console
|
186
|
+
$ demo/_bin/debug -r
|
187
|
+
```
|
188
|
+
Now point your web browser to http://localhost:4444
|
189
|
+
|
190
|
+
|
191
|
+
## Debugging
|
192
|
+
1. You have two options for initiating a debug session:
|
193
|
+
|
194
|
+
1. Run `demo/_bin/debug`, without the `-r` options shown above.
|
195
|
+
```
|
196
|
+
... lots of output as bundle update runs...
|
197
|
+
Bundle updated!
|
198
|
+
|
199
|
+
INFO PluginMetaLogger: Loaded AllCollectionsHooks v0.2.0 :site, :pre_render, :normal hook plugin.
|
200
|
+
INFO PluginMetaLogger: Loaded DraftFilter plugin.
|
201
|
+
INFO PluginMetaLogger: Loaded all_collections v0.2.0 tag plugin.
|
202
|
+
Configuration file: /mnt/_/work/jekyll/my_plugins/jekyll_all_collections/demo/_config.yml
|
203
|
+
Cleaner: Removing /mnt/_/work/jekyll/my_plugins/jekyll_all_collections/demo/_site...
|
204
|
+
Cleaner: Removing /mnt/_/work/jekyll/my_plugins/jekyll_all_collections/demo/.jekyll-metadata...
|
205
|
+
Cleaner: Removing /mnt/_/work/jekyll/my_plugins/jekyll_all_collections/demo/.jekyll-cache...
|
206
|
+
Cleaner: Nothing to do for .sass-cache.
|
207
|
+
Fast Debugger (ruby-debug-ide 0.7.3, debase 0.2.5.beta2, file filtering is supported) listens on 0.0.0.0:1234
|
208
|
+
```
|
209
|
+
|
210
|
+
2. Run `bin/attach` and pass the directory name of a Jekyll website that has a suitable script called `_bin/debug`.
|
211
|
+
The `demo` subdirectory fits this description.
|
212
|
+
```console
|
213
|
+
$ bin/attach demo
|
214
|
+
Successfully uninstalled jekyll_all_collections-0.1.2
|
215
|
+
jekyll_all_collections 0.1.2 built to pkg/jekyll_all_collections-0.1.2.gem.
|
216
|
+
jekyll_all_collections (0.1.2) installed.
|
217
|
+
Fast Debugger (ruby-debug-ide 0.7.3, debase 0.2.4.1, file filtering is supported) listens on 0.0.0.0:1234
|
218
|
+
```
|
219
|
+
|
220
|
+
2. Set breakpoints in Ruby code.
|
221
|
+
|
222
|
+
3. Attach to the debugger process.
|
223
|
+
This git repo includes a [Visual Studio Code launcher](./.vscode/launch.json) for this purpose labeled `Listen for rdebug-ide`.
|
224
|
+
|
225
|
+
4. Point your web browser to http://localhost:4444
|
21
226
|
|
22
227
|
|
23
228
|
## Additional Information
|
24
|
-
More information is available on Mike Slinn's
|
229
|
+
More information is available on Mike Slinn's website about
|
25
230
|
[Jekyll plugins](https://www.mslinn.com/blog/index.html#Jekyll).
|
26
231
|
|
27
232
|
|
28
233
|
## Installation
|
29
|
-
This has already been done for the demo;
|
234
|
+
This has already been done for the demo;
|
235
|
+
these instructions are for incorporating the plugin(s) into other Jekyll websites.
|
30
236
|
Add this line to your application's Gemfile:
|
31
237
|
|
32
238
|
```ruby
|
@@ -39,10 +245,6 @@ And then execute:
|
|
39
245
|
|
40
246
|
$ bundle install
|
41
247
|
|
42
|
-
Or install it yourself as:
|
43
|
-
|
44
|
-
$ gem install jekyll_all_collections
|
45
|
-
|
46
248
|
|
47
249
|
## Development
|
48
250
|
|
@@ -54,7 +256,7 @@ You can also run `bin/console` for an interactive prompt that will allow you to
|
|
54
256
|
### Build and Install Locally
|
55
257
|
To build and install this gem onto your local machine, run:
|
56
258
|
```shell
|
57
|
-
$ rake install
|
259
|
+
$ rake install
|
58
260
|
```
|
59
261
|
|
60
262
|
The following also does the same thing:
|
@@ -71,13 +273,12 @@ $ gem info jekyll_all_collections
|
|
71
273
|
*** LOCAL GEMS ***
|
72
274
|
|
73
275
|
jekyll_all_collections (0.1.0)
|
74
|
-
Author:
|
75
|
-
Homepage:
|
76
|
-
https://github.com/username/jekyll_all_collections
|
276
|
+
Author: Mike Slinn
|
277
|
+
Homepage: https://www.mslinn.com/blog/2020/12/30/jekyll-plugin-template-collection.html
|
77
278
|
License: MIT
|
78
|
-
Installed at: /home/mslinn/.gems
|
279
|
+
Installed at: /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0
|
79
280
|
|
80
|
-
|
281
|
+
Provides a collection of all collections in site.all_collections.
|
81
282
|
```
|
82
283
|
|
83
284
|
|
@@ -1,39 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative "lib/jekyll_all_collections/version"
|
1
|
+
require_relative 'lib/jekyll_all_collections/version'
|
4
2
|
|
5
3
|
Gem::Specification.new do |spec|
|
6
|
-
github =
|
4
|
+
github = 'https://github.com/mslinn/jekyll_all_collections'
|
7
5
|
|
8
|
-
spec.authors = [
|
9
|
-
spec.bindir =
|
6
|
+
spec.authors = ['Mike Slinn']
|
7
|
+
spec.bindir = 'bin'
|
10
8
|
spec.description = <<~END_OF_DESC
|
11
9
|
Provides a collection of all collections in site.all_collections.
|
12
10
|
END_OF_DESC
|
13
|
-
spec.email = [
|
11
|
+
spec.email = ['email@email.com']
|
14
12
|
spec.executables = []
|
15
13
|
|
16
14
|
# Specify which files should be added to the gem when it is released.
|
17
|
-
spec.files = Dir[
|
15
|
+
spec.files = Dir['.rubocop.yml', 'LICENSE.*', 'Rakefile', "{lib,spec}/**/*", "*.gemspec", "*.md"]
|
18
16
|
|
19
|
-
spec.homepage =
|
20
|
-
spec.license =
|
17
|
+
spec.homepage = 'https://www.mslinn.com/blog/2020/12/30/jekyll-plugin-template-collection.html'
|
18
|
+
spec.license = 'MIT'
|
21
19
|
spec.metadata = {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
'allowed_push_host' => 'https://rubygems.org',
|
21
|
+
'bug_tracker_uri' => "#{github}/issues",
|
22
|
+
'changelog_uri' => "#{github}/CHANGELOG.md",
|
23
|
+
'homepage_uri' => spec.homepage,
|
24
|
+
'source_code_uri' => github,
|
27
25
|
}
|
28
|
-
spec.name =
|
29
|
-
spec.require_paths = [
|
30
|
-
spec.required_ruby_version =
|
31
|
-
spec.summary =
|
26
|
+
spec.name = 'jekyll_all_collections'
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
spec.required_ruby_version = '>= 2.6.0'
|
29
|
+
spec.summary = 'Provides a collection of all collections in site.all_collections.'
|
32
30
|
spec.version = JekyllAllCollectionsVersion::VERSION
|
33
31
|
|
34
|
-
spec.add_dependency
|
35
|
-
spec.add_dependency
|
36
|
-
|
37
|
-
spec.add_development_dependency "debase"
|
38
|
-
spec.add_development_dependency "ruby-debug-ide"
|
32
|
+
spec.add_dependency 'jekyll', '>= 3.5.0'
|
33
|
+
spec.add_dependency 'jekyll_draft', '~>1.1.0'
|
34
|
+
spec.add_dependency 'jekyll_plugin_support', '~> 0.3.1'
|
39
35
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'jekyll'
|
2
|
+
require 'jekyll_plugin_logger'
|
3
|
+
require_relative 'jekyll_all_collections/version'
|
4
|
+
|
5
|
+
# Creates an array of `APage` called site.all_collections, which will be available from :site, :pre_render onwards
|
6
|
+
module AllCollectionsHooks
|
7
|
+
@logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
8
|
+
|
9
|
+
# No, all_collections is not defined for this hook
|
10
|
+
# Jekyll::Hooks.register(:site, :after_init, priority: :normal) do |site|
|
11
|
+
# defined = AllCollectionsHooks.all_collections_defined?(site)
|
12
|
+
# @logger.debug { "Jekyll::Hooks.register(:site, :after_init: #{defined}" }
|
13
|
+
# end
|
14
|
+
|
15
|
+
# Creates a `Array[String]` property called site.all_collections if it does not already exist
|
16
|
+
# Each `APage` entry is one document or page.
|
17
|
+
Jekyll::Hooks.register(:site, :post_read, priority: :normal) do |site|
|
18
|
+
defined = AllCollectionsHooks.all_collections_defined?(site)
|
19
|
+
@logger.info { "Jekyll::Hooks.register(:site, :post_read, :normal: #{defined}" }
|
20
|
+
AllCollectionsHooks.compute(site) unless site.class.method_defined? :all_collections
|
21
|
+
end
|
22
|
+
|
23
|
+
# Yes, all_collections is defined for this hook
|
24
|
+
# Jekyll::Hooks.register(:site, :post_read, priority: :low) do |site|
|
25
|
+
# defined = AllCollectionsHooks.all_collections_defined?(site)
|
26
|
+
# @logger.debug { "Jekyll::Hooks.register(:site, :post_read, :low: #{defined}" }
|
27
|
+
# end
|
28
|
+
|
29
|
+
# Yes, all_collections is defined for this hook
|
30
|
+
# Jekyll::Hooks.register(:site, :post_read, priority: :normal) do |site|
|
31
|
+
# defined = AllCollectionsHooks.all_collections_defined?(site)
|
32
|
+
# @logger.debug { "Jekyll::Hooks.register(:site, :post_read, :normal: #{defined}" }
|
33
|
+
# end
|
34
|
+
|
35
|
+
# Yes, all_collections is defined for this hook
|
36
|
+
# Jekyll::Hooks.register(:site, :pre_render, priority: :normal) do |site, _payload|
|
37
|
+
# defined = AllCollectionsHooks.all_collections_defined?(site)
|
38
|
+
# @logger.debug { "Jekyll::Hooks.register(:site, :pre_render: #{defined}" }
|
39
|
+
# end
|
40
|
+
|
41
|
+
def self.compute(site)
|
42
|
+
objects = site.collections
|
43
|
+
.values
|
44
|
+
.map { |x| x.class.method_defined?(:docs) ? x.docs : x }
|
45
|
+
.flatten
|
46
|
+
|
47
|
+
site.class.module_eval { attr_accessor :all_collections }
|
48
|
+
apages = AllCollectionsHooks.apages_from_objects(objects)
|
49
|
+
site.all_collections = apages
|
50
|
+
end
|
51
|
+
|
52
|
+
@sort_by = ->(apages, criteria) { [apages.sort(criteria)] }
|
53
|
+
|
54
|
+
# The collection value is just the collection label, not the entire collection object
|
55
|
+
def self.apages_from_objects(objects)
|
56
|
+
pages = []
|
57
|
+
objects.each do |object|
|
58
|
+
page = APage.new(object)
|
59
|
+
pages << page unless page.data['exclude_from_all']
|
60
|
+
end
|
61
|
+
pages
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.all_collections_defined?(site)
|
65
|
+
"site.all_collections #{site.class.method_defined?(:all_collections) ? 'IS' : 'IS NOT'} defined"
|
66
|
+
end
|
67
|
+
|
68
|
+
class APage
|
69
|
+
attr_reader :content, :data, :date, :description, :destination, :draft, :excerpt, :ext, \
|
70
|
+
:label, :last_modified, :layout, :path, :relative_path, :tags, :title, :type, :url
|
71
|
+
|
72
|
+
# Verify each property exists before accessing it; this helps write tests
|
73
|
+
def initialize(obj) # rubocop:disable Metrics/AbcSize
|
74
|
+
@data = obj.data if obj.respond_to? :data
|
75
|
+
|
76
|
+
@categories = @data['categories'] if obj.respond_to? :categories
|
77
|
+
@content = obj.content if obj.respond_to? :content
|
78
|
+
@date = @data['date'].to_date if obj.respond_to? :date
|
79
|
+
@description = @data['description'] if obj.respond_to? :data
|
80
|
+
@destination = obj.destination('') if obj.respond_to? :destination # TODO: What _config.yml setting should be passed to destination()?
|
81
|
+
@draft = Jekyll::Draft.draft?(obj)
|
82
|
+
@excerpt = @data['excerpt'] if obj.respond_to? :excerpt
|
83
|
+
@ext = @data['ext'] if obj.respond_to? :data
|
84
|
+
@label = obj.collection.label if obj.respond_to? :label
|
85
|
+
@last_modified = @data['last_modified'] || @data['last_modified_at'] || @date
|
86
|
+
@last_modified_field = case @data
|
87
|
+
when @data.key?('last_modified')
|
88
|
+
'last_modified'
|
89
|
+
when @data.key?('last_modified_at')
|
90
|
+
'last_modified_at'
|
91
|
+
end
|
92
|
+
@layout = @data['layout'] if obj.respond_to? :layout
|
93
|
+
@path = obj.path if obj.respond_to? :path
|
94
|
+
@relative_path = obj.relative_path if obj.respond_to? :relative_path
|
95
|
+
@tags = @data['tags'] if obj.respond_to? :tags
|
96
|
+
@title = @data['title'] if obj.respond_to? :title
|
97
|
+
@type = obj.type if obj.respond_to? :type
|
98
|
+
@url = obj.url
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
return @label if @label
|
103
|
+
|
104
|
+
@date.to_s
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
PluginMetaLogger.instance.logger.info {
|
109
|
+
"Loaded AllCollectionsHooks v#{JekyllAllCollectionsVersion::VERSION} :site, :pre_render, :normal hook plugin."
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
Liquid::Template.register_filter(AllCollectionsHooks)
|
@@ -0,0 +1,122 @@
|
|
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(self)
|
12
|
+
.call
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# @author Copyright 2020 Michael Slinn
|
17
|
+
# @license SPDX-License-Identifier: Apache-2.0
|
18
|
+
module AllCollectionsTag
|
19
|
+
PLUGIN_NAME = 'all_collections'.freeze
|
20
|
+
CRITERIA = %w[date destination draft label last_modified last_modified_at path relative_path title type url].freeze
|
21
|
+
|
22
|
+
class AllCollectionsTag < JekyllSupport::JekyllTag
|
23
|
+
# Method prescribed by JekyllTag.
|
24
|
+
# @return [String]
|
25
|
+
def render_impl
|
26
|
+
AllCollectionsHooks.compute(@site) unless @site.class.method_defined? :all_collections
|
27
|
+
|
28
|
+
@date_column = @helper.parameter_specified?('date_column') || 'date'
|
29
|
+
abort "Error: the date_column attribute must either have value 'date' or 'last_modified', but '#{@date_column}' was specified" \
|
30
|
+
unless %w[date last_modified].include?(@date_column)
|
31
|
+
|
32
|
+
@id = @helper.parameter_specified?('id') || SecureRandom.hex(10)
|
33
|
+
sort_by_param = @helper.parameter_specified?('sort_by')
|
34
|
+
sort_by = (sort_by_param&.gsub(' ', '')&.split(',') if sort_by_param != false) || ['-date']
|
35
|
+
@heading = @helper.parameter_specified?('heading') || self.class.default_head(sort_by)
|
36
|
+
sort_lambda_string = self.class.create_lambda_string(sort_by)
|
37
|
+
@logger.info "#{@page['path']} sort_by_param=#{sort_by_param}"
|
38
|
+
@logger.info " sort_lambda_string = #{sort_lambda_string}\n"
|
39
|
+
sort_lambda = self.class.evaluate(sort_lambda_string)
|
40
|
+
generate_output(sort_lambda)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.default_head(sort_by)
|
44
|
+
criteria = (sort_by.map do |x|
|
45
|
+
reverse = x.start_with? '-'
|
46
|
+
criterion = x.delete_prefix('-').capitalize
|
47
|
+
criterion += reverse ? ' (Newest to Oldest)' : ' (Oldest to Newest)'
|
48
|
+
criterion
|
49
|
+
end).join(', ')
|
50
|
+
"All Posts in All Categories Sorted By #{criteria}"
|
51
|
+
end
|
52
|
+
|
53
|
+
# Descending sort keys reverse the order of comparison
|
54
|
+
def self.create_lambda_string(criteria)
|
55
|
+
criteria_lhs_array = []
|
56
|
+
criteria_rhs_array = []
|
57
|
+
verify_sort_by_type(criteria).each do |c|
|
58
|
+
descending_sort = c.start_with?('-')
|
59
|
+
c.delete_prefix! '-'
|
60
|
+
abort("Error: '#{c}' is not a valid sort field. Valid field names are: #{CRITERIA.join(', ')}") \
|
61
|
+
unless CRITERIA.include?(c)
|
62
|
+
criteria_lhs_array << (descending_sort ? "b.#{c}" : "a.#{c}")
|
63
|
+
criteria_rhs_array << (descending_sort ? "a.#{c}" : "b.#{c}")
|
64
|
+
end
|
65
|
+
# Examples:
|
66
|
+
# "->(a, b) { [a.last_modified] <=> [b.last_modified] }"
|
67
|
+
# "->(a, b) { [b.last_modified] <=> [a.last_modified] }" (descending)
|
68
|
+
# "->(a, b) { [a.last_modified, a.date] <=> [b.last_modified, b.date] }" (descending last_modified, ascending date)
|
69
|
+
# "->(a, b) { [a.last_modified, b.date] <=> [b.last_modified, a.date] }" (ascending last_modified, descending date)
|
70
|
+
"->(a, b) { [#{criteria_lhs_array.join(', ')}] <=> [#{criteria_rhs_array.join(', ')}] }"
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.evaluate(string)
|
74
|
+
eval string, NullBinding.new.min_binding, __FILE__, __LINE__ # rubocop:disable Security/Eval
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.verify_sort_by_type(sort_by)
|
78
|
+
if @sort_by.is_a? Array
|
79
|
+
sort_by
|
80
|
+
elsif sort_by.is_a? Enumerable
|
81
|
+
sort_by.to_a
|
82
|
+
elsif sort_by.is_a? Date
|
83
|
+
[sort_by.to_i]
|
84
|
+
elsif sort_by.is_a? String
|
85
|
+
[sort_by]
|
86
|
+
else
|
87
|
+
abort "Error: sort_by was specified as '#{sort_by}'; it must either be a string or an array of strings"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def generate_output(sort_lambda)
|
94
|
+
id = @id.to_s.empty? ? '' : " id='#{@id}'"
|
95
|
+
heading = @heading.to_s.empty? ? '' : "<h2#{id}>#{@heading}</h2>"
|
96
|
+
@site.all_collections.each do |post|
|
97
|
+
# @logger.info "#{post.relative_path}: last_modified=#{post.last_modified}(#{post.last_modified.class}) date=#{post.date}(#{post.date.class})"
|
98
|
+
@logger.info "Error: #{post.relative_path} has no value for last_modified" if post.last_modified.to_s.empty?
|
99
|
+
end
|
100
|
+
collection = @site.all_collections.sort(&sort_lambda)
|
101
|
+
<<~END_TEXT
|
102
|
+
#{heading}
|
103
|
+
<div class="posts">
|
104
|
+
#{(collection.map do |post|
|
105
|
+
@logger.info { " post.last_modified='#{post.last_modified}' @date_column='#{@date_column}'" }
|
106
|
+
date = (@date_column == 'last_modified' ? post.last_modified : post.date).strftime('%Y-%m-%d')
|
107
|
+
draft = post.draft ? "<i class='jekyll_draft'>Draft</i>" : ''
|
108
|
+
href = "<a href='#{post.url}'>#{post.title}</a>"
|
109
|
+
@logger.info { " date='#{date}' #{post.title}\n" }
|
110
|
+
" <span>#{date}</span><span>#{href}#{draft}</span>"
|
111
|
+
end).join("\n")}
|
112
|
+
</div>
|
113
|
+
END_TEXT
|
114
|
+
rescue ArgumentError => e
|
115
|
+
puts e.message
|
116
|
+
puts e.backtrace.join("\n")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
Liquid::Template.register_tag(AllCollectionsTag::PLUGIN_NAME, AllCollectionsTag::AllCollectionsTag)
|
122
|
+
PluginMetaLogger.instance.info { "Loaded #{AllCollectionsTag::PLUGIN_NAME} v#{JekyllAllCollectionsVersion::VERSION} tag plugin." }
|
@@ -1,28 +1,7 @@
|
|
1
|
-
|
1
|
+
require_relative './all_collections_hooks'
|
2
|
+
require_relative './all_collections_tag'
|
2
3
|
|
3
|
-
require "jekyll"
|
4
|
-
require "jekyll_plugin_logger"
|
5
|
-
require_relative "jekyll_all_collections/version"
|
6
|
-
|
7
|
-
# Creates a property called site.all_collections if it does not already exist
|
8
4
|
module JekyllAllCollections
|
9
|
-
|
10
|
-
|
11
|
-
def maybe_compute_all_collections(site)
|
12
|
-
@logger.debug { "JekyllAllCollections.maybe_compute_all_collections invoked" }
|
13
|
-
return if site.class.method_defined? :all_collections
|
14
|
-
|
15
|
-
@logger.debug { "JekyllAllCollections.maybe_compute_all_collections creating site.all_collections" }
|
16
|
-
|
17
|
-
site.class.module_eval { attr_accessor :all_collections }
|
18
|
-
site.all_collections =
|
19
|
-
site.collections
|
20
|
-
.values
|
21
|
-
.map { |x| x.class.method_defined?(:docs) ? x.docs : x }
|
22
|
-
.flatten
|
23
|
-
end
|
24
|
-
|
25
|
-
module_function :maybe_compute_all_collections
|
26
|
-
|
27
|
-
PluginMetaLogger.instance.logger.info { "Loaded JekyllAllCollections v#{JekyllAllCollectionsVersion::VERSION} plugin." }
|
5
|
+
include AllCollectionsHooks
|
6
|
+
include AllCollectionsTag
|
28
7
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# See https://stackoverflow.com/a/75377832/553865
|
4
|
+
class Obj
|
5
|
+
# `last_modified` is primary sort key
|
6
|
+
# `date` (when specified) is secondary sort key
|
7
|
+
attr_reader :date, :last_modified
|
8
|
+
|
9
|
+
def initialize(param1, param2)
|
10
|
+
@last_modified = Date.parse(param1)
|
11
|
+
@date = Date.parse(param2)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
RSpec.describe(Obj) do # rubocop:disable Metrics/BlockLength
|
16
|
+
let(:o1) { Obj.new('2000-01-01', '2001-01-01') }
|
17
|
+
let(:o2) { Obj.new('2010-01-01', '2001-01-01') }
|
18
|
+
let(:o3) { Obj.new('2010-01-01', '2011-01-01') }
|
19
|
+
let(:o4) { Obj.new('2020-01-01', '2011-01-01') }
|
20
|
+
let(:objs) { [o1, o2, o3, o4] }
|
21
|
+
|
22
|
+
# See https://ruby-doc.org/3.2.0/Comparable.html
|
23
|
+
it "compares one key with ascending dates" do
|
24
|
+
expect([o1.last_modified] <=> [o2.last_modified]).to eq(-1)
|
25
|
+
expect([o2.last_modified] <=> [o3.last_modified]).to eq(0)
|
26
|
+
expect([o3.last_modified] <=> [o4.last_modified]).to eq(-1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "compares two keys with ascending dates" do
|
30
|
+
expect([o1.last_modified, o1.date] <=> [o2.last_modified, o2.date]).to eq(-1)
|
31
|
+
expect([o2.last_modified, o2.date] <=> [o3.last_modified, o3.date]).to eq(-1)
|
32
|
+
expect([o3.last_modified, o3.date] <=> [o4.last_modified, o4.date]).to eq(-1)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "compares one key with descending dates" do
|
36
|
+
expect([o1.last_modified] <=> [o2.last_modified]).to eq(-1)
|
37
|
+
expect([o2.last_modified] <=> [o3.last_modified]).to eq(0)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "compares two keys with descending dates" do
|
41
|
+
expect([o2.last_modified, o2.date] <=> [o1.last_modified, o1.date]).to eq(1)
|
42
|
+
expect([o3.last_modified, o3.date] <=> [o2.last_modified, o2.date]).to eq(1)
|
43
|
+
expect([o4.last_modified, o4.date] <=> [o3.last_modified, o3.date]).to eq(1)
|
44
|
+
end
|
45
|
+
|
46
|
+
# See https://ruby-doc.org/3.2.0/Enumerable.html#method-i-sort
|
47
|
+
it "sort with one key ascending" do
|
48
|
+
sort_lambda = ->(a, b) { [a.last_modified] <=> [b.last_modified] }
|
49
|
+
result = objs.sort(&sort_lambda)
|
50
|
+
expect(result).to eq([o1, o2, o3, o4])
|
51
|
+
end
|
52
|
+
|
53
|
+
it "sort with one key descending" do
|
54
|
+
sort_lambda = ->(a, b) { [b.last_modified] <=> [a.last_modified] }
|
55
|
+
result = objs.sort(&sort_lambda)
|
56
|
+
expect(result).to eq([o4, o2, o3, o1])
|
57
|
+
end
|
58
|
+
|
59
|
+
it "sort with two keys ascending" do
|
60
|
+
sort_lambda = ->(a, b) { [a.last_modified, a.date] <=> [b.last_modified, b.date] }
|
61
|
+
result = objs.sort(&sort_lambda)
|
62
|
+
expect(result).to eq([o1, o2, o3, o4])
|
63
|
+
end
|
64
|
+
|
65
|
+
it "sort with both keys descending" do
|
66
|
+
sort_lambda = ->(a, b) { [b.last_modified, b.date] <=> [a.last_modified, a.date] }
|
67
|
+
result = objs.sort(&sort_lambda)
|
68
|
+
expect(result).to eq([o4, o3, o2, o1])
|
69
|
+
end
|
70
|
+
|
71
|
+
it "sort with last_modified descending and date ascending" do
|
72
|
+
sort_lambda = ->(a, b) { [b.last_modified, a.date] <=> [a.last_modified, b.date] }
|
73
|
+
result = objs.sort(&sort_lambda)
|
74
|
+
expect(result).to eq([o4, o2, o3, o1])
|
75
|
+
end
|
76
|
+
|
77
|
+
it "sort with last_modified ascending and date descending" do
|
78
|
+
sort_lambda = ->(a, b) { [a.last_modified, b.date] <=> [b.last_modified, a.date] }
|
79
|
+
result = objs.sort(&sort_lambda)
|
80
|
+
expect(result).to eq([o1, o3, o2, o4])
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class APageStub
|
4
|
+
attr_reader :date, :last_modified, :label
|
5
|
+
|
6
|
+
def initialize(date, last_modified, label = '')
|
7
|
+
@date = Date.parse date
|
8
|
+
@last_modified = Date.parse last_modified
|
9
|
+
@label = label
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
@label
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def show(lambda_string, result, expected)
|
18
|
+
p "For lambda_string: #{lambda_string}"
|
19
|
+
p " result: #{result.map(&:label).join(', ')} <==> expected: #{expected.map(&:label).join(', ')}"
|
20
|
+
end
|
21
|
+
|
22
|
+
# See https://stackoverflow.com/a/75388137/553865
|
23
|
+
RSpec.describe(AllCollectionsTag) do
|
24
|
+
let(:o1) { APageStub.new('2020-01-01', '2020-01-01', 'a_A') }
|
25
|
+
let(:o2) { APageStub.new('2021-01-01', '2020-01-01', 'b_A') }
|
26
|
+
let(:o3) { APageStub.new('2021-01-01', '2023-01-01', 'b_B') }
|
27
|
+
let(:o4) { APageStub.new('2022-01-01', '2023-01-01', 'c_B') }
|
28
|
+
let(:objs) { [o1, o2, o3, o4] }
|
29
|
+
|
30
|
+
it "defines sort_by lambda with last_modified" do
|
31
|
+
sort_lambda = ->(a, b) { [a.last_modified] <=> [b.last_modified] }
|
32
|
+
result = objs.sort(&sort_lambda)
|
33
|
+
expect(result).to eq([o1, o2, o3, o4])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "makes sort_by lambdas from stringified date" do
|
37
|
+
sort_lambda = eval "->(a, b) { a.last_modified <=> b.last_modified }",
|
38
|
+
NullBinding.new.min_binding, __FILE__, __LINE__ - 1
|
39
|
+
result = objs.sort(&sort_lambda)
|
40
|
+
expect(result).to eq([o1, o2, o3, o4])
|
41
|
+
end
|
42
|
+
|
43
|
+
it "defines sort_by lambda with array of last_modified" do
|
44
|
+
sort_lambda = ->(a, b) { [a.last_modified] <=> [b.last_modified] }
|
45
|
+
result = objs.sort(&sort_lambda)
|
46
|
+
expect(result).to eq([o1, o2, o3, o4])
|
47
|
+
end
|
48
|
+
|
49
|
+
it "makes sort_by lambdas from stringified array of last_modified" do
|
50
|
+
sort_lambda = eval "->(a, b) { [a.last_modified] <=> [b.last_modified] }",
|
51
|
+
NullBinding.new.min_binding, __FILE__, __LINE__ - 1
|
52
|
+
result = objs.sort(&sort_lambda)
|
53
|
+
expect(result).to eq([o1, o2, o3, o4])
|
54
|
+
end
|
55
|
+
|
56
|
+
it "makes sort_by lambdas with descending keys from stringified array of last_modified" do
|
57
|
+
sort_lambda = eval "->(a, b) { [b.last_modified] <=> [a.last_modified] }",
|
58
|
+
NullBinding.new.min_binding, __FILE__, __LINE__ - 1
|
59
|
+
result = objs.sort(&sort_lambda)
|
60
|
+
expected = [o3, o4, o1, o2]
|
61
|
+
expect(result).to eq(expected)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "create_lambda with 1 date key, descending" do
|
65
|
+
lambda_string = AllCollectionsTag::AllCollectionsTag.create_lambda_string('-last_modified')
|
66
|
+
sort_lambda = AllCollectionsTag::AllCollectionsTag.evaluate(lambda_string)
|
67
|
+
result = objs.sort(&sort_lambda)
|
68
|
+
expected = [o3, o4, o1, o2]
|
69
|
+
# show(lambda_string, result, expected)
|
70
|
+
expect(result).to eq(expected)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "create_lambda with 1 date key, ascending" do
|
74
|
+
lambda_string = AllCollectionsTag::AllCollectionsTag.create_lambda_string('date')
|
75
|
+
sort_lambda = AllCollectionsTag::AllCollectionsTag.evaluate(lambda_string)
|
76
|
+
result = objs.sort(&sort_lambda)
|
77
|
+
expected = [o1, o2, o3, o4]
|
78
|
+
# show(lambda_string, result, expected)
|
79
|
+
expect(result).to eq(expected)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "create_lambda with 2 date keys, both ascending" do
|
83
|
+
lambda_string = AllCollectionsTag::AllCollectionsTag.create_lambda_string(%w[date last_modified])
|
84
|
+
sort_lambda = AllCollectionsTag::AllCollectionsTag.evaluate(lambda_string)
|
85
|
+
result = objs.sort(&sort_lambda)
|
86
|
+
expected = [o1, o2, o3, o4]
|
87
|
+
# show(lambda_string, result, expected)
|
88
|
+
expect(result).to eq(expected)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "create_lambda with 2 date keys, both descending" do
|
92
|
+
lambda_string = AllCollectionsTag::AllCollectionsTag.create_lambda_string(['-date', '-last_modified'])
|
93
|
+
sort_lambda = AllCollectionsTag::AllCollectionsTag.evaluate(lambda_string)
|
94
|
+
result = objs.sort(&sort_lambda)
|
95
|
+
expected = [o4, o3, o2, o1]
|
96
|
+
# show(lambda_string, result, expected)
|
97
|
+
expect(result).to eq(expected)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "create_lambda with 2 date keys, first descending and second ascending" do
|
101
|
+
lambda_string = AllCollectionsTag::AllCollectionsTag.create_lambda_string(['-date', 'last_modified'])
|
102
|
+
sort_lambda = AllCollectionsTag::AllCollectionsTag.evaluate(lambda_string)
|
103
|
+
result = objs.sort(&sort_lambda)
|
104
|
+
expected = [o4, o2, o3, o1]
|
105
|
+
# show(lambda_string, result, expected)
|
106
|
+
expect(result).to eq(expected)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "create_lambda with 2 date keys, first ascending and second descending" do
|
110
|
+
lambda_string = AllCollectionsTag::AllCollectionsTag.create_lambda_string(['date', '-last_modified'])
|
111
|
+
sort_lambda = AllCollectionsTag::AllCollectionsTag.evaluate(lambda_string)
|
112
|
+
result = objs.sort(&sort_lambda)
|
113
|
+
expected = [o1, o3, o2, o4]
|
114
|
+
# show(lambda_string, result, expected)
|
115
|
+
expect(result).to eq(expected)
|
116
|
+
end
|
117
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
|
-
|
1
|
+
require 'jekyll'
|
2
|
+
require 'date'
|
2
3
|
|
3
|
-
|
4
|
-
require "fileutils"
|
5
|
-
require "key_value_parser"
|
6
|
-
require "shellwords"
|
7
|
-
|
8
|
-
require_relative "../lib/jekyll_all_collections"
|
4
|
+
require_relative '../lib/jekyll_all_collections'
|
9
5
|
|
10
6
|
Jekyll.logger.log_level = :info
|
11
7
|
|
12
8
|
RSpec.configure do |config|
|
13
9
|
config.filter_run :focus
|
14
|
-
config.order =
|
10
|
+
# config.order = 'random'
|
15
11
|
config.run_all_when_everything_filtered = true
|
16
12
|
|
17
13
|
# See https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures
|
18
|
-
config.example_status_persistence_file_path =
|
14
|
+
config.example_status_persistence_file_path = 'spec/status_persistence.txt'
|
19
15
|
end
|
data/spec/status_persistence.txt
CHANGED
@@ -1,5 +1,23 @@
|
|
1
|
-
example_id
|
2
|
-
|
3
|
-
./spec/
|
4
|
-
./spec/
|
5
|
-
./spec/
|
1
|
+
example_id | status | run_time |
|
2
|
+
-------------------------------- | ------ | --------------- |
|
3
|
+
./spec/date_sort_spec.rb[1:1] | passed | 0.00111 seconds |
|
4
|
+
./spec/date_sort_spec.rb[1:2] | passed | 0.00019 seconds |
|
5
|
+
./spec/date_sort_spec.rb[1:3] | passed | 0.00014 seconds |
|
6
|
+
./spec/date_sort_spec.rb[1:4] | passed | 0.00016 seconds |
|
7
|
+
./spec/date_sort_spec.rb[1:5] | passed | 0.00016 seconds |
|
8
|
+
./spec/date_sort_spec.rb[1:6] | passed | 0.00015 seconds |
|
9
|
+
./spec/date_sort_spec.rb[1:7] | passed | 0.00014 seconds |
|
10
|
+
./spec/date_sort_spec.rb[1:8] | passed | 0.00014 seconds |
|
11
|
+
./spec/date_sort_spec.rb[1:9] | passed | 0.00016 seconds |
|
12
|
+
./spec/date_sort_spec.rb[1:10] | passed | 0.00015 seconds |
|
13
|
+
./spec/lambda_sort_spec.rb[1:1] | passed | 0.00017 seconds |
|
14
|
+
./spec/lambda_sort_spec.rb[1:2] | passed | 0.00022 seconds |
|
15
|
+
./spec/lambda_sort_spec.rb[1:3] | passed | 0.00029 seconds |
|
16
|
+
./spec/lambda_sort_spec.rb[1:4] | passed | 0.0002 seconds |
|
17
|
+
./spec/lambda_sort_spec.rb[1:5] | passed | 0.00018 seconds |
|
18
|
+
./spec/lambda_sort_spec.rb[1:6] | passed | 0.0002 seconds |
|
19
|
+
./spec/lambda_sort_spec.rb[1:7] | passed | 0.00019 seconds |
|
20
|
+
./spec/lambda_sort_spec.rb[1:8] | passed | 0.00019 seconds |
|
21
|
+
./spec/lambda_sort_spec.rb[1:9] | passed | 0.00019 seconds |
|
22
|
+
./spec/lambda_sort_spec.rb[1:10] | passed | 0.00019 seconds |
|
23
|
+
./spec/lambda_sort_spec.rb[1:11] | passed | 0.00036 seconds |
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll_all_collections
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Slinn
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -25,50 +25,36 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 3.5.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: jekyll_draft
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.1.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 1.1.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: jekyll_plugin_support
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
45
|
+
- - "~>"
|
53
46
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
|
56
|
-
name: ruby-debug-ide
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
47
|
+
version: 0.3.1
|
48
|
+
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- - "
|
52
|
+
- - "~>"
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
54
|
+
version: 0.3.1
|
69
55
|
description: 'Provides a collection of all collections in site.all_collections.
|
70
56
|
|
71
|
-
'
|
57
|
+
'
|
72
58
|
email:
|
73
59
|
- email@email.com
|
74
60
|
executables: []
|
@@ -81,9 +67,12 @@ files:
|
|
81
67
|
- README.md
|
82
68
|
- Rakefile
|
83
69
|
- jekyll_all_collections.gemspec
|
70
|
+
- lib/all_collections_hooks.rb
|
71
|
+
- lib/all_collections_tag.rb
|
84
72
|
- lib/jekyll_all_collections.rb
|
85
73
|
- lib/jekyll_all_collections/version.rb
|
86
|
-
- spec/
|
74
|
+
- spec/date_sort_spec.rb
|
75
|
+
- spec/lambda_sort_spec.rb
|
87
76
|
- spec/spec_helper.rb
|
88
77
|
- spec/status_persistence.txt
|
89
78
|
homepage: https://www.mslinn.com/blog/2020/12/30/jekyll-plugin-template-collection.html
|
@@ -95,7 +84,7 @@ metadata:
|
|
95
84
|
changelog_uri: https://github.com/mslinn/jekyll_all_collections/CHANGELOG.md
|
96
85
|
homepage_uri: https://www.mslinn.com/blog/2020/12/30/jekyll-plugin-template-collection.html
|
97
86
|
source_code_uri: https://github.com/mslinn/jekyll_all_collections
|
98
|
-
post_install_message:
|
87
|
+
post_install_message:
|
99
88
|
rdoc_options: []
|
100
89
|
require_paths:
|
101
90
|
- lib
|
@@ -110,8 +99,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
99
|
- !ruby/object:Gem::Version
|
111
100
|
version: '0'
|
112
101
|
requirements: []
|
113
|
-
rubygems_version: 3.
|
114
|
-
signing_key:
|
102
|
+
rubygems_version: 3.3.3
|
103
|
+
signing_key:
|
115
104
|
specification_version: 4
|
116
105
|
summary: Provides a collection of all collections in site.all_collections.
|
117
106
|
test_files: []
|