jekyll 3.9.1 → 4.0.0.pre.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +27 -50
  3. data/LICENSE +1 -1
  4. data/README.markdown +46 -17
  5. data/lib/blank_template/_config.yml +3 -0
  6. data/lib/blank_template/_layouts/default.html +12 -0
  7. data/lib/blank_template/_sass/main.scss +9 -0
  8. data/lib/blank_template/assets/css/main.scss +4 -0
  9. data/lib/blank_template/index.md +8 -0
  10. data/lib/jekyll.rb +5 -0
  11. data/lib/jekyll/cache.rb +183 -0
  12. data/lib/jekyll/cleaner.rb +2 -1
  13. data/lib/jekyll/collection.rb +78 -8
  14. data/lib/jekyll/command.rb +31 -6
  15. data/lib/jekyll/commands/build.rb +11 -20
  16. data/lib/jekyll/commands/clean.rb +2 -0
  17. data/lib/jekyll/commands/doctor.rb +15 -8
  18. data/lib/jekyll/commands/help.rb +1 -1
  19. data/lib/jekyll/commands/new.rb +37 -39
  20. data/lib/jekyll/commands/new_theme.rb +30 -28
  21. data/lib/jekyll/commands/serve.rb +46 -80
  22. data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
  23. data/lib/jekyll/commands/serve/servlet.rb +9 -11
  24. data/lib/jekyll/configuration.rb +26 -26
  25. data/lib/jekyll/converters/identity.rb +18 -0
  26. data/lib/jekyll/converters/markdown.rb +49 -40
  27. data/lib/jekyll/converters/markdown/kramdown_parser.rb +1 -10
  28. data/lib/jekyll/converters/smartypants.rb +34 -14
  29. data/lib/jekyll/convertible.rb +11 -13
  30. data/lib/jekyll/deprecator.rb +1 -3
  31. data/lib/jekyll/document.rb +44 -41
  32. data/lib/jekyll/drops/collection_drop.rb +2 -3
  33. data/lib/jekyll/drops/document_drop.rb +2 -1
  34. data/lib/jekyll/drops/drop.rb +3 -6
  35. data/lib/jekyll/drops/excerpt_drop.rb +4 -0
  36. data/lib/jekyll/drops/site_drop.rb +4 -13
  37. data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
  38. data/lib/jekyll/drops/url_drop.rb +1 -0
  39. data/lib/jekyll/entry_filter.rb +2 -1
  40. data/lib/jekyll/excerpt.rb +45 -34
  41. data/lib/jekyll/external.rb +10 -5
  42. data/lib/jekyll/filters.rb +72 -31
  43. data/lib/jekyll/filters/date_filters.rb +6 -3
  44. data/lib/jekyll/filters/grouping_filters.rb +1 -2
  45. data/lib/jekyll/filters/url_filters.rb +6 -1
  46. data/lib/jekyll/frontmatter_defaults.rb +35 -19
  47. data/lib/jekyll/hooks.rb +2 -3
  48. data/lib/jekyll/liquid_extensions.rb +0 -2
  49. data/lib/jekyll/liquid_renderer.rb +13 -1
  50. data/lib/jekyll/liquid_renderer/file.rb +14 -3
  51. data/lib/jekyll/liquid_renderer/table.rb +67 -65
  52. data/lib/jekyll/log_adapter.rb +5 -1
  53. data/lib/jekyll/page.rb +10 -11
  54. data/lib/jekyll/page_without_a_file.rb +0 -4
  55. data/lib/jekyll/plugin.rb +5 -11
  56. data/lib/jekyll/plugin_manager.rb +2 -0
  57. data/lib/jekyll/reader.rb +38 -8
  58. data/lib/jekyll/readers/data_reader.rb +7 -9
  59. data/lib/jekyll/readers/layout_reader.rb +2 -12
  60. data/lib/jekyll/readers/post_reader.rb +29 -17
  61. data/lib/jekyll/readers/static_file_reader.rb +1 -1
  62. data/lib/jekyll/readers/theme_assets_reader.rb +7 -5
  63. data/lib/jekyll/regenerator.rb +4 -12
  64. data/lib/jekyll/renderer.rb +14 -25
  65. data/lib/jekyll/site.rb +78 -34
  66. data/lib/jekyll/static_file.rb +47 -11
  67. data/lib/jekyll/stevenson.rb +2 -3
  68. data/lib/jekyll/tags/highlight.rb +22 -52
  69. data/lib/jekyll/tags/include.rb +22 -38
  70. data/lib/jekyll/tags/link.rb +11 -7
  71. data/lib/jekyll/tags/post_url.rb +17 -16
  72. data/lib/jekyll/theme.rb +12 -23
  73. data/lib/jekyll/theme_builder.rb +91 -89
  74. data/lib/jekyll/url.rb +3 -2
  75. data/lib/jekyll/utils.rb +5 -4
  76. data/lib/jekyll/utils/ansi.rb +1 -1
  77. data/lib/jekyll/utils/exec.rb +0 -1
  78. data/lib/jekyll/utils/internet.rb +2 -4
  79. data/lib/jekyll/utils/platforms.rb +8 -8
  80. data/lib/jekyll/utils/thread_event.rb +1 -5
  81. data/lib/jekyll/utils/win_tz.rb +1 -1
  82. data/lib/jekyll/version.rb +1 -1
  83. data/lib/site_template/.gitignore +2 -0
  84. data/lib/site_template/404.html +1 -0
  85. data/lib/site_template/_config.yml +17 -5
  86. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
  87. data/lib/site_template/{about.md → about.markdown} +0 -0
  88. data/lib/site_template/{index.md → index.markdown} +0 -0
  89. data/lib/theme_template/gitignore.erb +1 -0
  90. data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -0
  91. metadata +85 -51
  92. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
  93. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
  94. data/lib/jekyll/utils/rouge.rb +0 -22
@@ -39,17 +39,17 @@ module Jekyll
39
39
 
40
40
  begin
41
41
  self.content = File.read(@path || site.in_source_dir(base, name),
42
- **Utils.merged_file_read_opts(site, opts))
42
+ Utils.merged_file_read_opts(site, opts))
43
43
  if content =~ Document::YAML_FRONT_MATTER_REGEXP
44
44
  self.content = $POSTMATCH
45
45
  self.data = SafeYAML.load(Regexp.last_match(1))
46
46
  end
47
47
  rescue Psych::SyntaxError => e
48
48
  Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
49
- raise e if self.site.config["strict_front_matter"]
49
+ raise e if site.config["strict_front_matter"]
50
50
  rescue StandardError => e
51
51
  Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
52
- raise e if self.site.config["strict_front_matter"]
52
+ raise e if site.config["strict_front_matter"]
53
53
  end
54
54
 
55
55
  self.data ||= {}
@@ -64,12 +64,12 @@ module Jekyll
64
64
  def validate_data!(filename)
65
65
  unless self.data.is_a?(Hash)
66
66
  raise Errors::InvalidYAMLFrontMatterError,
67
- "Invalid YAML front matter in #{filename}"
67
+ "Invalid YAML front matter in #{filename}"
68
68
  end
69
69
  end
70
70
 
71
71
  def validate_permalink!(filename)
72
- if self.data["permalink"] && self.data["permalink"].to_s.empty?
72
+ if self.data["permalink"]&.to_s&.empty?
73
73
  raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
74
74
  end
75
75
  end
@@ -125,16 +125,12 @@ module Jekyll
125
125
  #
126
126
  # Returns the type of self.
127
127
  def type
128
- if is_a?(Page)
129
- :pages
130
- end
128
+ :pages if is_a?(Page)
131
129
  end
132
130
 
133
131
  # returns the owner symbol for hook triggering
134
132
  def hook_owner
135
- if is_a?(Page)
136
- :pages
137
- end
133
+ :pages if is_a?(Page)
138
134
  end
139
135
 
140
136
  # Determine whether the document is an asset file.
@@ -164,6 +160,8 @@ module Jekyll
164
160
  #
165
161
  # Returns true if the file has Liquid Tags or Variables, false otherwise.
166
162
  def render_with_liquid?
163
+ return false if data["render_with_liquid"] == false
164
+
167
165
  Jekyll::Utils.has_liquid_construct?(content)
168
166
  end
169
167
 
@@ -181,7 +179,7 @@ module Jekyll
181
179
  #
182
180
  # Returns true if the layout is invalid, false if otherwise
183
181
  def invalid_layout?(layout)
184
- !data["layout"].nil? && layout.nil? && !(self.is_a? Jekyll::Excerpt)
182
+ !data["layout"].nil? && layout.nil? && !(is_a? Jekyll::Excerpt)
185
183
  end
186
184
 
187
185
  # Recursively render layouts
@@ -210,7 +208,7 @@ module Jekyll
210
208
  renderer.payload = payload
211
209
  end.run
212
210
 
213
- Jekyll.logger.debug "Post-Render Hooks:", self.relative_path
211
+ Jekyll.logger.debug "Post-Render Hooks:", relative_path
214
212
  Jekyll::Hooks.trigger hook_owner, :post_render, self
215
213
  ensure
216
214
  @_renderer = nil # this will allow the modifications above to disappear
@@ -34,9 +34,7 @@ module Jekyll
34
34
  end
35
35
 
36
36
  def arg_is_present?(args, deprecated_argument, message)
37
- if args.include?(deprecated_argument)
38
- deprecation_message(message)
39
- end
37
+ deprecation_message(message) if args.include?(deprecated_argument)
40
38
  end
41
39
 
42
40
  def deprecation_message(message)
@@ -10,9 +10,9 @@ module Jekyll
10
10
 
11
11
  def_delegator :self, :read_post_data, :post_read
12
12
 
13
- YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m
14
- DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!
15
- DATE_FILENAME_MATCHER = %r!^(?:.+/)*(\d{2,4}-\d{1,2}-\d{1,2})-(.*)(\.[^.]+)$!
13
+ YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
14
+ DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!.freeze
15
+ DATE_FILENAME_MATCHER = %r!^(?>.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.]+)$!.freeze
16
16
 
17
17
  # Create a new Document.
18
18
  #
@@ -60,12 +60,19 @@ module Jekyll
60
60
  data
61
61
  end
62
62
 
63
+ # Returns the document date. If metadata is not present then calculates it
64
+ # based on Jekyll::Site#time or the document file modification time.
65
+ #
66
+ # Return document date string.
63
67
  def date
64
68
  data["date"] ||= (draft? ? source_file_mtime : site.time)
65
69
  end
66
70
 
71
+ # Return document file modification time in the form of a Time object.
72
+ #
73
+ # Return document file modification Time object.
67
74
  def source_file_mtime
68
- @source_file_mtime ||= File.mtime(path)
75
+ File.mtime(path)
69
76
  end
70
77
 
71
78
  # Returns whether the document is a draft. This is only the case if
@@ -112,15 +119,19 @@ module Jekyll
112
119
  # and with the collection's directory removed as well.
113
120
  # This method is useful when building the URL of the document.
114
121
  #
122
+ # NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
123
+ #
115
124
  # Examples:
116
- # When relative_path is "_methods/site/generate.md":
125
+ # When relative_path is "_methods/site/generate...md":
117
126
  # cleaned_relative_path
118
127
  # # => "/site/generate"
119
128
  #
120
129
  # Returns the cleaned relative path of the document.
121
130
  def cleaned_relative_path
122
131
  @cleaned_relative_path ||=
123
- relative_path[0..-extname.length - 1].sub(collection.relative_directory, "")
132
+ relative_path[0..-extname.length - 1]
133
+ .sub(collection.relative_directory, "")
134
+ .gsub(%r!\.*\z!, "")
124
135
  end
125
136
 
126
137
  # Determine whether the document is a YAML file.
@@ -159,6 +170,8 @@ module Jekyll
159
170
  # or if the document doesn't contain any Liquid Tags or Variables,
160
171
  # true otherwise.
161
172
  def render_with_liquid?
173
+ return false if data["render_with_liquid"] == false
174
+
162
175
  !(coffeescript_file? || yaml_file? || !Utils.has_liquid_construct?(content))
163
176
  end
164
177
 
@@ -204,11 +217,11 @@ module Jekyll
204
217
  #
205
218
  # Returns the computed URL for the document.
206
219
  def url
207
- @url ||= URL.new({
220
+ @url ||= URL.new(
208
221
  :template => url_template,
209
222
  :placeholders => url_placeholders,
210
- :permalink => permalink,
211
- }).to_s
223
+ :permalink => permalink
224
+ ).to_s
212
225
  end
213
226
 
214
227
  def [](key)
@@ -266,7 +279,7 @@ module Jekyll
266
279
  else
267
280
  begin
268
281
  merge_defaults
269
- read_content(**opts)
282
+ read_content(opts)
270
283
  read_post_data
271
284
  rescue StandardError => e
272
285
  handle_read_error(e)
@@ -286,7 +299,7 @@ module Jekyll
286
299
  #
287
300
  # Returns the inspect string for this document.
288
301
  def inspect
289
- "#<Jekyll::Document #{relative_path} collection=#{collection.label}>"
302
+ "#<#{self.class} #{relative_path} collection=#{collection.label}>"
290
303
  end
291
304
 
292
305
  # The string representation for this document.
@@ -303,6 +316,7 @@ module Jekyll
303
316
  # equal or greater than the other doc's path. See String#<=> for more details.
304
317
  def <=>(other)
305
318
  return nil unless other.respond_to?(:data)
319
+
306
320
  cmp = data["date"] <=> other.data["date"]
307
321
  cmp = path <=> other.path if cmp.nil? || cmp.zero?
308
322
  cmp
@@ -315,7 +329,7 @@ module Jekyll
315
329
  # method returns true, and if the site's Publisher will publish the document.
316
330
  # False otherwise.
317
331
  def write?
318
- collection && collection.write? && site.publisher.publish?(self)
332
+ collection&.write? && site.publisher.publish?(self)
319
333
  end
320
334
 
321
335
  # The Document excerpt_separator, from the YAML Front-Matter or site
@@ -323,7 +337,7 @@ module Jekyll
323
337
  #
324
338
  # Returns the document excerpt_separator
325
339
  def excerpt_separator
326
- (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
340
+ @excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
327
341
  end
328
342
 
329
343
  # Whether to generate an excerpt
@@ -335,16 +349,12 @@ module Jekyll
335
349
 
336
350
  def next_doc
337
351
  pos = collection.docs.index { |post| post.equal?(self) }
338
- if pos && pos < collection.docs.length - 1
339
- collection.docs[pos + 1]
340
- end
352
+ collection.docs[pos + 1] if pos && pos < collection.docs.length - 1
341
353
  end
342
354
 
343
355
  def previous_doc
344
356
  pos = collection.docs.index { |post| post.equal?(self) }
345
- if pos && pos > 0
346
- collection.docs[pos - 1]
347
- end
357
+ collection.docs[pos - 1] if pos && pos.positive?
348
358
  end
349
359
 
350
360
  def trigger_hooks(hook_name, *args)
@@ -400,32 +410,30 @@ module Jekyll
400
410
  end
401
411
 
402
412
  def populate_categories
403
- merge_data!({
413
+ merge_data!(
404
414
  "categories" => (
405
415
  Array(data["categories"]) + Utils.pluralized_array_from_hash(
406
416
  data, "category", "categories"
407
417
  )
408
- ).map(&:to_s).flatten.uniq,
409
- })
418
+ ).map(&:to_s).flatten.uniq
419
+ )
410
420
  end
411
421
 
412
422
  def populate_tags
413
- merge_data!({
414
- "tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten,
415
- })
423
+ merge_data!(
424
+ "tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
425
+ )
416
426
  end
417
427
 
418
428
  private
429
+
419
430
  def merge_categories!(other)
420
431
  if other.key?("categories") && !other["categories"].nil?
421
- if other["categories"].is_a?(String)
422
- other["categories"] = other["categories"].split
423
- end
432
+ other["categories"] = other["categories"].split if other["categories"].is_a?(String)
424
433
  other["categories"] = (data["categories"] || []) | other["categories"]
425
434
  end
426
435
  end
427
436
 
428
- private
429
437
  def merge_date!(source)
430
438
  if data.key?("date")
431
439
  data["date"] = Utils.parse_date(
@@ -435,7 +443,6 @@ module Jekyll
435
443
  end
436
444
  end
437
445
 
438
- private
439
446
  def merge_defaults
440
447
  defaults = @site.frontmatter_defaults.all(
441
448
  relative_path,
@@ -444,9 +451,8 @@ module Jekyll
444
451
  merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
445
452
  end
446
453
 
447
- private
448
- def read_content(**opts)
449
- self.content = File.read(path, **Utils.merged_file_read_opts(site, opts))
454
+ def read_content(opts)
455
+ self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
450
456
  if content =~ YAML_FRONT_MATTER_REGEXP
451
457
  self.content = $POSTMATCH
452
458
  data_file = SafeYAML.load(Regexp.last_match(1))
@@ -454,7 +460,6 @@ module Jekyll
454
460
  end
455
461
  end
456
462
 
457
- private
458
463
  def read_post_data
459
464
  populate_title
460
465
  populate_categories
@@ -462,7 +467,6 @@ module Jekyll
462
467
  generate_excerpt
463
468
  end
464
469
 
465
- private
466
470
  def handle_read_error(error)
467
471
  if error.is_a? Psych::SyntaxError
468
472
  Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{error.message}"
@@ -475,7 +479,6 @@ module Jekyll
475
479
  end
476
480
  end
477
481
 
478
- private
479
482
  def populate_title
480
483
  if relative_path =~ DATE_FILENAME_MATCHER
481
484
  date, slug, ext = Regexp.last_match.captures
@@ -484,6 +487,10 @@ module Jekyll
484
487
  slug, ext = Regexp.last_match.captures
485
488
  end
486
489
 
490
+ # slugs shouldn't end with a period
491
+ # `String#gsub!` removes all trailing periods (in comparison to `String#chomp!`)
492
+ slug.gsub!(%r!\.*\z!, "")
493
+
487
494
  # Try to ensure the user gets a title.
488
495
  data["title"] ||= Utils.titleize_slug(slug)
489
496
  # Only overwrite slug & ext if they aren't specified.
@@ -491,18 +498,14 @@ module Jekyll
491
498
  data["ext"] ||= ext
492
499
  end
493
500
 
494
- private
495
501
  def modify_date(date)
496
502
  if !data["date"] || data["date"].to_i == site.time.to_i
497
503
  merge_data!({ "date" => date }, :source => "filename")
498
504
  end
499
505
  end
500
506
 
501
- private
502
507
  def generate_excerpt
503
- if generate_excerpt?
504
- data["excerpt"] ||= Jekyll::Excerpt.new(self)
505
- end
508
+ data["excerpt"] ||= Jekyll::Excerpt.new(self) if generate_excerpt?
506
509
  end
507
510
  end
508
511
  end
@@ -7,9 +7,8 @@ module Jekyll
7
7
 
8
8
  mutable false
9
9
 
10
- def_delegator :@obj, :write?, :output
11
- def_delegators :@obj, :label, :docs, :files, :directory,
12
- :relative_directory
10
+ def_delegator :@obj, :write?, :output
11
+ def_delegators :@obj, :label, :docs, :files, :directory, :relative_directory
13
12
 
14
13
  private def_delegator :@obj, :metadata, :fallback_data
15
14
 
@@ -12,7 +12,7 @@ module Jekyll
12
12
  mutable false
13
13
 
14
14
  def_delegator :@obj, :relative_path, :path
15
- def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
15
+ def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url, :date
16
16
 
17
17
  private def_delegator :@obj, :data, :fallback_data
18
18
 
@@ -26,6 +26,7 @@ module Jekyll
26
26
 
27
27
  def <=>(other)
28
28
  return nil unless other.is_a? DocumentDrop
29
+
29
30
  cmp = self["date"] <=> other["date"]
30
31
  cmp = self["path"] <=> other["path"] if cmp.nil? || cmp.zero?
31
32
  cmp
@@ -15,11 +15,7 @@ module Jekyll
15
15
  #
16
16
  # Returns the mutability of the class
17
17
  def self.mutable(is_mutable = nil)
18
- @is_mutable = if is_mutable
19
- is_mutable
20
- else
21
- false
22
- end
18
+ @is_mutable = is_mutable || false
23
19
  end
24
20
 
25
21
  def self.mutable?
@@ -105,6 +101,7 @@ module Jekyll
105
101
  def key?(key)
106
102
  return false if key.nil?
107
103
  return true if self.class.mutable? && @mutations.key?(key)
104
+
108
105
  respond_to?(key) || fallback_data.key?(key)
109
106
  end
110
107
 
@@ -173,7 +170,7 @@ module Jekyll
173
170
  end
174
171
 
175
172
  def merge(other, &block)
176
- self.dup.tap do |me|
173
+ dup.tap do |me|
177
174
  if block.nil?
178
175
  me.merge!(other)
179
176
  else
@@ -7,6 +7,10 @@ module Jekyll
7
7
  @obj.doc.data["layout"]
8
8
  end
9
9
 
10
+ def date
11
+ @obj.doc.date
12
+ end
13
+
10
14
  def excerpt
11
15
  nil
12
16
  end
@@ -8,12 +8,12 @@ module Jekyll
8
8
  mutable false
9
9
 
10
10
  def_delegator :@obj, :site_data, :data
11
- def_delegators :@obj, :time, :pages, :static_files, :tags, :categories
11
+ def_delegators :@obj, :time, :pages, :static_files, :documents, :tags, :categories
12
12
 
13
13
  private def_delegator :@obj, :config, :fallback_data
14
14
 
15
15
  def [](key)
16
- if @obj.collections.key?(key) && key != "posts"
16
+ if key != "posts" && @obj.collections.key?(key)
17
17
  @obj.collections[key].docs
18
18
  else
19
19
  super(key)
@@ -21,7 +21,7 @@ module Jekyll
21
21
  end
22
22
 
23
23
  def key?(key)
24
- (@obj.collections.key?(key) && key != "posts") || super
24
+ (key != "posts" && @obj.collections.key?(key)) || super
25
25
  end
26
26
 
27
27
  def posts
@@ -38,22 +38,13 @@ module Jekyll
38
38
  @site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
39
39
  end
40
40
 
41
- # `Site#documents` cannot be memoized so that `Site#docs_to_write` can access the
42
- # latest state of the attribute.
43
- #
44
- # Since this method will be called after `Site#pre_render` hook,
45
- # the `Site#documents` array shouldn't thereafter change and can therefore be
46
- # safely memoized to prevent additional computation of `Site#documents`.
47
- def documents
48
- @documents ||= @obj.documents
49
- end
50
-
51
41
  # `{{ site.related_posts }}` is how posts can get posts related to
52
42
  # them, either through LSI if it's enabled, or through the most
53
43
  # recent posts.
54
44
  # We should remove this in 4.0 and switch to `{{ post.related_posts }}`.
55
45
  def related_posts
56
46
  return nil unless @current_document.is_a?(Jekyll::Document)
47
+
57
48
  @current_document.related_posts
58
49
  end
59
50
  attr_writer :current_document