cloudcannon-jekyll 2.3.4 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|