Listing all Collections in Jekyll
Second first; that answer from @sparanoid is fantastic! And between that and the source code from the default Jekyll Theme (Minima), I was able to bodge some of what follows together.
First second; excellent question and how both are not up-voted more is a bit baffling.
And third of many other related points; I'm not on a identical path as the question's poster but the following code may be of use to readers. My use case was wanting a way of listing the continence of a collection similar to the default Jekyll home
layout.
_layouts/named_collection.html
Note the source links are downloadable via, clicking on the
Raw
link/button then Ctrl s to save as a regular text file, however, these links have been frozen in time so be sure to check thegh-pages
branch for updates. And output examples are intended in this case to be just examples of possible content, eg. it could be Lorem strings for all that it matters to demonstrate what's to follow.
---
layout: default
---
{% comment %}
License note from S0AndS0; an editor in this context.
Minima (where the following code is sourced from), is shared under the
MIT Lisense, https://github.com/jekyll/minima/blob/master/LICENSE.txt
Thus any alterations to Minima source code is re-shared under the MIT Lisense
{% endcomment %}
{% capture workspace_collections %}
{% assign collection_name = page.collection_name | default: include.collection_name | default: nil %}
{% assign target_collection = site[collection_name] %}
<div class="home">
{%- if page.title -%}
<h1 class="page-heading">{{ page.title }}</h1>
{%- endif -%}
{{ content }}
{% assign has_output = False %}
{%- if target_collection.size > 0 -%}
{% capture workspace_collection %}
<h2 class="post-list-heading">{{ page.list_title | default: "Posts" }}</h2>
<ul class="post-list">
{%- for post in target_collection -%}
{%- if page.relative_path == post.relative_path -%}
{%- continue -%}
{%- else -%}
{% assign has_output = True %}
{%- endif -%}
<li>
{%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
<span class="post-meta">{{ post.date | date: date_format }}</span>
<h3>
<a class="post-link" href="{{ post.url | relative_url }}">
{{ post.title | escape }}
</a>
</h3>
{%- if site.show_excerpts -%}
{{ post.excerpt | markdownify | remove: '<p>' | remove: '</p>' }}
{%- endif -%}
</li>
{%- endfor -%}
</ul>
{% endcapture %}
{%- if has_output == True -%}
{{- workspace_collection -}}{% assign workspace_collection = nil %}
{%- endif -%}
{%- endif -%}
</div>
{% endcapture %}{{ workspace_collections | strip }}{% assign workspace_collections = nil %}
Side note, I can't remember where I picked up that
capture
someworkspace_
trick, but it's pretty sweat forstrip
ping new lines and other formatting shenanigans. If a reader figures out who started such fanciness, please edit or leave a comment.
Usage of this layout is much like the usage of Minima's home.html
layout.
administration.md
... Front-Matter selecting from the _administration
collection looks like...
layout: named_collection
collection_name: administration
title: Administration
list_title: Usage Examples
permalink: /admin/
... resulting in a <base-url>/admin/
collection listing being output.
git_shell_commands.md
... Front-Matter selecting from the _git_shell_commands
collection looks like...
layout: named_collection
collection_name: git_shell_commands
title: Git Shell Commands
list_title: Usage Examples
permalink: /git_shell_commands/
... resulting in a <base-url>/git_shell_commands/
collection listing being output.
Even more notes on collections
If I'm reading the latest Jekyll Collections documentation correctly, as of version 3.7.0
it could be possible to have a custom collections directory, in the case of this question that might look like...
ls ~/git/magazine-name/
# ... other files and/or directories
# issues/
# ... other files and/or directories
# _config.yml
... where the issues/
directory contains sub-directories such as...
ls ~/git/magazine-name/issues/
# _001/
# _002/
# _003/
# ...
... and the _config.yml
file has...
collections_dir: issues
collections:
001:
output: True
# ...
... the magic sauce was collections_dir
and not using an under-scored prefixed base directory. The documentation was loud about that last bit, eg. _issues/
would make for a bad time.
I'm not sure if there'd be any other adjustments needed to the previously posted Liquid code (I don't think so, but probably); so maybe try'em out individually first.
Warning/Update
Jekyll does not take kindly to numbered collections, eg.
_000
will cause errors! To mitigate such issues be sure to trick Jekyll into treating collection names as strings, eg._i000
The reason I suggest using a collections_dir
, is because in the case of @James Dinsdale's question it may help in organizing things a bit more. Personally I wanted my gh-pages
branch collection to mirror some of the same paths as my project's master
branch, so didn't pursue testing collections_dir
suggestions.
Notes about my Liquid coding choices
Because I'm using the Minima theme I placed the files that used the named_collection
theme in my project's root directory; default behavior is to link to such pages
at the top of every page. Cheap navigation.
Because readers might place pages that use the named_collection
within the same directory as what is being listed, eg...
ls Jekyll_Admin/_administration/
# _administration/administration.md
# ...
... I've written the Liquid for some of the edge-cases, but may not have covered all of'em. Be sure to test privately before unleashing something like it on production.
Updates
After some testing with collections_dir
it looks like when used the _posts
directory must be moved to that directory too, eg...
_config.yml
(Snip)
collections_dir: misc
Bash commands
mkdir misc
mv _posts misc/
... though that's only applicable if using a _posts
directory.
Between the time of the last edit and when you're now reading this I've published liquid-utilities/collection-home
on GitHub; might be of use to those that want a version tracked solution and is what I'm currently using in any projects that require this feature.
In case for someone still has this request here's how it works in latest Jekyll (v3.8.3):
Update: tested it still works in v4.2.0
{% for collection in site.collections %}
<h2>Items from {{ collection.label }}</h2>
<ul>
{% for item in site[collection.label] %}
<li><a href="{{ item.url }}">{{ item.title }}</a></li>
{% endfor %}
</ul>
{% endfor %}
In {% for issue in site.collections %}
, issue
is an array that contains :
0 => "issue_001",
1 => Hash
{"output"=>true,
"permalink"=>"/:title/:path",
"title"=>"Rebirth",
"date"=>#,
"label"=>"issue_001",
"docs"=>[#],
"files"=>[],
"directory"=>"/home/djacquel/www/test.dev/jekyll/wat/_issue_001",
"relative_directory"=>"_issue_001"}
The right way to access datas is :
{% for issue in site.collections %}
<li>
<h6 class="post-meta">
Issue {{ issue[1].label }}
—
{{ issue[1].date | date: "%b %-d, %Y" }}
</h6>
<h2>
{{ issue[1].title }}
</h2>
</li>
{% endfor %}