yarrow 0.8.3 → 0.8.5
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/lib/extensions/mementus.rb +7 -0
- data/lib/yarrow/content/expansion/strategy.rb +17 -0
- data/lib/yarrow/content/expansion/tree.rb +49 -29
- data/lib/yarrow/content/policy.rb +3 -0
- data/lib/yarrow/generator.rb +1 -1
- data/lib/yarrow/schema/definitions.rb +2 -1
- data/lib/yarrow/schema/dictionary.rb +2 -2
- data/lib/yarrow/schema/entity.rb +1 -1
- data/lib/yarrow/schema/types.rb +15 -4
- data/lib/yarrow/version.rb +1 -1
- data/lib/yarrow/web/document.rb +45 -5
- data/lib/yarrow/web/manifest.rb +2 -2
- data/lib/yarrow.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33fcaf7b1d66e43c0bd0a83967d0cc8b4891b96ec652bbfd28e5e91e7991b7e2
|
4
|
+
data.tar.gz: ccf4513eee11929864f76386e22adf39224a1898f5b207a3cefb11a30a5ed6e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20272c169c2dd1280c06b80277a981217ae08c77c80892b4c8d07bac0564099ea0cbc248d54ac3160522e7e38c7dbe129aa703e6cb9e9cb848619f2009e15273
|
7
|
+
data.tar.gz: 143a1bbb91909f1e8921b9b587f611293b2f20de9f50d66b18a7346c00e6ebc2078d98ac0e9abcb88cad258e2f3a2d902f1f2eda811d27abd0348ece8f7cf87e
|
data/lib/extensions/mementus.rb
CHANGED
@@ -34,6 +34,23 @@ module Yarrow
|
|
34
34
|
data
|
35
35
|
end
|
36
36
|
|
37
|
+
def populate_collection(node, policy, meta_attrs)
|
38
|
+
node.label = :collection
|
39
|
+
node.props[:type] = policy.collection
|
40
|
+
node.props[:resource] = policy.collection_const.new(meta_attrs)
|
41
|
+
end
|
42
|
+
|
43
|
+
def populate_entity(node, policy, meta_attrs)
|
44
|
+
node.label = :item
|
45
|
+
node.props[:type] = policy.entity
|
46
|
+
node.props[:resource] = policy.entity_const.new(meta_attrs)
|
47
|
+
end
|
48
|
+
|
49
|
+
def merge_collection_index(node, policy, meta_attrs)
|
50
|
+
props = { resource: node.props[:resource].merge(meta_attrs) }
|
51
|
+
node.merge_props(props)
|
52
|
+
end
|
53
|
+
|
37
54
|
# Workaround for handling meta and content source in multiple files or a single
|
38
55
|
# file with front matter.
|
39
56
|
def process_content(path)
|
@@ -21,11 +21,12 @@ module Yarrow
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# Extract metadata from given start node
|
24
|
-
collection_metadata = extract_metadata(start_node, policy.container)
|
24
|
+
#collection_metadata = extract_metadata(start_node, policy.container)
|
25
25
|
|
26
26
|
# Collect all nested collections in the subgraph for this content type
|
27
27
|
subcollections = {}
|
28
|
-
|
28
|
+
entity_links = []
|
29
|
+
index_links = []
|
29
30
|
index = nil
|
30
31
|
|
31
32
|
# Scan and collect all nested files from the root
|
@@ -33,12 +34,14 @@ module Yarrow
|
|
33
34
|
if node.label == :directory
|
34
35
|
# Create a collection node representing a collection of documents
|
35
36
|
index = graph.create_node do |collection_node|
|
36
|
-
collection_node.label = :collection
|
37
|
-
collection_node.props[:type] = policy.container
|
38
|
-
collection_node.props[:name] = node.props[:name]
|
39
37
|
|
40
|
-
|
41
|
-
|
38
|
+
collection_attrs = {
|
39
|
+
name: node.props[:name],
|
40
|
+
title: node.props[:name].capitalize,
|
41
|
+
body: ""
|
42
|
+
}
|
43
|
+
|
44
|
+
populate_collection(collection_node, policy, collection_attrs)
|
42
45
|
end
|
43
46
|
|
44
47
|
# Add this collection id to the lookup table for edge construction
|
@@ -54,38 +57,55 @@ module Yarrow
|
|
54
57
|
end
|
55
58
|
elsif node.label == :file
|
56
59
|
body, meta = process_content(node.props[:entry])
|
60
|
+
meta = {} if !meta
|
57
61
|
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
#
|
68
|
-
|
69
|
-
|
62
|
+
# TODO: document mapping convention for index pages and collection metadata
|
63
|
+
# TODO: underscore _index pattern?
|
64
|
+
bare_basename = node.props[:entry].basename(node.props[:entry].extname)
|
65
|
+
if bare_basename.to_s == "index"
|
66
|
+
index_links << {
|
67
|
+
parent_id: subcollections[node.props[:entry].parent.to_s],
|
68
|
+
index_attrs: meta.merge({ body: body})
|
69
|
+
}
|
70
|
+
else
|
71
|
+
# Create an entity node representing a file mapped to a unique content object
|
72
|
+
entity = graph.create_node do |entity_node|
|
73
|
+
|
74
|
+
entity_slug = node.props[:entry].basename(node.props[:entry].extname).to_s
|
70
75
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
76
|
+
entity_attrs = {
|
77
|
+
name: entity_slug,
|
78
|
+
title: entity_slug.gsub("-", " ").capitalize,
|
79
|
+
body: body
|
80
|
+
}
|
81
|
+
|
82
|
+
populate_entity(entity_node, policy, entity_attrs.merge(meta || {}))
|
83
|
+
end
|
84
|
+
|
85
|
+
# We may not have an expanded node for the parent collection if this is a
|
86
|
+
# preorder traversal so save it for later
|
87
|
+
entity_links << {
|
88
|
+
parent_id: subcollections[node.props[:entry].parent.to_s],
|
89
|
+
child_id: entity
|
90
|
+
}
|
91
|
+
end
|
77
92
|
end
|
78
93
|
end
|
79
94
|
|
80
95
|
# Once all files and directories have been expanded, connect all the child
|
81
|
-
# edges between collections and
|
82
|
-
|
96
|
+
# edges between collections and entities
|
97
|
+
entity_links.each do |entity_link|
|
83
98
|
graph.create_edge do |edge|
|
84
99
|
edge.label = :child
|
85
|
-
edge.from =
|
86
|
-
edge.to =
|
100
|
+
edge.from = entity_link[:parent_id].id
|
101
|
+
edge.to = entity_link[:child_id].id
|
87
102
|
end
|
88
103
|
end
|
104
|
+
|
105
|
+
# Merge index page body and metadata with their parent collections
|
106
|
+
index_links.each do |index_link|
|
107
|
+
merge_collection_index(index_link[:parent_id], policy, index_link[:index_attrs])
|
108
|
+
end
|
89
109
|
end
|
90
110
|
end
|
91
111
|
end
|
@@ -81,6 +81,9 @@ module Yarrow
|
|
81
81
|
@container_const ||= Yarrow::Symbols.to_module_const([*module_prefix, container])
|
82
82
|
end
|
83
83
|
|
84
|
+
alias_method :collection, :container
|
85
|
+
alias_method :collection_const, :container_const
|
86
|
+
|
84
87
|
def entity_const
|
85
88
|
@entity_const ||= Yarrow::Symbols.to_module_const([*module_prefix, entity])
|
86
89
|
end
|
data/lib/yarrow/generator.rb
CHANGED
@@ -8,7 +8,8 @@ module Yarrow
|
|
8
8
|
path: Types::Instance.of(Pathname).accept(String),
|
9
9
|
any: Types::Any.new,
|
10
10
|
array: Types::List.of(Types::Any),
|
11
|
-
hash: Types::Instance.of(Hash)
|
11
|
+
hash: Types::Instance.of(Hash),
|
12
|
+
markdown: Types::Instance.of(Kramdown::Document).accept(String)
|
12
13
|
}
|
13
14
|
|
14
15
|
TEMPLATE_TYPES = {
|
@@ -28,13 +28,13 @@ module Yarrow
|
|
28
28
|
|
29
29
|
if missing_attrs.any?
|
30
30
|
missing_attrs.each do |name|
|
31
|
-
raise "wrong number of attributes" unless @attrs_spec[name].is_a?(Types::Any)
|
31
|
+
raise "#{missing_attrs} wrong number of attributes" unless @attrs_spec[name].is_a?(Types::Any)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
35
|
mismatching_attrs = input.keys.difference(@attrs_spec.keys)
|
36
36
|
|
37
|
-
raise "attribute does not exist" if mismatching_attrs.any?
|
37
|
+
raise "attribute #{mismatching_attrs} does not exist" if mismatching_attrs.any?
|
38
38
|
|
39
39
|
input.reduce({}) do |converted, (name, value)|
|
40
40
|
converted[name] = @attrs_spec[name].cast(value)
|
data/lib/yarrow/schema/entity.rb
CHANGED
data/lib/yarrow/schema/types.rb
CHANGED
@@ -31,8 +31,13 @@ module Yarrow
|
|
31
31
|
@accepts = {}
|
32
32
|
end
|
33
33
|
|
34
|
-
def accept(type, constructor=:new)
|
35
|
-
accepts[type] =
|
34
|
+
def accept(type, constructor=:new, options=nil)
|
35
|
+
accepts[type] = if options.nil?
|
36
|
+
[constructor]
|
37
|
+
else
|
38
|
+
[constructor, options]
|
39
|
+
end
|
40
|
+
|
36
41
|
self
|
37
42
|
end
|
38
43
|
|
@@ -41,8 +46,14 @@ module Yarrow
|
|
41
46
|
end
|
42
47
|
|
43
48
|
def coerce(input)
|
44
|
-
constructor = accepts[input.class]
|
45
|
-
|
49
|
+
constructor, options = accepts[input.class]
|
50
|
+
|
51
|
+
# TODO: should we clone all input so copy is stored rather than ref?
|
52
|
+
if options.nil?
|
53
|
+
unit.send(constructor, input)
|
54
|
+
else
|
55
|
+
unit.send(constructor, input, options.clone)
|
56
|
+
end
|
46
57
|
end
|
47
58
|
|
48
59
|
def check_instance_of!(input)
|
data/lib/yarrow/version.rb
CHANGED
data/lib/yarrow/web/document.rb
CHANGED
@@ -6,35 +6,75 @@ module Yarrow
|
|
6
6
|
# too clever which has burned this lib in the past).
|
7
7
|
def initialize(item, parent, is_index)
|
8
8
|
@item = item
|
9
|
+
@resource = item.props[:resource]
|
9
10
|
@parent = parent
|
10
11
|
@is_index = is_index
|
11
12
|
end
|
12
13
|
|
14
|
+
def resource
|
15
|
+
@resource
|
16
|
+
end
|
17
|
+
|
18
|
+
def index
|
19
|
+
_index = @item.out_e(:index)
|
20
|
+
unless _index.first.nil?
|
21
|
+
_index.first.to.props
|
22
|
+
else
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def index_body
|
28
|
+
@item.props[:index_body]
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: manage behaviour with and without current item
|
32
|
+
# TODO: link to manifest
|
33
|
+
def breadcrumbs
|
34
|
+
path = []
|
35
|
+
|
36
|
+
current_parent = @item.in(:collection)
|
37
|
+
|
38
|
+
while !current_parent.first.nil?
|
39
|
+
path << current_parent.first.props[:resource]
|
40
|
+
current_parent = current_parent.in(:collection)
|
41
|
+
end
|
42
|
+
|
43
|
+
path.reverse
|
44
|
+
end
|
45
|
+
|
13
46
|
def name
|
14
|
-
@
|
47
|
+
@resource.name
|
15
48
|
end
|
16
49
|
|
17
50
|
def title
|
18
|
-
@
|
51
|
+
@resource.title
|
19
52
|
end
|
20
53
|
|
21
54
|
def type
|
22
55
|
@item.props[:type]
|
23
56
|
end
|
24
57
|
|
58
|
+
def body
|
59
|
+
return @resource.body.to_html if @resource.respond_to?(:body)
|
60
|
+
""
|
61
|
+
end
|
62
|
+
|
25
63
|
def url
|
26
64
|
if @parent.nil?
|
27
65
|
"/"
|
28
66
|
else
|
29
|
-
segments = [@
|
67
|
+
segments = [@resource.name]
|
30
68
|
current = @parent
|
31
69
|
|
32
70
|
until current.in(:collection).first.nil? do
|
33
|
-
segments << current.props[:name
|
71
|
+
segments << current.props[:resource].name
|
34
72
|
current = current.in(:collection).first
|
35
73
|
end
|
36
74
|
|
37
|
-
"/"
|
75
|
+
suffix = @is_index ? "/" : ""
|
76
|
+
|
77
|
+
"/" + segments.reverse.join("/") + suffix
|
38
78
|
end
|
39
79
|
end
|
40
80
|
end
|
data/lib/yarrow/web/manifest.rb
CHANGED
@@ -12,7 +12,7 @@ module Yarrow
|
|
12
12
|
unless collection.props[:index_only]
|
13
13
|
collection.out(:item).each do |item|
|
14
14
|
#if item[:entity].status.to_sym == :published
|
15
|
-
if item.props[:name
|
15
|
+
if item.props[:resource].name == "index"
|
16
16
|
index = item
|
17
17
|
else
|
18
18
|
manifest.add_document(item_context(item))
|
@@ -25,7 +25,7 @@ module Yarrow
|
|
25
25
|
unless collection.props[:content_only]
|
26
26
|
if index
|
27
27
|
manifest.add_document(collection_index_context(collection, index))
|
28
|
-
else
|
28
|
+
else
|
29
29
|
manifest.add_document(collection_context(collection))
|
30
30
|
end
|
31
31
|
end
|
data/lib/yarrow.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yarrow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Rickerby
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|