jekyll 3.9.1 → 4.0.0.pre.alpha1
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/.rubocop.yml +27 -50
- data/LICENSE +1 -1
- data/README.markdown +46 -17
- data/lib/blank_template/_config.yml +3 -0
- data/lib/blank_template/_layouts/default.html +12 -0
- data/lib/blank_template/_sass/main.scss +9 -0
- data/lib/blank_template/assets/css/main.scss +4 -0
- data/lib/blank_template/index.md +8 -0
- data/lib/jekyll.rb +5 -0
- data/lib/jekyll/cache.rb +183 -0
- data/lib/jekyll/cleaner.rb +2 -1
- data/lib/jekyll/collection.rb +78 -8
- data/lib/jekyll/command.rb +31 -6
- data/lib/jekyll/commands/build.rb +11 -20
- data/lib/jekyll/commands/clean.rb +2 -0
- data/lib/jekyll/commands/doctor.rb +15 -8
- data/lib/jekyll/commands/help.rb +1 -1
- data/lib/jekyll/commands/new.rb +37 -39
- data/lib/jekyll/commands/new_theme.rb +30 -28
- data/lib/jekyll/commands/serve.rb +46 -80
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
- data/lib/jekyll/commands/serve/servlet.rb +9 -11
- data/lib/jekyll/configuration.rb +26 -26
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +1 -10
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +11 -13
- data/lib/jekyll/deprecator.rb +1 -3
- data/lib/jekyll/document.rb +44 -41
- data/lib/jekyll/drops/collection_drop.rb +2 -3
- data/lib/jekyll/drops/document_drop.rb +2 -1
- data/lib/jekyll/drops/drop.rb +3 -6
- data/lib/jekyll/drops/excerpt_drop.rb +4 -0
- data/lib/jekyll/drops/site_drop.rb +4 -13
- data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
- data/lib/jekyll/drops/url_drop.rb +1 -0
- data/lib/jekyll/entry_filter.rb +2 -1
- data/lib/jekyll/excerpt.rb +45 -34
- data/lib/jekyll/external.rb +10 -5
- data/lib/jekyll/filters.rb +72 -31
- data/lib/jekyll/filters/date_filters.rb +6 -3
- data/lib/jekyll/filters/grouping_filters.rb +1 -2
- data/lib/jekyll/filters/url_filters.rb +6 -1
- data/lib/jekyll/frontmatter_defaults.rb +35 -19
- data/lib/jekyll/hooks.rb +2 -3
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer.rb +13 -1
- data/lib/jekyll/liquid_renderer/file.rb +14 -3
- data/lib/jekyll/liquid_renderer/table.rb +67 -65
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/page.rb +10 -11
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +2 -0
- data/lib/jekyll/reader.rb +38 -8
- data/lib/jekyll/readers/data_reader.rb +7 -9
- data/lib/jekyll/readers/layout_reader.rb +2 -12
- data/lib/jekyll/readers/post_reader.rb +29 -17
- data/lib/jekyll/readers/static_file_reader.rb +1 -1
- data/lib/jekyll/readers/theme_assets_reader.rb +7 -5
- data/lib/jekyll/regenerator.rb +4 -12
- data/lib/jekyll/renderer.rb +14 -25
- data/lib/jekyll/site.rb +78 -34
- data/lib/jekyll/static_file.rb +47 -11
- data/lib/jekyll/stevenson.rb +2 -3
- data/lib/jekyll/tags/highlight.rb +22 -52
- data/lib/jekyll/tags/include.rb +22 -38
- data/lib/jekyll/tags/link.rb +11 -7
- data/lib/jekyll/tags/post_url.rb +17 -16
- data/lib/jekyll/theme.rb +12 -23
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +3 -2
- data/lib/jekyll/utils.rb +5 -4
- data/lib/jekyll/utils/ansi.rb +1 -1
- data/lib/jekyll/utils/exec.rb +0 -1
- data/lib/jekyll/utils/internet.rb +2 -4
- data/lib/jekyll/utils/platforms.rb +8 -8
- data/lib/jekyll/utils/thread_event.rb +1 -5
- data/lib/jekyll/utils/win_tz.rb +1 -1
- data/lib/jekyll/version.rb +1 -1
- data/lib/site_template/.gitignore +2 -0
- data/lib/site_template/404.html +1 -0
- data/lib/site_template/_config.yml +17 -5
- data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
- data/lib/site_template/{about.md → about.markdown} +0 -0
- data/lib/site_template/{index.md → index.markdown} +0 -0
- data/lib/theme_template/gitignore.erb +1 -0
- data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -0
- metadata +85 -51
- data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
- data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
- data/lib/jekyll/utils/rouge.rb +0 -22
data/lib/jekyll/renderer.rb
CHANGED
@@ -9,6 +9,7 @@ module Jekyll
|
|
9
9
|
@site = site
|
10
10
|
@document = document
|
11
11
|
@payload = site_payload
|
12
|
+
@layouts = nil
|
12
13
|
end
|
13
14
|
|
14
15
|
# Fetches the payload used in Liquid rendering.
|
@@ -101,8 +102,8 @@ module Jekyll
|
|
101
102
|
converter.convert output
|
102
103
|
rescue StandardError => e
|
103
104
|
Jekyll.logger.error "Conversion error:",
|
104
|
-
|
105
|
-
|
105
|
+
"#{converter.class} encountered an error while "\
|
106
|
+
"converting '#{document.relative_path}':"
|
106
107
|
Jekyll.logger.error("", e.to_s)
|
107
108
|
raise e
|
108
109
|
end
|
@@ -121,13 +122,13 @@ module Jekyll
|
|
121
122
|
template = site.liquid_renderer.file(path).parse(content)
|
122
123
|
template.warnings.each do |e|
|
123
124
|
Jekyll.logger.warn "Liquid Warning:",
|
124
|
-
|
125
|
+
LiquidRenderer.format_error(e, path || document.relative_path)
|
125
126
|
end
|
126
127
|
template.render!(payload, info)
|
127
128
|
# rubocop: disable RescueException
|
128
129
|
rescue Exception => e
|
129
130
|
Jekyll.logger.error "Liquid Exception:",
|
130
|
-
|
131
|
+
LiquidRenderer.format_error(e, path || document.relative_path)
|
131
132
|
raise e
|
132
133
|
end
|
133
134
|
# rubocop: enable RescueException
|
@@ -158,19 +159,20 @@ module Jekyll
|
|
158
159
|
output = render_layout(output, layout, info)
|
159
160
|
add_regenerator_dependencies(layout)
|
160
161
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
162
|
+
next unless (layout = site.layouts[layout.data["layout"]])
|
163
|
+
break if used.include?(layout)
|
164
|
+
|
165
|
+
used << layout
|
165
166
|
end
|
166
167
|
output
|
167
168
|
end
|
168
169
|
|
170
|
+
private
|
171
|
+
|
169
172
|
# Checks if the layout specified in the document actually exists
|
170
173
|
#
|
171
174
|
# layout - the layout to check
|
172
175
|
# Returns nothing
|
173
|
-
private
|
174
176
|
def validate_layout(layout)
|
175
177
|
if invalid_layout?(layout)
|
176
178
|
Jekyll.logger.warn(
|
@@ -187,7 +189,6 @@ module Jekyll
|
|
187
189
|
# Render layout content into document.output
|
188
190
|
#
|
189
191
|
# Returns String rendered content
|
190
|
-
private
|
191
192
|
def render_layout(output, layout, info)
|
192
193
|
payload["content"] = output
|
193
194
|
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
|
@@ -200,9 +201,9 @@ module Jekyll
|
|
200
201
|
)
|
201
202
|
end
|
202
203
|
|
203
|
-
private
|
204
204
|
def add_regenerator_dependencies(layout)
|
205
205
|
return unless document.write?
|
206
|
+
|
206
207
|
site.regenerator.add_dependency(
|
207
208
|
site.in_source_dir(document.path),
|
208
209
|
layout.path
|
@@ -212,18 +213,14 @@ module Jekyll
|
|
212
213
|
# Set page content to payload and assign pager if document has one.
|
213
214
|
#
|
214
215
|
# Returns nothing
|
215
|
-
private
|
216
216
|
def assign_pages!
|
217
217
|
payload["page"] = document.to_liquid
|
218
|
-
payload["paginator"] = if document.respond_to?(:pager)
|
219
|
-
document.pager.to_liquid
|
220
|
-
end
|
218
|
+
payload["paginator"] = (document.pager.to_liquid if document.respond_to?(:pager))
|
221
219
|
end
|
222
220
|
|
223
221
|
# Set related posts to payload if document is a post.
|
224
222
|
#
|
225
223
|
# Returns nothing
|
226
|
-
private
|
227
224
|
def assign_current_document!
|
228
225
|
payload["site"].current_document = document
|
229
226
|
end
|
@@ -231,21 +228,16 @@ module Jekyll
|
|
231
228
|
# Set highlighter prefix and suffix
|
232
229
|
#
|
233
230
|
# Returns nothing
|
234
|
-
private
|
235
231
|
def assign_highlighter_options!
|
236
232
|
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
237
233
|
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
238
234
|
end
|
239
235
|
|
240
|
-
private
|
241
236
|
def assign_layout_data!
|
242
237
|
layout = layouts[document.data["layout"]]
|
243
|
-
if layout
|
244
|
-
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
|
245
|
-
end
|
238
|
+
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {}) if layout
|
246
239
|
end
|
247
240
|
|
248
|
-
private
|
249
241
|
def permalink_ext
|
250
242
|
document_permalink = document.permalink
|
251
243
|
if document_permalink && !document_permalink.end_with?("/")
|
@@ -254,7 +246,6 @@ module Jekyll
|
|
254
246
|
end
|
255
247
|
end
|
256
248
|
|
257
|
-
private
|
258
249
|
def converter_output_ext
|
259
250
|
if output_exts.size == 1
|
260
251
|
output_exts.last
|
@@ -263,14 +254,12 @@ module Jekyll
|
|
263
254
|
end
|
264
255
|
end
|
265
256
|
|
266
|
-
private
|
267
257
|
def output_exts
|
268
258
|
@output_exts ||= converters.map do |c|
|
269
259
|
c.output_ext(document.extname)
|
270
260
|
end.compact
|
271
261
|
end
|
272
262
|
|
273
|
-
private
|
274
263
|
def liquid_options
|
275
264
|
@liquid_options ||= site.config["liquid"]
|
276
265
|
end
|
data/lib/jekyll/site.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Jekyll
|
4
4
|
class Site
|
5
|
-
attr_reader :source, :dest, :config
|
5
|
+
attr_reader :source, :dest, :cache_dir, :config
|
6
6
|
attr_accessor :layouts, :pages, :static_files, :drafts,
|
7
7
|
:exclude, :include, :lsi, :highlighter, :permalink_style,
|
8
8
|
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
|
@@ -22,6 +22,8 @@ module Jekyll
|
|
22
22
|
|
23
23
|
self.config = config
|
24
24
|
|
25
|
+
@cache_dir = in_source_dir(config["cache_dir"])
|
26
|
+
|
25
27
|
@reader = Reader.new(self)
|
26
28
|
@regenerator = Regenerator.new(self)
|
27
29
|
@liquid_renderer = LiquidRenderer.new(self)
|
@@ -44,13 +46,14 @@ module Jekyll
|
|
44
46
|
@config = config.clone
|
45
47
|
|
46
48
|
%w(safe lsi highlighter baseurl exclude include future unpublished
|
47
|
-
|
48
|
-
|
49
|
+
show_drafts limit_posts keep_files).each do |opt|
|
50
|
+
send("#{opt}=", config[opt])
|
49
51
|
end
|
50
52
|
|
51
53
|
# keep using `gems` to avoid breaking change
|
52
54
|
self.gems = config["plugins"]
|
53
55
|
|
56
|
+
configure_cache
|
54
57
|
configure_plugins
|
55
58
|
configure_theme
|
56
59
|
configure_include_paths
|
@@ -58,6 +61,8 @@ module Jekyll
|
|
58
61
|
|
59
62
|
self.permalink_style = config["permalink"].to_sym
|
60
63
|
|
64
|
+
# Read in a _config.yml from the current theme-gem at the very end.
|
65
|
+
@config = load_theme_configuration(config) if theme
|
61
66
|
@config
|
62
67
|
end
|
63
68
|
|
@@ -78,6 +83,8 @@ module Jekyll
|
|
78
83
|
Jekyll.logger.info @liquid_renderer.stats_table
|
79
84
|
end
|
80
85
|
|
86
|
+
# rubocop:disable Metrics/MethodLength
|
87
|
+
#
|
81
88
|
# Reset Site details.
|
82
89
|
#
|
83
90
|
# Returns nothing
|
@@ -91,19 +98,22 @@ module Jekyll
|
|
91
98
|
self.pages = []
|
92
99
|
self.static_files = []
|
93
100
|
self.data = {}
|
101
|
+
@post_attr_hash = {}
|
94
102
|
@site_data = nil
|
95
103
|
@collections = nil
|
104
|
+
@documents = nil
|
96
105
|
@docs_to_write = nil
|
97
106
|
@regenerator.clear_cache
|
98
107
|
@liquid_renderer.reset
|
99
108
|
@site_cleaner = nil
|
109
|
+
frontmatter_defaults.reset
|
100
110
|
|
101
|
-
|
102
|
-
raise ArgumentError, "limit_posts must be a non-negative number"
|
103
|
-
end
|
111
|
+
raise ArgumentError, "limit_posts must be a non-negative number" if limit_posts.negative?
|
104
112
|
|
113
|
+
Jekyll::Cache.clear_if_config_changed config
|
105
114
|
Jekyll::Hooks.trigger :site, :after_reset, self
|
106
115
|
end
|
116
|
+
# rubocop:enable Metrics/MethodLength
|
107
117
|
|
108
118
|
# Load necessary libraries, plugins, converters, and generators.
|
109
119
|
#
|
@@ -124,7 +134,7 @@ module Jekyll
|
|
124
134
|
Pathname.new(source).ascend do |path|
|
125
135
|
if path == dest_pathname
|
126
136
|
raise Errors::FatalException,
|
127
|
-
|
137
|
+
"Destination directory cannot be or contain the Source directory."
|
128
138
|
end
|
129
139
|
end
|
130
140
|
end
|
@@ -174,7 +184,7 @@ module Jekyll
|
|
174
184
|
start = Time.now
|
175
185
|
generator.generate(self)
|
176
186
|
Jekyll.logger.debug "Generating:",
|
177
|
-
|
187
|
+
"#{generator.class} finished in #{Time.now - start} seconds."
|
178
188
|
end
|
179
189
|
end
|
180
190
|
|
@@ -232,12 +242,14 @@ module Jekyll
|
|
232
242
|
def post_attr_hash(post_attr)
|
233
243
|
# Build a hash map based on the specified post attribute ( post attr =>
|
234
244
|
# array of posts ) then sort each array in reverse order.
|
235
|
-
|
236
|
-
|
237
|
-
|
245
|
+
@post_attr_hash[post_attr] ||= begin
|
246
|
+
hash = Hash.new { |h, key| h[key] = [] }
|
247
|
+
posts.docs.each do |p|
|
248
|
+
p.data[post_attr]&.each { |t| hash[t] << p }
|
249
|
+
end
|
250
|
+
hash.each_value { |posts| posts.sort!.reverse! }
|
251
|
+
hash
|
238
252
|
end
|
239
|
-
hash.each_value { |posts| posts.sort!.reverse! }
|
240
|
-
hash
|
241
253
|
end
|
242
254
|
|
243
255
|
def tags
|
@@ -303,10 +315,10 @@ module Jekyll
|
|
303
315
|
def relative_permalinks_are_deprecated
|
304
316
|
if config["relative_permalinks"]
|
305
317
|
Jekyll.logger.abort_with "Since v3.0, permalinks for pages" \
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
318
|
+
" in subfolders must be relative to the" \
|
319
|
+
" site source directory, not the parent" \
|
320
|
+
" directory. Check https://jekyllrb.com/docs/upgrading/"\
|
321
|
+
" for more info."
|
310
322
|
end
|
311
323
|
end
|
312
324
|
|
@@ -314,15 +326,15 @@ module Jekyll
|
|
314
326
|
#
|
315
327
|
# Returns an Array of Documents which should be written
|
316
328
|
def docs_to_write
|
317
|
-
documents.select(&:write?)
|
329
|
+
@docs_to_write ||= documents.select(&:write?)
|
318
330
|
end
|
319
331
|
|
320
332
|
# Get all the documents
|
321
333
|
#
|
322
334
|
# Returns an Array of all Documents
|
323
335
|
def documents
|
324
|
-
collections.
|
325
|
-
|
336
|
+
@documents ||= collections.reduce(Set.new) do |docs, (_, collection)|
|
337
|
+
docs + collection.docs + collection.files
|
326
338
|
end.to_a
|
327
339
|
end
|
328
340
|
|
@@ -377,6 +389,7 @@ module Jekyll
|
|
377
389
|
# Returns a path which is prefixed with the theme root directory.
|
378
390
|
def in_theme_dir(*paths)
|
379
391
|
return nil unless theme
|
392
|
+
|
380
393
|
paths.reduce(theme.root) do |base, path|
|
381
394
|
Jekyll.sanitized_path(base, path)
|
382
395
|
end
|
@@ -394,6 +407,18 @@ module Jekyll
|
|
394
407
|
end
|
395
408
|
end
|
396
409
|
|
410
|
+
# Public: Prefix a given path with the cache directory.
|
411
|
+
#
|
412
|
+
# paths - (optional) path elements to a file or directory within the
|
413
|
+
# cache directory
|
414
|
+
#
|
415
|
+
# Returns a path which is prefixed with the cache directory.
|
416
|
+
def in_cache_dir(*paths)
|
417
|
+
paths.reduce(cache_dir) do |base, path|
|
418
|
+
Jekyll.sanitized_path(base, path)
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
397
422
|
# Public: The full path to the directory that houses all the collections registered
|
398
423
|
# with the current site.
|
399
424
|
#
|
@@ -403,14 +428,34 @@ module Jekyll
|
|
403
428
|
@collections_path ||= dir_str.empty? ? source : in_source_dir(dir_str)
|
404
429
|
end
|
405
430
|
|
431
|
+
private
|
432
|
+
|
433
|
+
def load_theme_configuration(config)
|
434
|
+
theme_config_file = in_theme_dir("_config.yml")
|
435
|
+
return config unless File.exist?(theme_config_file)
|
436
|
+
|
437
|
+
# Bail out if the theme_config_file is a symlink file irrespective of safe mode
|
438
|
+
return config if File.symlink?(theme_config_file)
|
439
|
+
|
440
|
+
theme_config = SafeYAML.load_file(theme_config_file)
|
441
|
+
return config unless theme_config.is_a?(Hash)
|
442
|
+
|
443
|
+
Jekyll.logger.info "Theme Config file:", theme_config_file
|
444
|
+
|
445
|
+
# theme_config should not be overriding Jekyll's defaults
|
446
|
+
theme_config.delete_if { |key, _| Configuration::DEFAULTS.key?(key) }
|
447
|
+
|
448
|
+
# Override theme_config with existing config and return the result.
|
449
|
+
Utils.deep_merge_hashes(theme_config, config)
|
450
|
+
end
|
451
|
+
|
406
452
|
# Limits the current posts; removes the posts which exceed the limit_posts
|
407
453
|
#
|
408
454
|
# Returns nothing
|
409
|
-
private
|
410
455
|
def limit_posts!
|
411
|
-
if limit_posts
|
456
|
+
if limit_posts.positive?
|
412
457
|
limit = posts.docs.length < limit_posts ? posts.docs.length : limit_posts
|
413
|
-
|
458
|
+
posts.docs = posts.docs[-limit, limit]
|
414
459
|
end
|
415
460
|
end
|
416
461
|
|
@@ -418,18 +463,21 @@ module Jekyll
|
|
418
463
|
# already exist.
|
419
464
|
#
|
420
465
|
# Returns The Cleaner
|
421
|
-
private
|
422
466
|
def site_cleaner
|
423
467
|
@site_cleaner ||= Cleaner.new(self)
|
424
468
|
end
|
425
469
|
|
426
|
-
|
470
|
+
# Disable Marshaling cache to disk in Safe Mode
|
471
|
+
def configure_cache
|
472
|
+
Jekyll::Cache.base_dir = in_source_dir(config["cache_dir"], "Jekyll/Cache")
|
473
|
+
Jekyll::Cache.disable_disk_cache! if safe
|
474
|
+
end
|
475
|
+
|
427
476
|
def configure_plugins
|
428
477
|
self.plugin_manager = Jekyll::PluginManager.new(self)
|
429
478
|
self.plugins = plugin_manager.plugins_path
|
430
479
|
end
|
431
480
|
|
432
|
-
private
|
433
481
|
def configure_theme
|
434
482
|
self.theme = nil
|
435
483
|
return if config["theme"].nil?
|
@@ -444,20 +492,17 @@ module Jekyll
|
|
444
492
|
end
|
445
493
|
end
|
446
494
|
|
447
|
-
private
|
448
495
|
def configure_include_paths
|
449
496
|
@includes_load_paths = Array(in_source_dir(config["includes_dir"].to_s))
|
450
|
-
@includes_load_paths << theme.includes_path if theme
|
497
|
+
@includes_load_paths << theme.includes_path if theme&.includes_path
|
451
498
|
end
|
452
499
|
|
453
|
-
private
|
454
500
|
def configure_file_read_opts
|
455
501
|
self.file_read_opts = {}
|
456
|
-
|
502
|
+
file_read_opts[:encoding] = config["encoding"] if config["encoding"]
|
457
503
|
self.file_read_opts = Jekyll::Utils.merged_file_read_opts(self, {})
|
458
504
|
end
|
459
505
|
|
460
|
-
private
|
461
506
|
def render_docs(payload)
|
462
507
|
collections.each_value do |collection|
|
463
508
|
collection.docs.each do |document|
|
@@ -466,16 +511,15 @@ module Jekyll
|
|
466
511
|
end
|
467
512
|
end
|
468
513
|
|
469
|
-
private
|
470
514
|
def render_pages(payload)
|
471
|
-
pages.
|
515
|
+
pages.each do |page|
|
472
516
|
render_regenerated(page, payload)
|
473
517
|
end
|
474
518
|
end
|
475
519
|
|
476
|
-
private
|
477
520
|
def render_regenerated(document, payload)
|
478
521
|
return unless regenerator.regenerate?(document)
|
522
|
+
|
479
523
|
document.output = Jekyll::Renderer.new(self, document, payload).run
|
480
524
|
document.trigger_hooks(:post_render)
|
481
525
|
end
|
data/lib/jekyll/static_file.rb
CHANGED
@@ -54,7 +54,8 @@ module Jekyll
|
|
54
54
|
#
|
55
55
|
# Returns destination file path.
|
56
56
|
def destination(dest)
|
57
|
-
@site.in_dest_dir(
|
57
|
+
dest = @site.in_dest_dir(dest)
|
58
|
+
@site.in_dest_dir(dest, Jekyll::URL.unescape_path(url))
|
58
59
|
end
|
59
60
|
|
60
61
|
def destination_rel_dir
|
@@ -86,7 +87,10 @@ module Jekyll
|
|
86
87
|
# Returns true unless the defaults for the destination path from
|
87
88
|
# _config.yml contain `published: false`.
|
88
89
|
def write?
|
89
|
-
defaults.fetch("published", true)
|
90
|
+
publishable = defaults.fetch("published", true)
|
91
|
+
return publishable unless @collection
|
92
|
+
|
93
|
+
publishable && @collection.write?
|
90
94
|
end
|
91
95
|
|
92
96
|
# Write the static file to the destination directory (if modified).
|
@@ -96,8 +100,8 @@ module Jekyll
|
|
96
100
|
# Returns false if the file was not modified since last time (no-op).
|
97
101
|
def write(dest)
|
98
102
|
dest_path = destination(dest)
|
99
|
-
|
100
103
|
return false if File.exist?(dest_path) && !modified?
|
104
|
+
|
101
105
|
self.class.mtimes[path] = mtime
|
102
106
|
|
103
107
|
FileUtils.mkdir_p(File.dirname(dest_path))
|
@@ -111,33 +115,58 @@ module Jekyll
|
|
111
115
|
@to_liquid ||= Drops::StaticFileDrop.new(self)
|
112
116
|
end
|
113
117
|
|
118
|
+
# Generate "basename without extension" and strip away any trailing periods.
|
119
|
+
# NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
|
114
120
|
def basename
|
115
|
-
File.basename(name, extname)
|
121
|
+
@basename ||= File.basename(name, extname).gsub(%r!\.*\z!, "")
|
116
122
|
end
|
117
123
|
|
118
124
|
def placeholders
|
119
125
|
{
|
120
126
|
:collection => @collection.label,
|
121
|
-
:path =>
|
122
|
-
@collection.relative_directory.size..relative_path.size],
|
127
|
+
:path => cleaned_relative_path,
|
123
128
|
:output_ext => "",
|
124
129
|
:name => "",
|
125
130
|
:title => "",
|
126
131
|
}
|
127
132
|
end
|
128
133
|
|
134
|
+
# Similar to Jekyll::Document#cleaned_relative_path.
|
135
|
+
# Generates a relative path with the collection's directory removed when applicable
|
136
|
+
# and additionally removes any multiple periods in the string.
|
137
|
+
#
|
138
|
+
# NOTE: `String#gsub!` removes all trailing periods (in comparison to `String#chomp!`)
|
139
|
+
#
|
140
|
+
# Examples:
|
141
|
+
# When `relative_path` is "_methods/site/my-cool-avatar...png":
|
142
|
+
# cleaned_relative_path
|
143
|
+
# # => "/site/my-cool-avatar"
|
144
|
+
#
|
145
|
+
# Returns the cleaned relative path of the static file.
|
146
|
+
def cleaned_relative_path
|
147
|
+
@cleaned_relative_path ||= begin
|
148
|
+
cleaned = relative_path[0..-extname.length - 1]
|
149
|
+
cleaned.gsub!(%r!\.*\z!, "")
|
150
|
+
cleaned.sub!(@collection.relative_directory, "") if @collection
|
151
|
+
cleaned
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
129
155
|
# Applies a similar URL-building technique as Jekyll::Document that takes
|
130
156
|
# the collection's URL template into account. The default URL template can
|
131
157
|
# be overriden in the collection's configuration in _config.yml.
|
132
158
|
def url
|
133
|
-
@url ||=
|
134
|
-
|
159
|
+
@url ||= begin
|
160
|
+
base = if @collection.nil?
|
161
|
+
cleaned_relative_path
|
135
162
|
else
|
136
|
-
|
163
|
+
Jekyll::URL.new(
|
137
164
|
:template => @collection.url_template,
|
138
|
-
:placeholders => placeholders
|
139
|
-
|
165
|
+
:placeholders => placeholders
|
166
|
+
)
|
140
167
|
end.to_s.chomp("/")
|
168
|
+
base << extname
|
169
|
+
end
|
141
170
|
end
|
142
171
|
|
143
172
|
# Returns the type of the collection if present, nil otherwise.
|
@@ -151,7 +180,14 @@ module Jekyll
|
|
151
180
|
@defaults ||= @site.frontmatter_defaults.all url, type
|
152
181
|
end
|
153
182
|
|
183
|
+
# Returns a debug string on inspecting the static file.
|
184
|
+
# Includes only the relative path of the object.
|
185
|
+
def inspect
|
186
|
+
"#<#{self.class} @relative_path=#{relative_path.inspect}>"
|
187
|
+
end
|
188
|
+
|
154
189
|
private
|
190
|
+
|
155
191
|
def copy_file(dest_path)
|
156
192
|
if @site.safe || Jekyll.env == "production"
|
157
193
|
FileUtils.cp(path, dest_path)
|