Publishing a linked folder in Jekyll
I use markdown to take notes. I wanted to publish a part of those notes using Jekyll.
The obvious way to do this is to just copy the files to the _posts
directory.
This would mean I’d have to keep the files in sync and copy-paste them back and forth whenever I made any changes. Not ideal.
I figured I could make _posts
a symbolic link to the directory with the notes. Then I’d (somehow) use the Jekyll pre_render
hook to filter the posts to only the files I wanted to publish.
This is what I came up. It filters to only the documents that I wanted to publish. It also does some housekeeping to automate converting the notes to posts.
# _plugins/filter.rb
module Filter
def self.process(site, payload)
site.collections['posts'].docs.select!{|x| x.data['slug'].include? 'files-to-publish'}
site.collections['posts'].docs.each do |x|
x.data['slug'] = x.data['slug'].gsub("files-to-publish", "")
x.data['permalink'] = x.data['slug']
x.data['layout'] = 'post' if !x.data['layout']
end
end
end
Jekyll::Hooks.register :site, :post_read do |site, payload|
Filter.process(site, payload)
end
What it does
All the notes that I wanted to publish had filenames in the format files-to-publish.actual-note-slug.md
. This removes any files that don’t follow that.
site.collections['posts'].docs.select!{|x| x.data['slug'].include? 'files-to-publish'}
Then I loop through all the remaining posts.
site.collections['posts'].docs.each do |x|
And set the slug to be just the final part of the name.
x.data['slug'] = x.data['slug'].gsub("files-to-publish", "")
x.data['permalink'] = x.data['slug']
And then set the notes to use the post
layout. Most notes didn’t have any layout set, but for a couple I specifically set them to use a different one.
x.data['layout'] = 'post' if !x.data['layout']
Finally register the hook to run before the rendering starts.
Jekyll::Hooks.register :site, :pre_render do |site, payload|
Filter.process(site, payload)
end
This way I don’t have to keep the notes in sync and any notes that I add will be automatically added to the site.
Update
I’ve reworked this to so that the external notes are combined into the _posts
collection. And I’ve changed the hook to run on post_read
rather then pre_render
.
Jekyll::Hooks.register :site, :post_read do |site, payload|
Filter.process(site, payload)
end
Further update
(new_doc
is x
in the code above)
I’ve also added the ability to fix links between files as well as correctly embed images.
new_doc.content.gsub!("", "")
new_doc.content.gsub!(/\[(.+)\]\(..\/(.+)\/(.+)\.md\)/, '[\1](/\3)')
I do still have to copy the images to the blog. At the moment I think this is a good thing because I make them smaller for the blog but the notes use the full resolution ones.
Yet another update
I’ve also added the ability to have parts of the markdown file excluded from being generated in Jekyll:
new_doc.content = new_doc.content.split("< !-- exclude -->").map{|x| x.split("< !-- include -->")}.select{|x| x.size > 1}.map{|x| x[1]}.join("")
Note the space in <!-- exclude-->
. This is due to because the syntaxt highlighter plugin renders each term within a span
which the interprets the rest of <!-- exclude-->
as a comment.