Reputation: 2871
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?
Upvotes: 5
Views: 2349
Reputation: 2871
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:
Upvotes: 5
Reputation: 4002
Well, if you don't need it to be a plugin, it can be put in your _config.yml
. For a plugin, you might need to append the hash to the site
variable.
I think that a generator would suffice. There is a page about plugins that you should take a look.
This is what I'd use (I can't test right now, so it might be wrong!):
module Jekyll
class ProjectsGenerator < Generator
safe true
def generate(site)
# This probably won't work.
site.projects = YAML::load(File.read('projects.yml'))
end
end
end
Anyway, I really think that if you don't need the extra complexity (having a separate file, creating a new plugin just for you, etc), just put the data in _config.yml
. Simplicity is good.
Hope that helps. :)
Upvotes: 0