54

I'm writing a site in Jekyll, which uses Liquid.

I have front matter for pages that I'd like to look like this:

---
title: Designing algorithms that scale horizontally
speaker: Luke Ehresman, CopperEgg
category: notes.mongodallas.talks
links:
 - demo: http://www.github.com/copperegg/mongo-scaling-demo
layout: talknotes
---

In Liquid, the links section of YAML comes through as:

[{'demo' => 'http://www.github.com/copperegg/mongo-scaling-demo' }]

I'd like to be able to iterate over the array, doing something like this:

<a href="{{ link.value }}">{{ link.key }}</a>

But any ideas I've had so far have failed me.

Brian Hicks
  • 5,683
  • 7
  • 48
  • 75

3 Answers3

112

When you iterate over a hash using a variable called hash, hash[0] contains the key and hash[1] contains the value on each iteration.

{% for link_hash in page.links %}
  {% for link in link_hash %}
    <a href="{{ link[1] }}">{{ link[0] }}</a>
  {% endfor %}
{% endfor %}
kikito
  • 48,656
  • 29
  • 134
  • 183
  • The code works, just not like you seem to expect. Notice that I said *iterate over a hash*. I've added more code to give you context. – kikito Nov 29 '11 at 08:43
  • 4
    Well, now it indeed looks like an answer, not a telegram. Updated my vote to reflect that. – manatwork Nov 29 '11 at 09:25
  • I'm a bit confused by your snippet: can you just add `_hash` to your frontmatter variable to make it work? – Edward Jun 12 '17 at 16:16
  • @user3411192 Sorry I don't know what you mean. – kikito Jun 13 '17 at 08:48
  • where does this `hash ` variable come from? I used `item` in my solution, though Jekyll nor Liquid documents the variable for iterating over key/value pairs in list items. – Edward Jun 13 '17 at 19:42
  • 1
    On the question, the front matter has a "list of hashes" called `links`. The first loop iterates over that list (`page.links`), getting one hash each time. I called each of these hashes `link_hash`. To iterate over the keys of each `link_hash`, I need the second loop, in which I used `link`. On my example, `hash` is being played by `link`. – kikito Jun 13 '17 at 20:50
24

I would define them like this in YAML:

links:
  demo: http://www.github.com/copperegg/mongo-scaling-demo

And then iterate:

{% for link in page.links %}
  <a href="{{ link[1] }}">{{ link[0] }}</a>
{% endfor %}
yegor256
  • 93,933
  • 106
  • 409
  • 558
  • This is definitely the better way to go. The YAML in the question redundantly has a hash within a list under `links`. The list can be eliminated. The top answer is confusing because it tries to first iterate over the list, and then iterates over the hash, which is completely unnecessary, and which this answer avoids. – Praveen Jun 20 '20 at 23:30
0
  {% for link in page.links %}
      {% for item in link %}
        <a href="{{ item[0] }}">{{ link[1] }}</a>
      {% endfor %}
    {% endfor %}

I had a very similar issue, but I had multiple items in my variable so I used the undocumented item variable and it did the job.

Edward
  • 1,100
  • 9
  • 20