Created
March 10, 2017 07:33
-
-
Save dgopstein/7fcb514d163f7b090edd5a98b9f3f9a7 to your computer and use it in GitHub Desktop.
Jekyll Plugin for Textual Inclusion in Data Files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Treat every _data file as liquid. | |
# This allows us to include YAML files in other YAML files. | |
module Jekyll | |
# Monkey patch Jekyll::DataReader::read_data_file with our own implementation | |
class DataReader | |
def read_data_file_with_liquid(path) | |
begin | |
dir = File.dirname(path) | |
filename = File.basename(path) | |
# If there are multiple sites assume we're | |
# the most recent since we're just starting up | |
site = Jekyll.sites.last | |
content = File.read(site.in_source_dir(dir, filename)) | |
template = Liquid::Template.parse(content) | |
context = Liquid::Context.new({}, {}, { :site => site }) | |
rendered = template.render(context) | |
# Write the post-liquid-rendered file to a temporary file. | |
# read_data_file parses the name of the file to use as its | |
# variable name in site.data so it's important to make the | |
# temp file name match the original file name. | |
Dir.mktmpdir do |tmp_dir| | |
tmp_path = File.join(tmp_dir, filename) | |
File.write(tmp_path, rendered) | |
read_data_file_without_liquid(tmp_path) | |
end | |
rescue => e | |
Jekyll.logger.warn( | |
"[Liquid Data] Error parsing data files " + | |
"for Liquid content at file #{path}: #{e.message}") | |
end | |
end | |
# Make our function overwrite the existing read_data_file function | |
# but keep the ability to still call back to the original | |
alias_method :read_data_file_without_liquid, :read_data_file | |
alias_method :read_data_file, :read_data_file_with_liquid | |
end | |
end | |
# Only include the given file one time (in this call tree) | |
# Useful for files that include files that include the original file | |
module Jekyll | |
module Tags | |
class IncludeRelativeOnceTag < IncludeRelativeTag | |
# Create a flag that indicates we're already 1 level | |
# deep in the inclusion, and don't go any farther down | |
SENTINEL = 'included_relative_once' | |
def render(context) | |
context.stack do | |
unless context[SENTINEL] | |
context[SENTINEL] = true | |
super(context) | |
end | |
end | |
end | |
end | |
end | |
end | |
Liquid::Template.register_tag("include_relative_once", Jekyll::Tags::IncludeRelativeOnceTag) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@dgopstein - Hey! I've been looking for a solution to this problem for ages and so far, this is the closest and best thing I've found. Thanks for putting this together and sharing it :)
I'm not a developer at all - I use Jekyll to write and manage my company's documentation. So while I dabble in Ruby, calling myself proficient would be generous. That being said, I hope you don't mind answering a few questions:
_data
as a Liquid file - is there a way to exclude files from being read this way? In my setup, I have a lot of data files that don't need this functionality, which is throwing a ton of errors when I start up the server._data
? In my case, I set up a collection that contains files with data about database schemas. This is the only place in my site that I'd like to use this.Thanks :)