I have some content originating from yaml and markdown in the normal Jekyll pattern.
I also have various content pulled in from an API that I access via Jekyll data. For example, I can link a page to its related data file with the following.
sita.data.API[page.api-id]
This is working quite nicely. However, I only use say the image from the site.data if there is none available in front-matter. I have achieved this but have all sorts of if statements in my template to control the output of say a URL to an image.
I've attempted to put in an include but this led to trouble when looping over site.pages, for example, outputting thumbnails for a collection of posts.
I really want to pull the data from site.data into the page's Jekyll model. So that all of the default values and other logic can be hidden from the templates. I can iterate over site.pages without having lots of copy and paste code scattered across the site or attempting to push the include tag beyond what it was designed for.
Is this something that can be done with a plugin?
Failing that, I could use a gulp or other build step that merged the data from the markdown files and the site.data into the third set of files - probably markdown? This solution feels like a step away from Jekyll towards using something like gatsby.
As per the Jekyll docs
... a generator [plugin] can inject values computed at build time for template variables.
There are some quite usable examples on the page as linked.
module Composite-model
class Generator < Jekyll::Generator
priority :lowest
def generate(site)
# get the target from collections.
# you could also target site.page or site.post with various filters.
customCollection = site.collections['my-collection']
customCollection.each do |item|
# Get data from another source and link on id.
apiId = item["api-id"].to_s
apiData = site.data["api"][apiId]
# attach data to collection item
item.data['api-data'] = apiData
# please forgive the messy logic, first bit of ruby.
# Will refactor and update
if apiData && apiData["images"]
singleImage = apiData["images"].length == 1
item.data['single-image'] = singleImage
if item["custom-image"].to_s.strip.empty?
imageUri = apiData['images'][0]['uri'].split('/').last
image = File.join("/assets/images/", apiId, imageUri)
item.data['image'] = image
else
item.data['image'] = item["custom-image"]
end
else
item.data['image'] = item["custom-image"]
end
end
end
end
end
N.B It looks like you can not overwrite a page variable from within a generator plugin. For example, I first tried to transform item.image directly from the front-matter. However, this did not work so have page front matter use custom-image and then image is first used by this generator. Might be worth a different question.