I'm trying to create a list for the posts each author has written. This is a problem since each post should be able to specify multiple authors.
Let's say we have 3 posts in total and 3 authors in total.
Edit 1: as suggested in the answers this is best done by listing the authors in a front matter list instead of a CSV string. So,
Like this
Post:
---
title: post
authors:
- foo
- bar
---
instead of like this:
Post:
---
title: post
authors: [foo, bar]
---
(edited, according to Edit 1)
Post 1:
---
title: post1
authors:
- foo
- bar
---
Post 2:
---
title: post2
authors:
- foo
- bar
---
Post 3:
---
title: post3
authors:
- john doe
- bar
---
Out:
bar (3)
john doe (1)
foo (2)
A click on the author should then result in all posts getting displayed.
Alternatively an array can be displayed like this, but it's not helping the case, just an equivalent style.
I did the same with categories and tags and this algorithm worked like a charm. However, replacing site.categories
with site.authors
is somehow not supported.
returns:
Liquid Exception: 0 is not a symbol nor a string in authors.html
I suppose this is due to the nature of categories
and tags
being arrays by default.
I think it would help to be able to set the front matter tag authors
as an array somehow. I suppose this is done in _config.yml, but I busted by head in with it.
As of now I got as far as coming up with a way to target individual authors in an array, but I'm far from being able to list them individually and counting them up. I suppose I'm limited due to the nature of authors not being an array by default, otherwise implementations like this one would work with custom front matter variables like authors
, but they don't.
What I meant (when I said "As of now"):
{% for post in site.posts %}
<li><a href="{{ SITEURL }}/{{ author.url }}">{{ post.authors }}</a> ({{ post.authors[0] }})</li>
{% endfor %}
Out:
foobar (foo)
foobar (foo)
john doebar (john doe)
Afterall, I think I'm missing something here. I'm probably not the first one who tried this but the only documentation I found was from people who attempted what I'm trying but didn't really get there.
This user for example created a way to count users, but when used with site.authors
it returns the array size == 0
-if clause:
No author
It seems like a simple thing, but for some reason isn't. At least for me.
Edit 2:
based on Kieths answer I came closer to getting there, but I have issues with creating an emphty array. According to this issue in Jekyll this seems to be a problem in general. However a workaround seems to be to assign a variable and split it with an emphty tag. Currently I struggle with adding authors to the array so I can assess it's size.
{% assign authors = site.posts | map: 'authors' | uniq %}
{% assign authorCount = '' | split: '' %}
<div class="softwaretitle">
{% for author in authors %}
<a>{{ author }}</a>
{% for post in site.posts %}
{% for post_author in post.authors %}
{% if post_author == author %}
{% assign authorCount = authorCount | push author %}
<a>({{ page.authorCount | size }})</a>
{% endif %}
{% endfor %Edit 2:}
{% endfor %}
{% endfor %}
</div>
Out:
Error: Liquid error (.../_includes/authors.html line 14): wrong number of arguments (given 1, expected 2) included Error: Run jekyll build --trace for more information.
Line 14:
{% assign authorCount = authorCount | push author %}
Edit 3:
At last, the final result (without link to the post list, but thats details)
<!-- Get a list of unique authors -->
{% assign authors = site.posts | map: 'authors' | uniq | sort%}
{% assign author_post_count = 0 %}
{% for author in authors %}
{% assign author_post_count = 0 %}
<div class="">
<li><a>{{ author }}
{% for post in site.posts %}
{% for post_author in post.authors %}
{% if post_author == author %}
{% assign author_post_count = author_post_count | | plus: 1 %}
{% endif %}
{% endfor %}
{% endfor %}
<span>  ({{ author_post_count }})</span></a></li>
</div>
{% endfor %}
Out:
bar (3)
john doe (1)
foo (2)
Updated answer:
To get a list of authors (without duplicates) and including the total number of posts the author has contributed to, together with a list of posts' titles and a link to the posts.
{% assign authors = site.posts | map: 'authors' | uniq %}
{% for author in authors %}
{% assign author_post_count = 0 %}
{% for post in site.posts %}
{% if post.authors %}
{% for post_author in post.authors %}
{% if post_author == author %}
{% assign author_post_count = author_post_count | plus: 1 %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
<h2>{{ author }} - {{ author_post_count }}</h2>
{% for post in site.posts %}
{% if post.authors %}
{% for post_author in post.authors %}
{% if post_author == author %}
{% assign author_url_query = author | replace: ' ', '-' %}
<a href="{{ post.url }}" title="A posts {{ author }}">
{{ post.title }}
</a>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
If instead, you want to have a page per author that includes a list of posts written by them (automatically generated), you will need to extend Jekyll through a custom plugin. This is very possible if you have experience with the Ruby programming language. This is a very close example: https://github.com/avillafiorita/jekyll-datapage_gen and you can simply remove the _config
data requirements and hardcode the directory names and permalinks :)