lifer 0.9.0 → 0.10.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 +22 -0
- data/Gemfile.lock +6 -6
- data/lib/lifer/builder/html/from_any.rb +66 -0
- data/lib/lifer/builder/html/from_erb.rb +10 -12
- data/lib/lifer/builder/html/from_liquid/liquid_env.rb +0 -2
- data/lib/lifer/builder/html/from_liquid.rb +16 -29
- data/lib/lifer/builder/html.rb +1 -0
- data/lib/lifer/entry.rb +4 -7
- data/lib/lifer/version.rb +1 -1
- data/lib/lifer.rb +4 -0
- metadata +5 -5
- data/lib/lifer/builder/html/from_liquid/layout_tag.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1d33c1f633f27b80005a2e2e7c1919f43d86a5fdba9f12523dd4dcdb4e47422
|
4
|
+
data.tar.gz: 37927e9a39b49363ee0de3f34294c4e8ccf82b83a7a73b8d86ebc1bae8243947
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db511f0ace1e617851b7e4de0fd12f9a615c283db318d3c05013cdadbae40ab89cd6be06bc429f4c443caf5d1c67f1d385276f4596788eadbfe3d22916e9c20d
|
7
|
+
data.tar.gz: 917d189530c40b4c15fb57a9d1bfce28a809b00fd07267b5a2485997adcb8c3e557dcf242def3a515297b908a5000902a1e7fcbe4bff29240791a88681b2fa1f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
## Next
|
2
2
|
|
3
|
+
## v0.10.0
|
4
|
+
|
5
|
+
These commits collect work to let all layout files (either Liquid or ERB files)
|
6
|
+
provide a reference to parent, or "root", layout files that should wrap the via
|
7
|
+
frontmatter.
|
8
|
+
|
9
|
+
Previously, we did this for Liquid layouts using the custom `layout` tag. But
|
10
|
+
because there was no equivalent tag for ERB files, I realized it would be less
|
11
|
+
work to just provide the value via frontmatter. The same way for every type of
|
12
|
+
layout file.
|
13
|
+
|
14
|
+
End users (just me?) must update their Lifer project Liquid layouts accordingly:
|
15
|
+
|
16
|
+
```diff
|
17
|
+
- {% layout "layouts/root_layout.html.liquid" %}
|
18
|
+
+ ---
|
19
|
+
+ layout: layouts/root_layout.html.liquid
|
20
|
+
+ ---
|
21
|
+
|
22
|
+
Layout content.
|
23
|
+
```
|
24
|
+
|
3
25
|
## v0.9.0
|
4
26
|
|
5
27
|
Atom feeds now support entries with both `#published_at` and `#updated_at`
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lifer (0.
|
4
|
+
lifer (0.10.0)
|
5
5
|
i18n (< 2)
|
6
6
|
kramdown (~> 2.4)
|
7
7
|
liquid (~> 5.6, < 6)
|
@@ -32,9 +32,9 @@ GEM
|
|
32
32
|
irb (~> 1.10)
|
33
33
|
reline (>= 0.3.8)
|
34
34
|
diff-lcs (1.5.1)
|
35
|
-
ffi (1.17.
|
36
|
-
ffi (1.17.
|
37
|
-
ffi (1.17.
|
35
|
+
ffi (1.17.2-arm64-darwin)
|
36
|
+
ffi (1.17.2-x86_64-darwin)
|
37
|
+
ffi (1.17.2-x86_64-linux-gnu)
|
38
38
|
i18n (1.14.7)
|
39
39
|
concurrent-ruby (~> 1.0)
|
40
40
|
io-console (0.7.2)
|
@@ -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.6)
|
48
48
|
bigdecimal
|
49
49
|
strscan (>= 3.1.1)
|
50
50
|
listen (3.9.0)
|
@@ -107,7 +107,7 @@ GEM
|
|
107
107
|
sorbet-runtime (>= 0.5.10782)
|
108
108
|
sorbet-runtime (0.5.11558)
|
109
109
|
stringio (3.1.1)
|
110
|
-
strscan (3.1.
|
110
|
+
strscan (3.1.5)
|
111
111
|
xpath (3.2.0)
|
112
112
|
nokogiri (~> 1.8)
|
113
113
|
yard (0.9.37)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class Lifer::Builder
|
2
|
+
class HTML
|
3
|
+
# A base class for all HTML builder adapters. The methods provided by this
|
4
|
+
# class are either required or reusable by builder subclasses. See the
|
5
|
+
# committed HTML builder adapter classes for example implementations.
|
6
|
+
class FromAny
|
7
|
+
class << self
|
8
|
+
# Build and render an entry.
|
9
|
+
#
|
10
|
+
# @param entry [Lifer::Entry] The entry to be rendered.
|
11
|
+
# @return [String] The rendered entry.
|
12
|
+
def build(entry:)
|
13
|
+
new(entry: entry).render
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# The base class does not provide a render method, but any subclass
|
18
|
+
# should be expected to.
|
19
|
+
#
|
20
|
+
# @raise [NotImplementedError]
|
21
|
+
def render
|
22
|
+
raise NotImplementedError,
|
23
|
+
"subclasses must implement a custom `#render` method"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# The frontmatter provided by the layout file.
|
29
|
+
#
|
30
|
+
# @return [Hash] The frontmatter represented as a hash.
|
31
|
+
def frontmatter
|
32
|
+
return {} unless frontmatter?
|
33
|
+
|
34
|
+
Lifer::Utilities.symbolize_keys(
|
35
|
+
YAML.load layout_file_contents(raw: true)[Lifer::FRONTMATTER_REGEX, 1],
|
36
|
+
permitted_classes: [Time]
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Checks whether frontmatter is present in the layout file.
|
41
|
+
#
|
42
|
+
# @return [boolean]
|
43
|
+
def frontmatter?
|
44
|
+
@frontmatter ||=
|
45
|
+
layout_file_contents(raw: true).match?(Lifer::FRONTMATTER_REGEX)
|
46
|
+
end
|
47
|
+
|
48
|
+
# The contents of the layout file.
|
49
|
+
#
|
50
|
+
# @param raw [boolean] Whether to include or exclude frontmatter from
|
51
|
+
# the contents.
|
52
|
+
# @return [String] The contents of the layout file.
|
53
|
+
def layout_file_contents(raw: false)
|
54
|
+
cache_variable = "@layout_file_contents_#{raw}"
|
55
|
+
cached_value = instance_variable_get cache_variable
|
56
|
+
|
57
|
+
return cached_value if cached_value
|
58
|
+
|
59
|
+
contents = File.read layout_file
|
60
|
+
contents = contents.gsub(Lifer::FRONTMATTER_REGEX, "") unless raw
|
61
|
+
|
62
|
+
instance_variable_set cache_variable, contents
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -23,23 +23,21 @@ class Lifer::Builder::HTML
|
|
23
23
|
# </body>
|
24
24
|
# </html>
|
25
25
|
#
|
26
|
-
class FromERB
|
27
|
-
class << self
|
28
|
-
# Build and render an entry.
|
29
|
-
#
|
30
|
-
# @param entry [Lifer::Entry] The entry to be rendered.
|
31
|
-
# @return [String] The rendered entry.
|
32
|
-
def build(entry:)
|
33
|
-
new(entry: entry).render
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
26
|
+
class FromERB < FromAny
|
37
27
|
# Reads the entry as ERB, given our renderer context (see the documentation
|
38
28
|
# for `#build_binding_context`) and renders the production-ready entry.
|
39
29
|
#
|
40
30
|
# @return [String] The rendered entry.
|
41
31
|
def render
|
42
|
-
ERB.new(
|
32
|
+
document = ERB.new(layout_file_contents).result context
|
33
|
+
|
34
|
+
return document unless (relative_layout_path = frontmatter[:layout])
|
35
|
+
|
36
|
+
document_binding = binding.tap { |binding|
|
37
|
+
binding.local_variable_set :content, document
|
38
|
+
}
|
39
|
+
layout_path = "%s/%s" % [Lifer.root, relative_layout_path]
|
40
|
+
ERB.new(File.read layout_path).result(document_binding)
|
43
41
|
end
|
44
42
|
|
45
43
|
private
|
@@ -22,8 +22,6 @@ class Lifer::Builder::HTML::FromLiquid
|
|
22
22
|
Liquid::LocalFileSystem.new(Lifer.root, "%s.html.liquid")
|
23
23
|
|
24
24
|
environment.register_filter Lifer::Builder::HTML::FromLiquid::Filters
|
25
|
-
environment.register_tag "layout",
|
26
|
-
Lifer::Builder::HTML::FromLiquid::LayoutTag
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -1,10 +1,5 @@
|
|
1
1
|
require "liquid"
|
2
2
|
|
3
|
-
require_relative "from_liquid/drops"
|
4
|
-
require_relative "from_liquid/filters"
|
5
|
-
require_relative "from_liquid/layout_tag"
|
6
|
-
require_relative "from_liquid/liquid_env"
|
7
|
-
|
8
3
|
class Lifer::Builder::HTML
|
9
4
|
# If the HTML builder is given a Liquid template, it uses this class to parse
|
10
5
|
# the Liquid into HTML. Lifer project metadata is provided as context. For
|
@@ -28,16 +23,10 @@ class Lifer::Builder::HTML
|
|
28
23
|
# </body>
|
29
24
|
# </html>
|
30
25
|
#
|
31
|
-
class FromLiquid
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# @param entry [Lifer::Entry] The entry to render.
|
36
|
-
# @return [String] The rendered entry, ready for output.
|
37
|
-
def build(entry:) = new(entry:).render
|
38
|
-
end
|
39
|
-
|
40
|
-
attr_accessor :entry, :layout_file
|
26
|
+
class FromLiquid < FromAny
|
27
|
+
require_relative "from_liquid/drops"
|
28
|
+
require_relative "from_liquid/filters"
|
29
|
+
require_relative "from_liquid/liquid_env"
|
41
30
|
|
42
31
|
# Reads the entry as Liquid, given our document context, and renders
|
43
32
|
# an entry.
|
@@ -49,13 +38,23 @@ class Lifer::Builder::HTML
|
|
49
38
|
.parse(entry.to_html, **parse_options)
|
50
39
|
.render(context, **render_options)
|
51
40
|
)
|
41
|
+
document = Liquid::Template
|
42
|
+
.parse(layout_file_contents, **parse_options)
|
43
|
+
.render(document_context, **render_options)
|
44
|
+
|
45
|
+
return document unless (relative_layout_path = frontmatter[:layout])
|
46
|
+
|
47
|
+
layout_path = "%s/%s" % [Lifer.root, relative_layout_path]
|
48
|
+
document_context = context.merge! "content" => document
|
52
49
|
Liquid::Template
|
53
|
-
.parse(
|
50
|
+
.parse(File.read layout_path, **parse_options)
|
54
51
|
.render(document_context, **render_options)
|
55
52
|
end
|
56
53
|
|
57
54
|
private
|
58
55
|
|
56
|
+
attr_accessor :entry, :layout_file
|
57
|
+
|
59
58
|
def initialize(entry:)
|
60
59
|
@entry = entry
|
61
60
|
@layout_file = entry.collection.layout_file
|
@@ -79,19 +78,6 @@ class Lifer::Builder::HTML
|
|
79
78
|
}
|
80
79
|
end
|
81
80
|
|
82
|
-
# @private
|
83
|
-
# It's possible for the provided layout to request a parent layout, which
|
84
|
-
# makes this method a bit complicated.
|
85
|
-
#
|
86
|
-
# @return [String] A Liquid layout document, ready for parsing.
|
87
|
-
def layout
|
88
|
-
contents = File.read layout_file
|
89
|
-
|
90
|
-
return contents unless contents.match?(/\{%\s*#{LayoutTag::NAME}.*%\}/)
|
91
|
-
|
92
|
-
contents + "\n{% #{LayoutTag::ENDNAME} %}"
|
93
|
-
end
|
94
|
-
|
95
81
|
def liquid_environment = (@liquid_environment ||= LiquidEnv.global)
|
96
82
|
|
97
83
|
def parse_options
|
@@ -103,6 +89,7 @@ class Lifer::Builder::HTML
|
|
103
89
|
|
104
90
|
def render_options
|
105
91
|
{
|
92
|
+
registers: {file_system: liquid_environment.file_system},
|
106
93
|
strict_variables: true,
|
107
94
|
strict_filters: true
|
108
95
|
}
|
data/lib/lifer/builder/html.rb
CHANGED
data/lib/lifer/entry.rb
CHANGED
@@ -39,10 +39,6 @@ module Lifer
|
|
39
39
|
#
|
40
40
|
FILENAME_DATE_FORMAT = /^(\d{4}-\d{1,2}-\d{1,2})-/
|
41
41
|
|
42
|
-
# We expect frontmatter to be provided in the following format.
|
43
|
-
#
|
44
|
-
FRONTMATTER_REGEX = /^---\n(.*)---\n/m
|
45
|
-
|
46
42
|
# If tags are represented in YAML frontmatter as a string, they're split on
|
47
43
|
# commas and/or spaces.
|
48
44
|
#
|
@@ -147,7 +143,7 @@ module Lifer
|
|
147
143
|
def body
|
148
144
|
return full_text.strip unless frontmatter?
|
149
145
|
|
150
|
-
full_text.gsub(FRONTMATTER_REGEX, "").strip
|
146
|
+
full_text.gsub(Lifer::FRONTMATTER_REGEX, "").strip
|
151
147
|
end
|
152
148
|
|
153
149
|
def feedable?
|
@@ -168,7 +164,8 @@ module Lifer
|
|
168
164
|
return {} unless frontmatter?
|
169
165
|
|
170
166
|
Lifer::Utilities.symbolize_keys(
|
171
|
-
YAML.load
|
167
|
+
YAML.load full_text[Lifer::FRONTMATTER_REGEX, 1],
|
168
|
+
permitted_classes: [Time]
|
172
169
|
)
|
173
170
|
end
|
174
171
|
|
@@ -326,6 +323,6 @@ module Lifer
|
|
326
323
|
File.basename(file).match(FILENAME_DATE_FORMAT)[1]
|
327
324
|
end
|
328
325
|
|
329
|
-
def frontmatter? = (full_text && full_text.match?(FRONTMATTER_REGEX))
|
326
|
+
def frontmatter? = (full_text && full_text.match?(Lifer::FRONTMATTER_REGEX))
|
330
327
|
end
|
331
328
|
end
|
data/lib/lifer/version.rb
CHANGED
data/lib/lifer.rb
CHANGED
@@ -24,6 +24,10 @@ module Lifer
|
|
24
24
|
"(\\/\\.)+" # Contains a dot directory.
|
25
25
|
] | IGNORE_DIRECTORIES.map { |d| "^(#{d})" }
|
26
26
|
|
27
|
+
# We expect frontmatter in any file to be provided in the following format.
|
28
|
+
#
|
29
|
+
FRONTMATTER_REGEX = /^---\n(.*)---\n/m
|
30
|
+
|
27
31
|
class << self
|
28
32
|
# The first time `Lifer.brain` is referenced, we build a new `Lifer::Brain`
|
29
33
|
# object that is used and reused until the current process has ended.
|
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.10.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-
|
11
|
+
date: 2025-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- lib/lifer/brain.rb
|
160
160
|
- lib/lifer/builder.rb
|
161
161
|
- lib/lifer/builder/html.rb
|
162
|
+
- lib/lifer/builder/html/from_any.rb
|
162
163
|
- lib/lifer/builder/html/from_erb.rb
|
163
164
|
- lib/lifer/builder/html/from_liquid.rb
|
164
165
|
- lib/lifer/builder/html/from_liquid/drops.rb
|
@@ -170,7 +171,6 @@ files:
|
|
170
171
|
- lib/lifer/builder/html/from_liquid/drops/tag_drop.rb
|
171
172
|
- lib/lifer/builder/html/from_liquid/drops/tags_drop.rb
|
172
173
|
- lib/lifer/builder/html/from_liquid/filters.rb
|
173
|
-
- lib/lifer/builder/html/from_liquid/layout_tag.rb
|
174
174
|
- lib/lifer/builder/html/from_liquid/liquid_env.rb
|
175
175
|
- lib/lifer/builder/rss.rb
|
176
176
|
- lib/lifer/builder/txt.rb
|
@@ -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.10.0/README.md
|
214
|
+
source_code_uri: https://github.com/benjaminwil/lifer/tree/v0.10.0
|
215
215
|
changelog_uri: https://github.com/benjaminwil/lifer/blob/main/CHANGELOG.md
|
216
216
|
post_install_message:
|
217
217
|
rdoc_options: []
|
@@ -1,66 +0,0 @@
|
|
1
|
-
class Lifer::Builder::HTML::FromLiquid
|
2
|
-
# Note that if you want to learn more about the shape of this class, check out
|
3
|
-
# `Liquid::Block` in the `liquid` gem.
|
4
|
-
#
|
5
|
-
# The layout tag is a bit magic. The idea here is to emulate how Jekyll
|
6
|
-
# handles `layout:` YAML frontmatter within entries to change the normal
|
7
|
-
# parent layout to an override parent layout--but without the need for
|
8
|
-
# frontmatter.
|
9
|
-
#
|
10
|
-
# The reason we took this strategy was to avoid pre-processing every entry for
|
11
|
-
# frontmatter when we didn't need to. Maybe in the long run this was a bad
|
12
|
-
# call? I don't know.
|
13
|
-
#
|
14
|
-
# @example Usage from a Liquid template.
|
15
|
-
# {% layout "path/to/my_liquid_layout_template" %}
|
16
|
-
#
|
17
|
-
# (The required `endlayout` tag will be appended to the end of the file
|
18
|
-
# on render if you do not insert it yourself.
|
19
|
-
#
|
20
|
-
class LayoutTag < Liquid::Block
|
21
|
-
# The name of the tag in Liquid templates, `layout`.
|
22
|
-
#
|
23
|
-
NAME = :layout
|
24
|
-
|
25
|
-
# The end name of the tag in Liquid templates, `endlayout`.
|
26
|
-
#
|
27
|
-
ENDNAME = ("end%s" % NAME).to_sym
|
28
|
-
|
29
|
-
def initialize(layout, path, options)
|
30
|
-
@path = path.delete("\"").strip
|
31
|
-
super
|
32
|
-
end
|
33
|
-
|
34
|
-
# A layout tag wraps an entire document and outputs it inside of whatever
|
35
|
-
# the `@layout` is. This lets a child document specify a parernt layout!
|
36
|
-
# Very confusing stuff.
|
37
|
-
#
|
38
|
-
# @param context [Liquid::Context] All of the context of the Liquid
|
39
|
-
# document that would be rendered.
|
40
|
-
# @return [String] A rendered document.
|
41
|
-
def render(context)
|
42
|
-
document_context = context.environments.first
|
43
|
-
parse_options = document_context["parse_options"]
|
44
|
-
liquid_file_system = parse_options[:environment].file_system
|
45
|
-
render_options = document_context["render_options"]
|
46
|
-
|
47
|
-
current_layout_file = File
|
48
|
-
.read(document_context["entry"]["collection"]["layout_file"])
|
49
|
-
.gsub(/\{%\s*#{tag_name}.+%\}/, "")
|
50
|
-
|
51
|
-
content_with_layout = Liquid::Template
|
52
|
-
.parse(current_layout_file, **parse_options)
|
53
|
-
.render(document_context, **render_options)
|
54
|
-
|
55
|
-
Liquid::Template
|
56
|
-
.parse(
|
57
|
-
liquid_file_system.read_template_file(@path),
|
58
|
-
**parse_options
|
59
|
-
)
|
60
|
-
.render(
|
61
|
-
document_context.merge({"content" => content_with_layout}),
|
62
|
-
**render_options
|
63
|
-
)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|