This problem is bothering me for a while now.
The generated Jekyll site does show the right collections and all it's info on the desired pages. But all collections other than the (default) posts
collection can't be used in a ruby plugin.
Case:
We have a blog site using Jekyll.
To enrich the blog posts with author info and vice-versa there are some custom plugins using Jekyll::Hooks.register
The blog posts are written in markdown language and all contain some info in YAML format:
---
layout: post
authors: [author]
title: 'title'
intro: a short intro text
image: /path/to/image.png
tags: [jekyll, collections]
category: Programming
comments: true
---
This is the code for enriching the post with author information:
Jekyll::Hooks.register :site, :post_read do |site|
puts 'Enriching posts with link to authors'
site.posts.docs.each { |post|
post.data['authors'].collect! { |author_username|
site.data['authors'][author_username]
}.compact!
}
end
Next step:
I updated the site with two more collections since we also want to show the training courses and talks that will be given.
Both collections contain a few files in markdown format with a same kind of YAML info at the top of the file.
--- ---
layout: talk layout: training
speakers: [author] trainers: [author]
title: Title title: Title
subtitle: Subtitle subtitle: Subtitle
duration: 120 minutes duration: 180 minutes
level: beginner level: intermediate
image: /path/to/image.png image: /path/to/image.png
tags: [] tags: []
category: Talks category: Training
comments: false comments: false
--- ---
And I added the collections to the _config.yml
collections:
training:
output: true
permalink: /training/:path/
talks:
output: true
permalink: /talks/:path/
defaults:
- scope:
path: "training"
type: training
values:
layout: training
- scope:
path: "talks"
type: talks
values:
layout: talk
Desired implementation:
Now I want to enrich the talks and training courses with the authors as well.
Since the posts, talks and training files are all in a collection, I assume that changing the posts
object to talks
or training
should obtain the desired objects and loop through them.
So I changed the custom plugin to this:
Jekyll::Hooks.register :site, :post_read do |site|
puts 'Enriching posts with link to authors'
site.posts.docs.each { |post|
post.data['authors'].collect! { |author_username|
site.data['authors'][author_username]
}.compact!
}
site.talks.docs.each { |talk|
talk.data['authors'].collect! { |author_username|
site.data['authors'][author_username]
}.compact!
}
end
But then I get this error:
jekyll 3.7.3 | Error: undefined method `talks' for #<Jekyll::Site:0x00007f9325268e90>
The thing that is bothering me is that when I log the collection contents I get the following result: (formatted to json structure for better readability)
{
"posts"=>
#<Jekyll::Collection @label=posts docs=[
#<Jekyll::Document _posts/2017-02-01-page1.md collection=posts>,
#<Jekyll::Document _posts/2017-02-02-page2.md collection=posts>,
#<Jekyll::Document _posts/2018-04-04-page3.md collection=posts>
]>,
"training"=>
#<Jekyll::Collection @label=training docs=[
#<Jekyll::Document _training/page1.md collection=training>,
#<Jekyll::Document _training/page2.md collection=training>,
#<Jekyll::Document _training/page3.md collection=training>
]>,
"talks"=>
#<Jekyll::Collection @label=talks docs=[
#<Jekyll::Document _talks/page1.md collection=talks>,
#<Jekyll::Document _talks/page2.md collection=talks>,
#<Jekyll::Document _talks/page3.md collection=talks>
]>
}
As far as I can tell, both the talks
and the training
collection are in the same level and data structure as the posts
collection.
Question:
How can I accomplish to obtain the talks/training collection in my custom plugin so I can enrich the data with the author information.
I reduced the files and output for readability. Full codebase is available at GitHub