jekyll_all_collections 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/jekyll_all_collections.svg)](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: []
|