'Force Jekyll to re-read files in a collection to _site after a Hook runs

I've written a Hook for my Jekyll site that takes a .json file from my _data directory, creates a bunch of .md files from it's content and stores them in a _collection.

The problem is by the time Jekyll executes this Hook it's done reading the _collection and so the new or updated files don't make it into _site.


So: I'm thinking I need a way to make Jekyll re-read the _collection after the Hook runs. Thus updating the necessary files in _site before render.


Here's my Hook

jekyll::Hooks.register :site, :post_read do |site|
  if site.data.has_key? 'projects'
    site.data['projects'].each do |project|
      File.open("./_projects/#{file_name}.md") do |file|
        # A bunch of YAML Front-Matter written to file.
      end
    end
  end
end

I believe :post_read is about as early as the Hook can run. Any earlier and site.data is empty.

I've already tried a Generator but the same problem occurred as "Generators run after Jekyll has made an inventory of the existing content".

I know I could have the files output directly into _site but there are a few reasons I don't want to do that.

  1. By outputting the files as .md with YAML Front-Matter to a _collection I can let Jekyll do the conversion and rendering to html. This seems practical, as that's what Jekyll is for.
  2. _site is always dumped, so by storing these files in a _collection they'll stick around. Just incase the .json file is't there or what ever.
    • Plus, eventually there will be some conditionals added to the Hook so only what needs updating or creating will be processed through the Hook. But I'd still want the existing files to be rendered to _site.

Also Just incase it's relevant:

  • The .json file will be automatically updated from a Google Spreadsheet whenever it (the Spreadsheet) changes. And then whenever the .json file changes Jekyll will need to update the site (thus running the Hook).
  • I'm currently developing locally, but the site will eventually be served up as a Gitlab Page.
  • This is my first time working with Jekyll, and I only started learning Ruby about a week ago. So please explain like I'm a total noob (as I am).


Update

Although I'm sure Jekyll will have a method for this, I have implemented a workaround for now.

projects = File.read('./_data/projects.json')
projects_file = JSON.parse(projects)
projects_file.each do |project|
  File.open("./_projects/#{file_name}.md", 'w+') do |file|
    # A bunch of YAML Front-Matter written to file.
  end
end
  • This script executes before Jekyll's :after_init event


Solution 1:[1]

--- The following is only an idea and is untested. ---

How about initializing a new Jekyll::Collection instance after all the "project" documents have been written to?

Jekyll::Hooks.register :site, :post_read do |site|
  if site.data.has_key? 'projects'
    site.data['projects'].each do |project|
      File.open("./_projects/#{file_name}.md") do |file|
        # A bunch of YAML Front-Matter written to file.
      end
    end

    # Re-read collections in this site
    Jekyll::CollectionReader.new(site).read
  end
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1