cloudcannon-jekyll 2.3.4 → 3.0.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/.gitignore +0 -1
- data/.rubocop.yml +24 -20
- data/HISTORY.md +8 -0
- data/README.md +160 -23
- data/cloudcannon-jekyll.gemspec +16 -18
- data/lib/cloudcannon-jekyll/config.rb +146 -0
- data/lib/cloudcannon-jekyll/generator.rb +20 -248
- data/lib/cloudcannon-jekyll/generators/collections.rb +267 -0
- data/lib/cloudcannon-jekyll/generators/data.rb +34 -0
- data/lib/cloudcannon-jekyll/generators/info.rb +92 -0
- data/lib/cloudcannon-jekyll/generators/paths.rb +18 -0
- data/lib/cloudcannon-jekyll/logger.rb +12 -0
- data/lib/cloudcannon-jekyll/readers/data-reader.rb +3 -3
- data/lib/cloudcannon-jekyll/readers/old-data-reader.rb +11 -8
- data/lib/cloudcannon-jekyll/{reader.rb → readers/reader.rb} +11 -11
- data/lib/cloudcannon-jekyll/{configuration.rb → setup.rb} +7 -4
- data/lib/cloudcannon-jekyll/version.rb +1 -1
- data/lib/cloudcannon-jekyll.rb +8 -13
- data/script/lint +5 -0
- data/script/test +0 -1
- data/script/{ci-smoke-test → test-all-versions} +2 -4
- metadata +12 -46
- data/.travis.yml +0 -19
- data/lib/cloudcannon-jekyll/_cloudcannon/info-2.x.json +0 -83
- data/lib/cloudcannon-jekyll/_cloudcannon/info-3.0-4.x.json +0 -83
- data/lib/cloudcannon-jekyll/_cloudcannon/info.json +0 -86
- data/lib/cloudcannon-jekyll/jsonify-filter.rb +0 -214
- data/lib/cloudcannon-jekyll/page-without-a-file.rb +0 -10
- data/script/cibuild +0 -6
@@ -1,281 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
3
|
+
require 'jekyll'
|
4
|
+
require 'json'
|
5
|
+
require 'fileutils'
|
6
|
+
require_relative 'logger'
|
7
|
+
require_relative 'config'
|
8
|
+
require_relative 'generators/info'
|
6
9
|
|
7
10
|
module CloudCannonJekyll
|
8
|
-
# Generates JSON
|
11
|
+
# Generates JSON file with build information
|
9
12
|
class Generator < Jekyll::Generator
|
10
|
-
# Override the Jekyll::Plugin spaceship to push our plugin to the very end
|
11
13
|
priority :lowest
|
14
|
+
|
15
|
+
# Override the Jekyll::Plugin spaceship to run at the end
|
12
16
|
def self.<=>(*)
|
13
17
|
1
|
14
18
|
end
|
15
19
|
|
16
|
-
# rubocop:disable Metrics/MethodLength
|
17
20
|
def generate(site)
|
18
|
-
|
19
|
-
|
21
|
+
Logger.info "⭐️ Starting #{'cloudcannon-jekyll'.blue}"
|
20
22
|
@site = site
|
21
|
-
|
22
|
-
|
23
|
-
migrate_legacy_config
|
24
|
-
pages = generate_pages
|
25
|
-
collections_config = generate_collections_config(pages)
|
26
|
-
drafts = add_blogging_config(collections_config)
|
27
|
-
add_collection_paths(collections_config)
|
28
|
-
|
29
|
-
collections = generate_collections(collections_config, pages, drafts)
|
30
|
-
remove_empty_collection_config(collections_config, collections)
|
31
|
-
|
32
|
-
add_data_config(collections_config)
|
33
|
-
data = generate_data
|
34
|
-
|
35
|
-
generate_file("info", @site.site_payload.merge({
|
36
|
-
"pwd" => Dir.pwd,
|
37
|
-
"version" => "0.0.2",
|
38
|
-
"gem_version" => CloudCannonJekyll::VERSION,
|
39
|
-
"config" => @site.config,
|
40
|
-
"collections_config" => collections_config,
|
41
|
-
"collections" => collections,
|
42
|
-
"data" => data,
|
43
|
-
}))
|
44
|
-
end
|
45
|
-
# rubocop:enable Metrics/MethodLength
|
46
|
-
|
47
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
48
|
-
def generate_collections_config(pages)
|
49
|
-
collections = @site.config["collections"]&.dup || {}
|
50
|
-
collections_config = @site.config.dig("cloudcannon", "collections")&.dup || {}
|
51
|
-
|
52
|
-
collections.each_key do |key|
|
53
|
-
# Workaround for empty collection configurations
|
54
|
-
defaults = collections[key] || { "output" => false }
|
55
|
-
collections_config[key] = (collections_config[key] || {}).merge(defaults)
|
56
|
-
end
|
57
|
-
|
58
|
-
unless pages.empty? || collections.key?("pages")
|
59
|
-
pages_defaults = {
|
60
|
-
"output" => true,
|
61
|
-
"filter" => "strict",
|
62
|
-
"path" => "",
|
63
|
-
}
|
64
|
-
|
65
|
-
collections_config["pages"] = pages_defaults.merge(collections_config["pages"] || {})
|
66
|
-
end
|
67
|
-
|
68
|
-
collections_config
|
69
|
-
end
|
70
|
-
|
71
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
72
|
-
def generate_collections(collections_config, pages, drafts)
|
73
|
-
split_posts = group_by_category_folder(all_posts, "posts")
|
74
|
-
split_drafts = group_by_category_folder(drafts, "drafts")
|
75
|
-
|
76
|
-
collections = {}
|
77
|
-
collections_config.each_key do |key|
|
78
|
-
collections[key] = if key == "posts" || key.end_with?("/posts")
|
79
|
-
split_posts[key]
|
80
|
-
elsif key == "drafts" || key.end_with?("/drafts")
|
81
|
-
split_drafts[key]
|
82
|
-
else
|
83
|
-
@site.collections[key]&.docs
|
84
|
-
end
|
85
|
-
|
86
|
-
collections[key] ||= []
|
87
|
-
end
|
88
|
-
|
89
|
-
has_collection_pages = collections.key?("pages") && !collections["pages"].empty?
|
90
|
-
collections["pages"] = pages unless pages.empty? || has_collection_pages
|
91
|
-
collections
|
92
|
-
end
|
93
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
94
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
95
|
-
|
96
|
-
def generate_data
|
97
|
-
cc_data = @site.config.dig("cloudcannon", "data")
|
98
|
-
data = if cc_data == true
|
99
|
-
@site.data&.dup
|
100
|
-
elsif cc_data&.is_a?(Hash)
|
101
|
-
@site.data&.select { |key, _| cc_data.key?(key) }
|
102
|
-
end
|
103
|
-
|
104
|
-
data ||= {}
|
105
|
-
data["categories"] ||= @site.categories.keys
|
106
|
-
data["tags"] ||= @site.tags.keys
|
107
|
-
|
108
|
-
data.each_key do |key|
|
109
|
-
log "💾 Processed #{key.bold} data set"
|
110
|
-
end
|
111
|
-
|
112
|
-
data
|
113
|
-
end
|
114
|
-
|
115
|
-
def generate_pages
|
116
|
-
html_pages = @site.pages.select do |page|
|
117
|
-
page.html? || page.url.end_with?("/")
|
118
|
-
end
|
119
|
-
|
120
|
-
static_pages = @site.static_files.select do |static_page|
|
121
|
-
JsonifyFilter::STATIC_EXTENSIONS.include?(static_page.extname)
|
122
|
-
end
|
123
|
-
|
124
|
-
html_pages + static_pages
|
125
|
-
end
|
126
|
-
|
127
|
-
def collections_dir
|
128
|
-
return "" if Jekyll::VERSION.start_with? "2."
|
129
|
-
|
130
|
-
@site.config["collections_dir"] || ""
|
131
|
-
end
|
132
|
-
|
133
|
-
def data_dir
|
134
|
-
@site.config["data_dir"] || "_data"
|
135
|
-
end
|
136
|
-
|
137
|
-
def all_posts
|
138
|
-
posts = @site.posts || @site.collections["posts"]
|
139
|
-
posts.class.method_defined?(:docs) ? posts.docs : posts
|
140
|
-
end
|
141
|
-
|
142
|
-
def group_by_category_folder(collection, key)
|
143
|
-
split_path = "/_#{key}/"
|
144
|
-
collection.group_by do |doc|
|
145
|
-
parts = doc.relative_path.split(split_path)
|
146
|
-
if parts.length > 1
|
147
|
-
"#{parts.first}/#{key}".sub(%r!^\/+!, "")
|
148
|
-
else
|
149
|
-
key
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def add_category_folder_config(collections_config, posts_config = {})
|
155
|
-
seen = {}
|
156
|
-
|
157
|
-
all_posts.map do |post|
|
158
|
-
parts = post.relative_path.split("/_posts/")
|
159
|
-
path = parts.first
|
160
|
-
|
161
|
-
# Ignore unless it's an unseen category folder post
|
162
|
-
next if parts.length < 2 || path.empty? || seen[path]
|
163
|
-
|
164
|
-
# Could check this to ensure raw files exist since posts can be generated without files
|
165
|
-
# next if @reader.read_posts(parts[0]).empty?
|
166
|
-
|
167
|
-
seen[path] = true
|
168
|
-
folder = path.sub(%r!^\/+!, "")
|
169
|
-
collections_path = "#{collections_dir}/#{folder}".gsub(%r!\/+!, "/").sub(%r!^\/+!, "")
|
170
|
-
|
171
|
-
collections_config["#{folder}/posts"] = posts_config.merge({
|
172
|
-
"path" => "#{collections_path}/_posts",
|
173
|
-
})
|
174
|
-
|
175
|
-
# Adding the category draft config like this isn't ideal, since you could have drafts
|
176
|
-
# without posts, but it's a decent trade off vs looking for _drafts folders
|
177
|
-
collections_config["#{folder}/drafts"] = posts_config.merge({
|
178
|
-
"path" => "#{collections_path}/_drafts",
|
179
|
-
})
|
180
|
-
|
181
|
-
path
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def remove_empty_collection_config(collections_config, collections)
|
186
|
-
cc_collections = @site.config.dig("cloudcannon", "collections") || {}
|
187
|
-
|
188
|
-
collections_config.each_key do |key|
|
189
|
-
if collections[key].empty? && !cc_collections.key?(key)
|
190
|
-
log "📂 #{"Ignored".yellow} #{key.bold} collection"
|
191
|
-
collections_config.delete(key)
|
192
|
-
else
|
193
|
-
log "📁 Processed #{key.bold} collection with #{collections[key]&.length || 0} files"
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def migrate_legacy_config
|
199
|
-
add_legacy_explore_groups
|
200
|
-
end
|
201
|
-
|
202
|
-
# Support for the deprecated _explore configuration
|
203
|
-
def add_legacy_explore_groups
|
204
|
-
unless @site.config.key?("_collection_groups")
|
205
|
-
@site.config["_collection_groups"] = @site.config.dig("_explore", "groups")&.dup
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
# Add data to collections config if raw data files exist
|
210
|
-
def add_data_config(collections_config)
|
211
|
-
data_files = @reader.read_data(data_dir)
|
212
|
-
collections_config["data"] = { "path" => data_dir } if data_files&.keys&.any?
|
213
|
-
end
|
214
|
-
|
215
|
-
# Add posts/drafts to collections config
|
216
|
-
def add_blogging_config(collections_config)
|
217
|
-
collections_config["posts"] = { "output" => true } if Jekyll::VERSION.start_with? "2."
|
218
|
-
drafts = @reader.read_drafts(collections_dir)
|
219
|
-
|
220
|
-
if drafts.any? && !collections_config.key?("drafts")
|
221
|
-
collections_config["drafts"] = { "output" => !!@site.show_drafts }
|
222
|
-
end
|
223
|
-
|
224
|
-
folders = add_category_folder_config(collections_config, collections_config["posts"])
|
225
|
-
folders.compact.each do |folder|
|
226
|
-
drafts += @reader.read_drafts(folder)
|
227
|
-
end
|
228
|
-
|
229
|
-
drafts
|
230
|
-
end
|
231
|
-
|
232
|
-
# Add path to each collection config
|
233
|
-
def add_collection_paths(collections_config)
|
234
|
-
collections_config.each do |key, collection|
|
235
|
-
collection["path"] ||= File.join(collections_dir, "_#{key}").sub(%r!^\/+!, "")
|
236
|
-
end
|
23
|
+
config = Config.new(site)
|
24
|
+
generate_file('info', Info.new.generate_info(site, config.read))
|
237
25
|
end
|
238
26
|
|
239
27
|
def generate_file(filename, data)
|
240
28
|
dest = destination_path(filename)
|
241
29
|
FileUtils.mkdir_p(File.dirname(dest))
|
242
|
-
File.open(dest,
|
30
|
+
File.open(dest, 'w') { |file| file.write(file_content(data)) }
|
243
31
|
@site.keep_files ||= []
|
244
32
|
@site.keep_files << path(filename)
|
245
|
-
|
246
|
-
end
|
247
|
-
|
248
|
-
def log(str)
|
249
|
-
Jekyll.logger.info("CloudCannon:", str)
|
250
|
-
end
|
251
|
-
|
252
|
-
def version_path_suffix
|
253
|
-
return "-2.x" if Jekyll::VERSION.start_with? "2."
|
254
|
-
return "-3.0-4.x" if Jekyll::VERSION.match? %r!3\.[0-4]\.!
|
255
|
-
|
256
|
-
""
|
33
|
+
Logger.info "🏁 Generated #{path(filename).bold} #{'successfully'.green}"
|
257
34
|
end
|
258
35
|
|
259
|
-
def path(filename
|
260
|
-
"_cloudcannon/#{filename}
|
36
|
+
def path(filename)
|
37
|
+
"_cloudcannon/#{filename}.json"
|
261
38
|
end
|
262
39
|
|
263
40
|
def source_path(filename)
|
264
|
-
|
41
|
+
file_path = path(filename)
|
42
|
+
File.expand_path(file_path, File.dirname(__FILE__))
|
265
43
|
end
|
266
44
|
|
267
45
|
def destination_path(filename)
|
268
46
|
Jekyll.sanitized_path(@site.dest, path(filename))
|
269
47
|
end
|
270
48
|
|
271
|
-
def file_content(
|
272
|
-
|
273
|
-
page.content = File.read(source_path(filename))
|
274
|
-
page.data["layout"] = nil
|
275
|
-
page.data["sitemap"] = false
|
276
|
-
page.data["permalink"] = "/#{path(filename)}"
|
277
|
-
page.render({}, data)
|
278
|
-
page.output
|
49
|
+
def file_content(data)
|
50
|
+
JSON.pretty_generate(data)
|
279
51
|
end
|
280
52
|
end
|
281
53
|
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative '../readers/reader'
|
5
|
+
require_relative '../logger'
|
6
|
+
require_relative 'paths'
|
7
|
+
|
8
|
+
module CloudCannonJekyll
|
9
|
+
STATIC_EXTENSIONS = ['.html', '.htm'].freeze
|
10
|
+
IS_JEKYLL_2_X_X = Jekyll::VERSION.start_with?('2.').freeze
|
11
|
+
IS_JEKYLL_3_04_X = Jekyll::VERSION.match?(/3\.[0-4]\./).freeze
|
12
|
+
|
13
|
+
# Helper functions for generating collection configuration and summaries
|
14
|
+
class Collections
|
15
|
+
def initialize(site, config)
|
16
|
+
@site = site
|
17
|
+
@config = config
|
18
|
+
@reader = Reader.new(site)
|
19
|
+
@collections_dir = Paths.collections_dir(site)
|
20
|
+
@data_dir = Paths.data_dir(site)
|
21
|
+
@split_posts = group_by_category_folder(all_posts, 'posts')
|
22
|
+
@split_drafts = group_by_category_folder(all_drafts, 'drafts')
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_collections_config
|
26
|
+
collections = @site.config['collections'] || {}
|
27
|
+
collections_config = @config['collections_config']&.dup || {}
|
28
|
+
|
29
|
+
return collections_config if @config['collections_config_override']
|
30
|
+
|
31
|
+
if collections.is_a?(Array)
|
32
|
+
collections = collections.each_with_object({}) { |key, memo| memo[key] = {} }
|
33
|
+
end
|
34
|
+
|
35
|
+
defaults = {
|
36
|
+
'data' => {
|
37
|
+
'path' => @data_dir,
|
38
|
+
'output' => false
|
39
|
+
},
|
40
|
+
'posts' => {
|
41
|
+
'output' => true
|
42
|
+
},
|
43
|
+
'drafts' => {
|
44
|
+
'output' => !!@site.show_drafts
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
unless collections.key?('pages') && !collections['pages'].empty?
|
49
|
+
defaults['pages'] = {
|
50
|
+
'path' => '',
|
51
|
+
'output' => true,
|
52
|
+
'filter' => 'strict'
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
collection_keys = (defaults.keys + collections.keys).uniq
|
57
|
+
|
58
|
+
collection_keys.each do |key|
|
59
|
+
processed = (defaults[key] || {})
|
60
|
+
.merge(collections[key] || {})
|
61
|
+
.merge(collections_config[key] || {})
|
62
|
+
|
63
|
+
processed['output'] ||= false
|
64
|
+
processed['auto_discovered'] = !collections_config.key?(key)
|
65
|
+
processed['path'] ||= File.join(@collections_dir, "_#{key}")
|
66
|
+
processed['path'] = processed['path'].sub(%r{^/+}, '')
|
67
|
+
|
68
|
+
Config.rename_legacy_collection_config_keys(processed)
|
69
|
+
|
70
|
+
collections_config[key] = processed
|
71
|
+
end
|
72
|
+
|
73
|
+
@split_posts.each_key do |key|
|
74
|
+
posts_path = @split_posts[key]&.first&.relative_path&.sub(%r{(^|/)_posts.*}, '\1_posts')
|
75
|
+
next unless posts_path
|
76
|
+
|
77
|
+
defaults = {
|
78
|
+
'auto_discovered' => !collections_config.key?(key),
|
79
|
+
'path' => File.join(@collections_dir, posts_path).sub(%r{^/+}, ''),
|
80
|
+
'output' => true
|
81
|
+
}
|
82
|
+
|
83
|
+
collections_config[key] = defaults.merge(collections_config[key] || {})
|
84
|
+
end
|
85
|
+
|
86
|
+
@split_drafts.each_key do |key|
|
87
|
+
drafts_path = @split_drafts[key]&.first&.relative_path&.sub(%r{(^|/)_drafts.*}, '\1_drafts')
|
88
|
+
next unless drafts_path
|
89
|
+
|
90
|
+
defaults = {
|
91
|
+
'auto_discovered' => !collections_config.key?(key),
|
92
|
+
'path' => File.join(@collections_dir, drafts_path).sub(%r{^/+}, ''),
|
93
|
+
'output' => !!@site.show_drafts
|
94
|
+
}
|
95
|
+
|
96
|
+
collections_config[key] = defaults.merge(collections_config[key] || {})
|
97
|
+
end
|
98
|
+
|
99
|
+
collections_config
|
100
|
+
end
|
101
|
+
|
102
|
+
def drafts_paths
|
103
|
+
paths = @split_posts.keys.map do |key|
|
104
|
+
File.join('/', @collections_dir, key.sub(/posts$/, '_drafts'))
|
105
|
+
end
|
106
|
+
|
107
|
+
paths.empty? ? [File.join('/', @collections_dir, '_drafts')] : paths
|
108
|
+
end
|
109
|
+
|
110
|
+
def generate_collections(collections_config)
|
111
|
+
collections = {}
|
112
|
+
|
113
|
+
collections_config.each_key do |key|
|
114
|
+
next if key == 'data'
|
115
|
+
|
116
|
+
collections[key] = if key == 'posts' || key.end_with?('/posts')
|
117
|
+
@split_posts[key]
|
118
|
+
elsif key == 'drafts' || key.end_with?('/drafts')
|
119
|
+
@split_drafts[key]
|
120
|
+
else
|
121
|
+
@site.collections[key]&.docs
|
122
|
+
end
|
123
|
+
|
124
|
+
collections[key] ||= []
|
125
|
+
collections[key] = collections[key].map do |doc|
|
126
|
+
document_to_json(doc, key)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if collections.key?('pages') && collections['pages'].empty?
|
131
|
+
collections['pages'] = all_pages.map do |doc|
|
132
|
+
document_to_json(doc, 'pages')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
collections
|
137
|
+
end
|
138
|
+
|
139
|
+
def remove_empty_collection_config(collections_config, collections)
|
140
|
+
collections_config.each do |key, collection_config|
|
141
|
+
should_delete = if key == 'data'
|
142
|
+
!data_files?
|
143
|
+
else
|
144
|
+
collections[key].empty? && collection_config['auto_discovered']
|
145
|
+
end
|
146
|
+
|
147
|
+
if should_delete
|
148
|
+
Logger.info "📂 #{'Ignored'.yellow} #{key.bold} collection"
|
149
|
+
collections_config.delete(key)
|
150
|
+
else
|
151
|
+
count = collections[key]&.length || 0
|
152
|
+
Logger.info "📁 Processed #{key.bold} collection with #{count} files"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def document_type(doc)
|
158
|
+
if IS_JEKYLL_2_X_X && (doc.instance_of?(Jekyll::Post) || doc.instance_of?(Jekyll::Draft))
|
159
|
+
:posts
|
160
|
+
elsif doc.respond_to? :type
|
161
|
+
doc.type
|
162
|
+
elsif doc.respond_to?(:collection)
|
163
|
+
doc.collection.label.to_sym
|
164
|
+
elsif doc.instance_of?(Jekyll::Page)
|
165
|
+
:pages
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def legacy_document_data(doc)
|
170
|
+
data = doc.data.merge(
|
171
|
+
{
|
172
|
+
categories: doc.categories,
|
173
|
+
tags: doc.tags,
|
174
|
+
date: doc.date
|
175
|
+
}
|
176
|
+
)
|
177
|
+
|
178
|
+
data['slug'] = doc.slug if doc.respond_to?(:slug)
|
179
|
+
data
|
180
|
+
end
|
181
|
+
|
182
|
+
def legacy_doc?(doc)
|
183
|
+
(IS_JEKYLL_3_04_X && doc.instance_of?(Jekyll::Document) && doc.collection.label == 'posts') ||
|
184
|
+
(IS_JEKYLL_2_X_X && (doc.instance_of?(Jekyll::Draft) || doc.instance_of?(Jekyll::Post)))
|
185
|
+
end
|
186
|
+
|
187
|
+
def document_data(doc)
|
188
|
+
data = if legacy_doc?(doc)
|
189
|
+
legacy_document_data(doc)
|
190
|
+
elsif doc.respond_to?(:data)
|
191
|
+
doc.data
|
192
|
+
else
|
193
|
+
{}
|
194
|
+
end
|
195
|
+
|
196
|
+
defaults = @site.frontmatter_defaults.all(doc.relative_path, document_type(doc))
|
197
|
+
defaults.merge(data)
|
198
|
+
end
|
199
|
+
|
200
|
+
def document_url(doc)
|
201
|
+
doc.respond_to?(:url) ? doc.url : doc.relative_path
|
202
|
+
end
|
203
|
+
|
204
|
+
def document_path(doc)
|
205
|
+
path = if doc.respond_to?(:collection) && doc.collection
|
206
|
+
File.join(@collections_dir, doc.relative_path)
|
207
|
+
else
|
208
|
+
doc.relative_path
|
209
|
+
end
|
210
|
+
|
211
|
+
path.sub(%r{^/+}, '')
|
212
|
+
end
|
213
|
+
|
214
|
+
def document_to_json(doc, collection)
|
215
|
+
base = document_data(doc).merge(
|
216
|
+
{
|
217
|
+
'path' => document_path(doc),
|
218
|
+
'url' => document_url(doc),
|
219
|
+
'collection' => collection
|
220
|
+
}
|
221
|
+
)
|
222
|
+
|
223
|
+
base['id'] = doc.id if doc.respond_to? :id
|
224
|
+
base
|
225
|
+
end
|
226
|
+
|
227
|
+
def all_posts
|
228
|
+
posts = @site.posts || @site.collections['posts']
|
229
|
+
posts.class.method_defined?(:docs) ? posts.docs : posts
|
230
|
+
end
|
231
|
+
|
232
|
+
def all_drafts
|
233
|
+
drafts_paths.reduce([]) do |drafts, drafts_path|
|
234
|
+
base_path = drafts_path.gsub(%r{(^|/)_drafts}, '')
|
235
|
+
drafts + @reader.read_drafts(base_path)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def all_pages
|
240
|
+
html_pages = @site.pages.select do |page|
|
241
|
+
page.html? || page.url.end_with?('/')
|
242
|
+
end
|
243
|
+
|
244
|
+
static_pages = @site.static_files.select do |static_page|
|
245
|
+
STATIC_EXTENSIONS.include?(static_page.extname)
|
246
|
+
end
|
247
|
+
|
248
|
+
html_pages + static_pages
|
249
|
+
end
|
250
|
+
|
251
|
+
def data_files?
|
252
|
+
@reader.read_data(@data_dir)&.keys&.any?
|
253
|
+
end
|
254
|
+
|
255
|
+
def group_by_category_folder(collection, key)
|
256
|
+
split_path = "/_#{key}/"
|
257
|
+
collection.group_by do |doc|
|
258
|
+
parts = doc.relative_path.split(split_path)
|
259
|
+
if parts.length > 1
|
260
|
+
File.join(parts.first, key).sub(%r{^/+}, '')
|
261
|
+
else
|
262
|
+
key
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../logger'
|
4
|
+
require_relative 'paths'
|
5
|
+
|
6
|
+
module CloudCannonJekyll
|
7
|
+
# Generator functions for site data
|
8
|
+
class Data
|
9
|
+
def initialize(site, config)
|
10
|
+
@site = site
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_data
|
15
|
+
data_config = @config['data_config']
|
16
|
+
data = case data_config
|
17
|
+
when true
|
18
|
+
@site.data&.dup
|
19
|
+
when Hash
|
20
|
+
@site.data&.select { |key, _| data_config.key?(key) && data_config[key] }
|
21
|
+
end
|
22
|
+
|
23
|
+
data ||= {}
|
24
|
+
data['categories'] ||= @site.categories.keys
|
25
|
+
data['tags'] ||= @site.tags.keys
|
26
|
+
|
27
|
+
data.each_key do |key|
|
28
|
+
Logger.info "💾 Processed #{key.bold} data set"
|
29
|
+
end
|
30
|
+
|
31
|
+
data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jekyll'
|
4
|
+
require 'fileutils'
|
5
|
+
require_relative '../logger'
|
6
|
+
require_relative 'collections'
|
7
|
+
require_relative 'data'
|
8
|
+
require_relative 'paths'
|
9
|
+
|
10
|
+
module CloudCannonJekyll
|
11
|
+
# Generates a summary of a Jekyll site
|
12
|
+
class Info
|
13
|
+
def generate_info(site, config)
|
14
|
+
@site = site
|
15
|
+
@site_config = site.config
|
16
|
+
@config = config
|
17
|
+
@data_dir = Paths.data_dir(site)
|
18
|
+
@collections_dir = Paths.collections_dir(site)
|
19
|
+
|
20
|
+
collections_generator = Collections.new(site, config)
|
21
|
+
collections_config = collections_generator.generate_collections_config
|
22
|
+
collections = collections_generator.generate_collections(collections_config)
|
23
|
+
collections_generator.remove_empty_collection_config(collections_config, collections)
|
24
|
+
|
25
|
+
{
|
26
|
+
time: site.time.iso8601,
|
27
|
+
version: '0.0.3',
|
28
|
+
cloudcannon: generate_cloudcannon,
|
29
|
+
generator: generate_generator,
|
30
|
+
paths: generate_paths,
|
31
|
+
collections_config: collections_config,
|
32
|
+
collection_groups: @config['collection_groups'],
|
33
|
+
collections: collections,
|
34
|
+
data: generate_data,
|
35
|
+
source: @config['source'] || '',
|
36
|
+
timezone: @config['timezone'],
|
37
|
+
base_url: @config['base_url'] || '',
|
38
|
+
editor: @config['editor'],
|
39
|
+
source_editor: @config['source_editor'],
|
40
|
+
_inputs: @config['_inputs'],
|
41
|
+
_editables: @config['_editables'],
|
42
|
+
_select_data: @config['_select_data'],
|
43
|
+
_structures: @config['_structures'],
|
44
|
+
|
45
|
+
# Deprecated
|
46
|
+
_array_structures: @config['_array_structures'],
|
47
|
+
_comments: @config['_comments'],
|
48
|
+
_enabled_editors: @config['_enabled_editors'],
|
49
|
+
_instance_values: @config['_instance_values'],
|
50
|
+
_options: @config['_options'],
|
51
|
+
|
52
|
+
# Jekyll-only
|
53
|
+
defaults: @site_config['defaults']
|
54
|
+
}.compact
|
55
|
+
end
|
56
|
+
|
57
|
+
def generate_data
|
58
|
+
data_generator = Data.new(@site, @config)
|
59
|
+
data_generator.generate_data
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_cloudcannon
|
63
|
+
{
|
64
|
+
name: 'cloudcannon-jekyll',
|
65
|
+
version: CloudCannonJekyll::VERSION
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def generate_paths
|
70
|
+
{
|
71
|
+
static: '',
|
72
|
+
uploads: @config.dig('paths', 'uploads') || 'uploads',
|
73
|
+
data: @data_dir,
|
74
|
+
collections: @collections_dir,
|
75
|
+
layouts: @site_config['layouts_dir'] || '_layouts'
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate_generator
|
80
|
+
{
|
81
|
+
name: 'jekyll',
|
82
|
+
version: Jekyll::VERSION,
|
83
|
+
environment: Jekyll.env,
|
84
|
+
metadata: {
|
85
|
+
markdown: @site_config['markdown'],
|
86
|
+
kramdown: @site_config['kramdown'],
|
87
|
+
commonmark: @site_config['commonmark']
|
88
|
+
}
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|