lifer 0.8.0 → 0.9.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/CHANGELOG.md +15 -0
- data/Gemfile.lock +2 -2
- data/lib/lifer/builder/html/from_liquid/drops/entry_drop.rb +13 -6
- data/lib/lifer/builder/html/from_liquid/filters.rb +1 -1
- data/lib/lifer/builder/rss.rb +17 -5
- data/lib/lifer/collection.rb +2 -2
- data/lib/lifer/entry.rb +62 -20
- data/lib/lifer/utilities.rb +4 -1
- data/lib/lifer/version.rb +1 -1
- data/lib/lifer.rb +10 -0
- data/locales/en.yml +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b6414082e8f6f1d9b18034f2f227890b85ac73b22ab50c25cb2e350812c1a90
|
4
|
+
data.tar.gz: 5891afc57d102fd67422bf581edc4de839b05efbe10d104529a817391c0e7cad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7adb1041c558a2d60ef525bf1d12af4dd3d587a26f8ae0ef4e2f4c8fb9e04e14c648cf4bd72717aba143e747ccabe970ec1c859cd0c69b5259847887c0f99361
|
7
|
+
data.tar.gz: a9ec79fce82554f69ba1634ce414b7b63014c8545f8f8c5a6201c194d375d57d09a36128db4f6b242c279bfe0fe419f3b333034268415379c1b9138d372d352f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
## Next
|
2
2
|
|
3
|
+
## v0.9.0
|
4
|
+
|
5
|
+
Atom feeds now support entries with both `#published_at` and `#updated_at`
|
6
|
+
timestamp. There is no standard equivalent way to provide this functonality for
|
7
|
+
RSS-format feeds, unfortunately. As part of this change, we removed all
|
8
|
+
`Entry#date` methods in favour of `Entry#published_at` onces. In Atom feeds, if
|
9
|
+
an article has no last updated date, the publication date is used instead.
|
10
|
+
|
11
|
+
Additionally, this release includes a new environment variable:
|
12
|
+
`LIFER_UNPARALLELIZED`. You can use this environment variable to run `lifer
|
13
|
+
build` or `lifer serve` without any parallelization turned on. This could be
|
14
|
+
useful for reproducing bugs and so on. Example usage:
|
15
|
+
|
16
|
+
LIFER_UNPARALLELIZED=1 lifer build
|
17
|
+
|
3
18
|
## v0.8.0
|
4
19
|
|
5
20
|
### Tags
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lifer (0.
|
4
|
+
lifer (0.9.0)
|
5
5
|
i18n (< 2)
|
6
6
|
kramdown (~> 2.4)
|
7
7
|
liquid (~> 5.6, < 6)
|
@@ -44,7 +44,7 @@ GEM
|
|
44
44
|
kramdown (2.5.1)
|
45
45
|
rexml (>= 3.3.9)
|
46
46
|
language_server-protocol (3.17.0.3)
|
47
|
-
liquid (5.8.
|
47
|
+
liquid (5.8.2)
|
48
48
|
bigdecimal
|
49
49
|
strscan (>= 3.1.1)
|
50
50
|
listen (3.9.0)
|
@@ -4,7 +4,9 @@ module Lifer::Builder::HTML::FromLiquid::Drops
|
|
4
4
|
#
|
5
5
|
# @example Usage
|
6
6
|
# <h1>{{ entry.title }}</h1>
|
7
|
-
# <small>
|
7
|
+
# <small>
|
8
|
+
# Published on <datetime>{{ entry.published_at }}</datetime>
|
9
|
+
# </small>
|
8
10
|
#
|
9
11
|
class EntryDrop < Liquid::Drop
|
10
12
|
attr_accessor :lifer_entry, :collection
|
@@ -30,11 +32,6 @@ module Lifer::Builder::HTML::FromLiquid::Drops
|
|
30
32
|
# @return [String]
|
31
33
|
def content = (@content ||= lifer_entry.to_html)
|
32
34
|
|
33
|
-
# The entry date (as a string).
|
34
|
-
#
|
35
|
-
# @return [String]
|
36
|
-
def date = (@date ||= lifer_entry.date)
|
37
|
-
|
38
35
|
# The entry frontmatter data.
|
39
36
|
#
|
40
37
|
# @return [FrontmatterDrop]
|
@@ -50,6 +47,11 @@ module Lifer::Builder::HTML::FromLiquid::Drops
|
|
50
47
|
# @return [String] The entry permalink.
|
51
48
|
def permalink = (@permalink ||= lifer_entry.permalink)
|
52
49
|
|
50
|
+
# The entry publication date (as a string).
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
def published_at = (@published_at ||= lifer_entry.published_at)
|
54
|
+
|
53
55
|
# The summary of the entry.
|
54
56
|
#
|
55
57
|
# @return [String] The summary of the entry.
|
@@ -59,5 +61,10 @@ module Lifer::Builder::HTML::FromLiquid::Drops
|
|
59
61
|
#
|
60
62
|
# @return [String] The entry title.
|
61
63
|
def title = (@title ||= lifer_entry.title)
|
64
|
+
|
65
|
+
# The entry's last updated date (as a string).
|
66
|
+
#
|
67
|
+
# @return [String]
|
68
|
+
def updated_at = (@updated_at ||= lifer_entry.updated_at)
|
62
69
|
end
|
63
70
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# In many cases these utilities exist to be pseudo-compatible with Jekyll.
|
3
3
|
#
|
4
4
|
# @example A filter in a Liquid template.
|
5
|
-
# {{ entry.
|
5
|
+
# {{ entry.published_at | date_to_xmlschema }}
|
6
6
|
#
|
7
7
|
module Lifer::Builder::HTML::FromLiquid::Filters
|
8
8
|
# @!visibility private
|
data/lib/lifer/builder/rss.rb
CHANGED
@@ -65,8 +65,7 @@ class Lifer::Builder::RSS < Lifer::Builder
|
|
65
65
|
# The name of the format type, as needed by `RSS::Maker`, used by default by
|
66
66
|
# this feed builder.
|
67
67
|
#
|
68
|
-
|
69
|
-
|
68
|
+
DEFAULT_MAKER_FORMAT_NAME = FORMATS[:rss]
|
70
69
|
|
71
70
|
self.name = :rss
|
72
71
|
self.settings = [
|
@@ -96,7 +95,7 @@ class Lifer::Builder::RSS < Lifer::Builder
|
|
96
95
|
|
97
96
|
return FORMATS[format] if FORMATS.keys.include? format
|
98
97
|
|
99
|
-
|
98
|
+
DEFAULT_MAKER_FORMAT_NAME
|
100
99
|
end
|
101
100
|
|
102
101
|
# Traverses and renders an RSS feed for feedable collection.
|
@@ -220,8 +219,21 @@ class Lifer::Builder::RSS < Lifer::Builder
|
|
220
219
|
rss_feed_item.link = lifer_entry.permalink
|
221
220
|
rss_feed_item.title = lifer_entry.title
|
222
221
|
rss_feed_item.summary = lifer_entry.summary
|
223
|
-
|
224
|
-
|
222
|
+
|
223
|
+
if feed_format(lifer_entry.collection) == "atom"
|
224
|
+
rss_feed_item.content.content = lifer_entry.to_html
|
225
|
+
rss_feed_item.published = lifer_entry.published_at
|
226
|
+
|
227
|
+
# Note: RSS does not provide a standard way to share last updated
|
228
|
+
# timestamps at all, while Atom does. This is the reason there is no
|
229
|
+
# equivalent call in the condition for RSS feeds.
|
230
|
+
#
|
231
|
+
rss_feed_item.updated =
|
232
|
+
lifer_entry.updated_at(fallback: lifer_entry.published_at)
|
233
|
+
else
|
234
|
+
rss_feed_item.content_encoded = lifer_entry.to_html
|
235
|
+
rss_feed_item.pubDate = lifer_entry.published_at.to_time.rfc2822
|
236
|
+
end
|
225
237
|
end
|
226
238
|
end
|
227
239
|
|
data/lib/lifer/collection.rb
CHANGED
@@ -57,9 +57,9 @@ class Lifer::Collection
|
|
57
57
|
cached_entries_variable,
|
58
58
|
case order
|
59
59
|
when :latest
|
60
|
-
@entries_collection.sort_by { |entry| entry.
|
60
|
+
@entries_collection.sort_by { |entry| entry.published_at }.reverse
|
61
61
|
when :oldest
|
62
|
-
@entries_collection.sort_by { |entry| entry.
|
62
|
+
@entries_collection.sort_by { |entry| entry.published_at }
|
63
63
|
end
|
64
64
|
)
|
65
65
|
end
|
data/lib/lifer/entry.rb
CHANGED
@@ -150,26 +150,6 @@ module Lifer
|
|
150
150
|
full_text.gsub(FRONTMATTER_REGEX, "").strip
|
151
151
|
end
|
152
152
|
|
153
|
-
# Since text files would only store dates as simple strings, it's nice to
|
154
|
-
# attempt to convert those into Ruby date or datetime objects.
|
155
|
-
#
|
156
|
-
# @return [Time] A Ruby representation of the date and time provided by the
|
157
|
-
# entry frontmatter or filename.
|
158
|
-
def date
|
159
|
-
date_data = frontmatter[:date] || filename_date
|
160
|
-
|
161
|
-
case date_data
|
162
|
-
when Time then date_data
|
163
|
-
when String then DateTime.parse(date_data).to_time
|
164
|
-
else
|
165
|
-
Lifer::Message.log("entry.no_date_metadata", filename: file)
|
166
|
-
Lifer::Entry::DEFAULT_DATE
|
167
|
-
end
|
168
|
-
rescue ArgumentError => error
|
169
|
-
Lifer::Message.error("entry.date_error", filename: file, error:)
|
170
|
-
Lifer::Entry::DEFAULT_DATE
|
171
|
-
end
|
172
|
-
|
173
153
|
def feedable?
|
174
154
|
if (setting = self.class.include_in_feeds).nil?
|
175
155
|
raise NotImplementedError,
|
@@ -232,6 +212,27 @@ module Lifer
|
|
232
212
|
# @return [String] The absolute URI path to the entry.
|
233
213
|
def path = permalink(host: "/")
|
234
214
|
|
215
|
+
# The entry's publication date. The published date can be inferred in a few
|
216
|
+
# ways. The priority is:
|
217
|
+
#
|
218
|
+
# 1. the frontmatter's `published_at` field
|
219
|
+
# 2. the frontmatter's `published` field
|
220
|
+
# 3. the frontamtter's `date` field
|
221
|
+
# 4. The date in the filename.
|
222
|
+
#
|
223
|
+
# Since text files would only store dates as simple strings, it's nice to
|
224
|
+
# attempt to convert those into Ruby date or datetime objects.
|
225
|
+
#
|
226
|
+
# @return [Time] A Ruby representation of the date and time provided by the
|
227
|
+
# entry frontmatter or filename.
|
228
|
+
def published_at
|
229
|
+
date_for frontmatter[:published_at],
|
230
|
+
frontmatter[:published],
|
231
|
+
frontmatter[:date],
|
232
|
+
filename_date,
|
233
|
+
missing_metadata_translation_key: "entry.no_published_at_metadata"
|
234
|
+
end
|
235
|
+
|
235
236
|
# If given a summary in the frontmatter of the entry, we can use this to
|
236
237
|
# provide a summary.
|
237
238
|
#
|
@@ -263,6 +264,26 @@ module Lifer
|
|
263
264
|
raise NotImplementedError, I18n.t("shared.not_implemented_method")
|
264
265
|
end
|
265
266
|
|
267
|
+
# The entry's last updated date. In the frontmatter, the last updated date
|
268
|
+
# can be specified using one of two fields. In priority order:
|
269
|
+
#
|
270
|
+
# 1. the `updated_at` field
|
271
|
+
# 2. the `updated` field
|
272
|
+
#
|
273
|
+
# The developer could set a fallback value as a fallback. For example, when
|
274
|
+
# building RSS feeds one might want the value of `#published_at` if there is
|
275
|
+
# no last updated date.
|
276
|
+
#
|
277
|
+
# @param fallback [Time, String, NilClass] Provide datetime data, a string
|
278
|
+
# that parses to a datetime object, or nil.
|
279
|
+
# @return [Time] A Ruby representation of the date and time provided by the
|
280
|
+
# entry frontmatter.
|
281
|
+
def updated_at(fallback: nil)
|
282
|
+
date_for frontmatter[:updated_at],
|
283
|
+
frontmatter[:updated],
|
284
|
+
default_date: fallback
|
285
|
+
end
|
286
|
+
|
266
287
|
private
|
267
288
|
|
268
289
|
# It is conventional for users to use spaces or commas to delimit tags in
|
@@ -278,6 +299,27 @@ module Lifer
|
|
278
299
|
end.uniq
|
279
300
|
end
|
280
301
|
|
302
|
+
def date_for(
|
303
|
+
*candidate_date_fields,
|
304
|
+
default_date: Lifer::Entry::DEFAULT_DATE,
|
305
|
+
missing_metadata_translation_key: nil
|
306
|
+
)
|
307
|
+
date_data = candidate_date_fields.detect(&:itself)
|
308
|
+
|
309
|
+
case date_data
|
310
|
+
when Time then date_data
|
311
|
+
when String then DateTime.parse(date_data).to_time
|
312
|
+
else
|
313
|
+
if (translation_string = missing_metadata_translation_key)
|
314
|
+
Lifer::Message.log(translation_string, filename: file)
|
315
|
+
end
|
316
|
+
default_date
|
317
|
+
end
|
318
|
+
rescue ArgumentError => error
|
319
|
+
Lifer::Message.error("entry.date_error", filename: file, error:)
|
320
|
+
default_date
|
321
|
+
end
|
322
|
+
|
281
323
|
def filename_date
|
282
324
|
return unless file && File.basename(file).match?(FILENAME_DATE_FORMAT)
|
283
325
|
|
data/lib/lifer/utilities.rb
CHANGED
@@ -76,7 +76,10 @@ module Lifer::Utilities
|
|
76
76
|
# @raise [Exception] Any exception thrown by a child process.
|
77
77
|
# @return [Array] The mapped results of the operation.
|
78
78
|
def parallelized(collection, &block)
|
79
|
-
|
79
|
+
options = {}
|
80
|
+
options[:in_threads] = 0 if Lifer.parallelism_disabled?
|
81
|
+
|
82
|
+
results = Parallel.map(collection, **options) do |collection_item|
|
80
83
|
begin
|
81
84
|
yield collection_item
|
82
85
|
rescue => error
|
data/lib/lifer/version.rb
CHANGED
data/lib/lifer.rb
CHANGED
@@ -96,6 +96,16 @@ module Lifer
|
|
96
96
|
# project would be built to.
|
97
97
|
def output_directory = brain.output_directory
|
98
98
|
|
99
|
+
# Returns false if the Lifer project will be built with parallelism. This
|
100
|
+
# should return false almost always--unless you've explicitly set the
|
101
|
+
# `LIFER_UNPARALLELIZED` environment variable before running the program.
|
102
|
+
#
|
103
|
+
# This method is used internally by Lifer to determine whether features that
|
104
|
+
# would normally run in parallel should *not* run in parallel for some reason.
|
105
|
+
#
|
106
|
+
# @return [boolean] Returns whether parallelism is disabled.
|
107
|
+
def parallelism_disabled? = ENV["LIFER_UNPARALLELIZED"].is_a?(String)
|
108
|
+
|
99
109
|
# Register new settings so that they are "safe" and can be read from a Lifer
|
100
110
|
# configuration file. Unregistered settings are ignored.
|
101
111
|
#
|
data/locales/en.yml
CHANGED
@@ -33,7 +33,7 @@ en:
|
|
33
33
|
date_error: "[%{filename}]: %{error}"
|
34
34
|
feedable_error: >
|
35
35
|
please set `%{entry_class}.include_in_feeds` to true or false
|
36
|
-
|
36
|
+
no_published_at_metadata: "[%{filename}]: no `published_at` metadata"
|
37
37
|
not_found: >
|
38
38
|
file "%{file}" does not exist
|
39
39
|
config:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lifer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- benjamin wil
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -210,8 +210,8 @@ licenses:
|
|
210
210
|
- MIT
|
211
211
|
metadata:
|
212
212
|
allowed_push_host: https://rubygems.org
|
213
|
-
homepage_uri: https://github.com/benjaminwil/lifer/blob/v0.
|
214
|
-
source_code_uri: https://github.com/benjaminwil/lifer/tree/v0.
|
213
|
+
homepage_uri: https://github.com/benjaminwil/lifer/blob/v0.9.0/README.md
|
214
|
+
source_code_uri: https://github.com/benjaminwil/lifer/tree/v0.9.0
|
215
215
|
changelog_uri: https://github.com/benjaminwil/lifer/blob/main/CHANGELOG.md
|
216
216
|
post_install_message:
|
217
217
|
rdoc_options: []
|