Get a hash into a Jekyll Liquid template from a Plugin for use in the FOR loop?
jekyll, liquid, ruby, yaml
Solution
Here's the solution that I came up:
A Jekyll Plugin that create's a Liquid Tag: `yaml_to_liquid`. This plugin parses the yaml file into a hash and then adds it to the Jekyll `page` variable.
module Jekyll
class YamlToLiquid < Liquid::Tag
def initialize(tag_name, arg, tokens)
super
if arg.length == 0
raise 'Please enter a yaml file path'
else
@yml_path = arg
end
end
def render(context)
yml = YAML::load(File.read(@yml_path))
context.registers[:page]['yml'] = yml
end
end
end
Liquid::Template.register_tag('yaml_to_liquid', Jekyll::YamlToLiquid)
To use it. Place the tag at the top of your `.html` or `.md` page just below the Yaml Front Matter and then access the `yml` variable as usual. This loop will only output the `code` hash (allows you to access the whole hash or just sub-hashes):
---
layout: page
---
{% yaml_to_liquid work/_projects.yml %}
<ul>
{% for n in page.yml.projects.code %}
<li>
<a href="{{ n.url }}">{{ n.title }}</a>
</li>
{% endfor %}
</ul>
Example of `work/_projects.yml`:
projects:
code:
- title:
url:
- title:
url:
websites:
- title:
url:
- title:
url:
Problem
This one's got me stumped... I'd like to share a YAML hash from a single file among a few other Jekyll pages. I know you can put it in the Front Matter (which would require duplicating it), and I know you can generate (write) pages via a plugin (but I'm using it in a few different types of pages, which would be complex). Neither is what I'm looking for. I'd like to loop over the hash with Liquid in my pages, but I can't seem to get the hash from the plugin to Liquid. `{% capture %}` only works with strings and `{% assign %}` won't let you call a tag within itself, like `{% assign projects = gethash %}` where `gethash` is a custom Liquid tag. Basically, I'd like to use the separate YAML file like a text-based database. YAML File has this in it: ``` projects: category1: - title: Project 1 desc: Description etc... - title: Project 2 etc... category2: - title: Project 3 desc: Description etc... - title: Project 4 etc... ``` Plugin is calling (which gives a Ruby Hash of the YAML): ``` def... YAML::load(File.read('projects.yml')) end... ``` And in template, I want to: ``` {% for p in projects %} ... ``` This should be really simple, but it's one of those Liquid things that is a pain. How can you get a hash into Liquid from a plugin for use in the `{% for %}` loop?