0
votes

Short version: How do I reference a collection by variable in Liquid?

I'm building a site on Jekyll which is documentation with multiple different parts. It consists of collections of articles and there are no blogposts. Right now I have a three level menu structure defined with data files, where the third level is the actual articles. The data file look like this.

menu.yml

- title: Book
  url: book
  subpages: 
  - title: Volume 1
    url: book/vol1
  - title: Volume 2
    url: book/vol2
- title: The Library
  url: library
  subpages: 
  - title: Getting started
    url: library/getting-started
  - title: Components
    url: library/components
- title: Theme
  url: theme
  subpages: 
  - title: Tutorials
    url: theme/tutorials
  - title: Reference
    url: theme/reference

Additionally, I have collections defined that match the top level items by url.

_config.yml

...
collections:
  book:
    output: true
  library:
    output: true
  theme:
    output: true

Right now I use the menu YML to construct myself a nice two level structure and put the articles into them to form the third level. The problem is that I don't know how to call the collections dynamically when I am constructing the menu. For example when I am creating the 'Book' menu item, I'd like to loop over site.book data collection with something like this:

{% assign collection = 'book' %}
{% for p in site.{{collection}} %}
  <p>{{p.title}}</p>
{% endfor %}

site.{{collection}} doesn't work there but for example calling directly site.book does. I don't know how to pass the variable in Liquid.

What I do to get around this problem is that for every menu item that I create i loop through the whole {{site.pages}} which contains all the articles in the whole site, and match their url against the menu item url. These feels like bad programming on so many levels and I'm taking a huge performance hit when looping through everything multiple times. Generation of files goes up four times, from 5 seconds to 20 seconds right now, and it will get even worse when I make the menu even larger.

So I'm open to hearing how I could loop dynamically through the collections, or hearing about other options to create such a menu. As I have the relative url at hand, for example /book/vol1, the optimal would to find a way to get a reference to all articles within that folder (excluding those in subfolders but that is not a must-have).

1

1 Answers

2
votes

The syntax for using a liquid variable inside a liquid tag looks a bit different than {% for p in site.{{collection}} %}. You can try either:

{% assign collection = 'book' %}
{% for p in site.[collection] %}

or you simply use:

{% assign books = site.book %}
{% for p in books %}