fix(date): Correctly set date to nil in collections

This commit is contained in:
Pixelastic 2018-03-20 11:39:16 +01:00
parent f8c656a802
commit d8a7dad71d
7 changed files with 71 additions and 54 deletions

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'jekyll/commands/algolia'
require 'jekyll/algolia/overwrites'
require 'date'
module Jekyll
@ -26,7 +27,6 @@ module Jekyll
# The gist of the plugin works by instanciating a Jekyll site,
# monkey-patching its `write` method and building it.
def self.init(config = {})
@start_time = Time.now
config = Configurator.init(config).config
@site = Jekyll::Algolia::Site.new(config)
@ -63,16 +63,6 @@ module Jekyll
@site
end
# Public: Get access to the time at which the command was run
#
# Jekyll will always set the updated time of pages to the time of the build
# run. The plugin needs those values to stay at nil if they did not change,
# so we'll keep track of the time at build time and revert any page build at
# that time to nil.
def self.start_time
@start_time
end
# A Jekyll::Site subclass that overrides process from the parent class to
# create JSON records out of rendered documents and push those records to
# Algolia instead of writing files to disk.

View File

@ -216,26 +216,21 @@ module Jekyll
#
# file - The Jekyll file
#
# All collections (including posts) will have a date taken either from the
# front-matter or the filename prefix. If none is set, Jekyll will use the
# current date.
#
# For pages, only dates defined in the front-matter will be used.
#
# Note that because the default date is the current one if none is
# defined, we have to make sure the date is actually nil when we index it.
# Otherwise the diff indexing mode will think that records have changed
# while they haven't.
# Posts have their date coming from the filepath, or the front-matter.
# Pages and other collection items can only have a date set in
# front-matter.
def self.date(file)
date = file.data['date']
# Collections get their date from .date, while pages read it from .data.
# Jekyll by default will set the date of collection to the current date,
# but we overwrote this.
date = if file.respond_to?(:date)
file.date
else
file.data['date']
end
return nil if date.nil?
# The date is *exactly* the time where the `jekyll algolia` was run.
# What a coincidence! It's a safe bet to assume that the original date
# was nil and has been overwritten by Jekyll
return nil if date.to_i == Jekyll::Algolia.start_time.to_i
date.to_i
date.to_time.to_i
end
# Public: Returns the raw excerpt of a file, directly as returned by

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
module Jekyll
# Overwriting the Jekyll::Document class
class Document
# By default, Jekyll will set the current date (time of build) to any
# collection item. This will break our diff algorithm, so we monkey patch
# this call to return nil if no date is defined instead.
def date
data['date'] || nil
end
end
end

View File

@ -462,29 +462,44 @@ describe(Jekyll::Algolia::FileBrowser) do
end
describe '.date' do
subject { current.date(file) }
subject { current.date(site.__find_file(filepath)) }
context 'with a page in the root' do
let(:file) { site.__find_file('about.md') }
it { should eq nil }
end
context 'with a collection element with a date set in front-matter' do
let(:file) { site.__find_file('_my-collection/collection-item.html') }
it { should eq 452_469_600 }
end
context 'with a collection element with no date' do
let(:file) { site.__find_file('_my-collection/sample-item.md') }
it { should eq nil }
end
context 'with a post' do
let(:file) { site.__find_file('_posts/2015-07-02-test-post.md') }
it { should eq 1_435_788_000 }
context 'page' do
describe 'nothing in front matter' do
let(:filepath) { 'about.md' }
it { should eq nil }
end
describe 'date in front matter' do
let(:filepath) { 'front_matter.md' }
it { should eq 1_521_500_400 }
end
end
context 'with a custom timezone' do
let(:site) { init_new_jekyll_site(timezone: 'America/New_York') }
let(:file) { site.__find_file('_posts/2015-07-02-test-post.md') }
it { should eq 1_435_809_600 }
context 'post' do
describe 'only date in filepath' do
let(:filepath) { 'post-with-date.md' }
it { should eq 1_521_414_000 }
end
describe 'date set in frontmatter' do
let(:filepath) { 'test-post.md' }
it { should eq 1_435_788_000 }
end
describe 'with a custom timezone' do
let(:site) { init_new_jekyll_site(timezone: 'America/New_York') }
let(:filepath) { 'test-post.md' }
it { should eq 1_435_809_600 }
end
end
context 'collection' do
describe 'no date defined' do
let(:filepath) { 'sample-item.md' }
it { should eq nil }
end
describe 'date in frontmatter' do
let(:filepath) { 'collection-item.md' }
it { should eq 452_469_600 }
end
end
end

View File

@ -2,7 +2,4 @@
title: Sample item
---
This collection item has no defined date. Jekyll will try to set the current
date instead, but we need to keep it nil. If we don't the `diff` indexing mode
will think that the item changed while it did not.
This collection item has no defined date.

View File

@ -0,0 +1,7 @@
---
title: "Post with date"
date: 2018-03-19
---
This post has a date set in the front matter different than the date set in the
filename.

View File

@ -3,7 +3,7 @@ title: Front-matter test
author: John Doe
custom: foo
slug: front_matter_test
date: foo
date: 2018-03-20
tags: foo
url: http://www.foo.com/
type: foo