How to paginate posts by author
Asked Answered
F

2

6

What I'm trying to do

Jekyll can use front matter variables like tags and categories and access them with site.tags and site.categories to iterate over them using liquid. Now my problem is that I can't do this with a custom front matter variable like author (as in site.authors) because Jekyll will not store it in a list format. This makes it very hard to paginate it.

The problem

Every solution I have looked at i.e.

requires me to hardcode a list of authors to _config.yml or some other .yml (i.e. in _data/authors.yml). The problem here is that I don't use a fixed list of authors. The authors list needs to get updated when I throw in another post with a front-matter tag author: exampleAuthor or a list of authors (as in multiple authors per post, as currently only possible with categories and tags as well), while the server is running. It works with tags and categories splendidly, but not with custom tags like authors.

The easiest solution would to have a site.authors list to iterate over and just extending it with a ruby plugin.

I haven't found a plugin that provides me with a solution and thinking this was a common problem that I'm probably not the first to have.

What I tried

I then looked at writing my own ruby plugin (Which is hard on it's own because of the lack of documentation. Maybe I'm to dumb to google, but the resources I found where very limited and hardly enough to guide you through the process) but there has to be a reason why this is so hard to do that makes all the existing solutions require hard-coding the author list in a .yml (or .json, but most people go with .yml for some reason).

Doing this is out of the question for me, since I want to only throw in posts with author names in it later on and manipulating a .yml (I am under the impression that .yml-files don't get compiled once the server is started, like _config.yml, correct me if I'm wrong) would be counterproductive because it requires you to restart the server to have them compiled.

Even very advanced plugins like jekyll-paginate-v2 (which I use successfully to paginate posts by tags and categories) don't have a solution to this, as shown by this issue. As per this issue, it is getting recommended to misuse the category variable to paginate by author. In my opinion, that is desperate workaround and too hacky to be considered.

I have found suggestions that it could also be done with collections, but this would again requiring to hard-coding the author list (again, I don't want that. I don't have a fixed list of authors. All of the author information has to come from the front-matter in the /_posts directory .md files) As of now I don't see how it can be done with collections. However I'm open to suggestions.

Edit: I found this dated issue on Jekylls github page which highlights that people are trying to do the same but to no avail. Has this become viable in the last 4 years?

Forethoughtful answered 8/8, 2018 at 10:19 Comment(7)
Can you update the question with an example of what are you trying to do? I'm not sure I am understanding it right but it seems that you need a _data/authors.yml file with author usernames as indexes, then in your posts you just add the author username to an author attribute in front matter, and each post will have its own author metadata.Monaxial
Do yml files get updated while the server is running?Forethoughtful
for example? Jekyll is a static website generator, the static part means you have to update them by hand.Monaxial
not at all. The server can update the html files in the _site directory in real time if you add posts to the _posts directory. No need to restart the server. I don't know if this is possible with .ymls, since _config.yml is not getting recompiled for technical reasons. In Terms of examples, I'd like to paginate authors. What to you mean, example? It is not hard to imagine what I mean by that. How well do you know Jekyll? No offence.Forethoughtful
I guess that you said "no offence" because you know it was offensive? Please have a look at stackoverflow.com/conduct and jekyllrb.com/docs/usageMonaxial
I`m sorry, can you clarify what your question is?Forethoughtful
stop making trivial edits to your question. It only serves to keep bumping the question.Fang
S
2

For someone still looking for a way to

  • Generate author pages automatically just by dropping author: name to post front matter,
  • Have pagination on the author pages (a good optimization).

I built a plugin jekyll-auto-authors that works in sync with jekyll-paginate-v2 to enable author auto pages along with pagination.

I wrote this guide and made this video to help with the setup.

The bare minimum setup instructions:

Install the plugin:

group :jekyll_plugins do
  # other gems
  gem "jekyll-paginate-v2" # reqiured for jekyll-auto-authors to work
  gem "jekyll-auto-authors"
end

Enable it:

plugins:
  # other plugins
  - jekyll-paginate-v2
  - jekyll-auto-authors

Make a data file with author data, for example using _data/authors.yml:

johndoe:
  name: "John Doe"
  bio: "John Doe is a software engineer."
  email: "[email protected]"
  socials:
    github: "john-doe"
    twitter: "john_doe"

janedoe:
  name: "Jane Doe"
  bio: "Jane Doe is a systems engineer."
  email: "[email protected]"
  socials:
    github: "jane-doe"
    twitter: "jane_doe"

Make a layout for the author page, let's say _layout/author.html. Example layout can be taken from the article.

Enable pagination and auto pages for authors in _config.yml file:

pagination:
  enabled: true
  per_page: 9
  permalink: '/page/:num/'
  title: ':title - page :num'
  sort_field: 'date'
  sort_reverse: true

autopages:
  enabled: true

  # enable auto pages for tags/categories/collections as per need. Disabling for this demo.
  tags:
    enabled: false
  categories:
    enabled: false
  collections:
    enabled: false

  authors:
    enabled: true # adding false here stops the auto-generation
    data: '_data/authors.yml' # Data file with the author details
    layouts: 
      - 'author.html' # We'll define this layout later, will be used for each author
    title: 'Posts by :author'
    permalink: '/author/:author/'
    slugify:
      mode: 'default' # choose from [raw, default, pretty, ascii or latin]
      cased: true # if true, the uppercase letters in slug will be converted to lowercase ones.

That's the initial setup!

Now drop in the author value in the front matter of posts:

---
# other configs
author: johndoe
---

This will generate a page as defined in the permalink block of the auto pages configuration. If there's pagination enabled, and per_page value is exceeded, the additional pages will be generated in /page/:num/ format.

To render the author values, the plugin exposes page.pagination.author_data value

{% assign author = page.pagination.author_data %}

<!-- Use {{ author.name }} or any such value, as defined inside the data file -->

To show next and previous buttons, you can use this logic that paginator exposes:

{% if paginator.total_pages > 1 %}
<ul>
  {% if paginator.previous_page %}
  <li>
    <a href="{{ paginator.previous_page_path | prepend: site.baseurl }}">Newer</a>
  </li>
  {% endif %}
  {% if paginator.next_page %}
  <li>
    <a href="{{ paginator.next_page_path | prepend: site.baseurl }}">Older</a>
  </li>
  {% endif %}
</ul>
{% endif %}

The initial setup is overwhelming, but once done you can then just drop in author data inside _data/authors.yml file and add author: value inside post frontmatter and it is fairly easy then!

P.S. I developed this solution for Genics Blog as managing multiple authors got hard. To learn how I've implemented it at Genics, please check out the theme-files repository.

Update

I released v1.0.1 just now, which makes adding the data parameter to author autopage configuration optional.

If data isn't defined, you can still access the author username string with page.pagination.author. You can use it to show the username on the page.

If data is defined, page.pagination.author_data variable is available. This would be a hashmap that has data as defined in the data file.

This means that you just have to:

  • Add and enable the plugin.
  • Set up pagination and author pages config.
  • Make a layout file.

And you can just drop in author: username to post files to generate autopages for them with pagination!

Speechmaker answered 11/4, 2022 at 7:0 Comment(2)
Would it also be possible to forego the authors.yml and have all the authors into in the blog posts front matter?Forethoughtful
@Forethoughtful Released v1.0.1 and updated answer. I think this is the set up that you intended to have 🚀 If this is exactly what you wanted, please mark it as accepted :)Speechmaker
P
2

Adding authors to Jekyll posts is easy with collections. Here's a proof of concept for you. Specifically, in this commit I add everything you need for it.

As for your question about pagination, will need to use a pagination plugin (paginate-v2 is good), as I believe the built in pagination only supports the posts collection.

Palmore answered 18/8, 2018 at 21:24 Comment(7)
I found the suggestions about collections too, but again, I need to hardcode the list of authors into _config.yml, which I simply can't do. I don't have a fixed list of authors. I'm 70% sure collections are not feasible in my case. The gh link is broken btwForethoughtful
It's possible I misunderstand what you're trying to accomplish. Note that in my example, the authors list is based on whatever you put in the collection, not what is in the config. If your goal is to infer the list of authors based on the author value in each post, and you want it to be 100% dynamic, I'd recommend writing a plugin. You'll want to map the post list, extract the authors, and then use the plugin to generate whatever sort of data you need. The Generators example is a good starting place for how to generate pages with a plugin jekyllrb.com/docs/plugins/#generatorsPalmore
Is your commit to a private repo (it's giving me a 404 FSR)? I'd really like to take a look at it and report back, rather then speculating about it. Also welcome on SO btw. About time you joined the frenzyForethoughtful
Whoops, I swear I made it public. Have another look.Palmore
I made a couple edits to add some functionality, so here's a better commit for you: github.com/cameronmcefee/jekyll-authors/commit/…Palmore
Good stuff. I don't see any red flags ATM other than that I now need to store every post twice. Once for _posts and once for the author_posts which is kind of violating DRY but heck I'll take it. The posts will get populated by crawlers eventually, so whatever. I'll report back once I get to try to implement it. The glory about it is that it doesn't need another plugin, since multiple pagination plugins don't go well together and paginate-v2 is especially picky. ty!Forethoughtful
Why would you need to store the posts twice? In the example there is only one source of posts and you can see all posts by an author at /authors/author-name/, which uses the author template to render a list of their posts: github.com/cameronmcefee/jekyll-authors/blob/master/_layouts/…Palmore
S
2

For someone still looking for a way to

  • Generate author pages automatically just by dropping author: name to post front matter,
  • Have pagination on the author pages (a good optimization).

I built a plugin jekyll-auto-authors that works in sync with jekyll-paginate-v2 to enable author auto pages along with pagination.

I wrote this guide and made this video to help with the setup.

The bare minimum setup instructions:

Install the plugin:

group :jekyll_plugins do
  # other gems
  gem "jekyll-paginate-v2" # reqiured for jekyll-auto-authors to work
  gem "jekyll-auto-authors"
end

Enable it:

plugins:
  # other plugins
  - jekyll-paginate-v2
  - jekyll-auto-authors

Make a data file with author data, for example using _data/authors.yml:

johndoe:
  name: "John Doe"
  bio: "John Doe is a software engineer."
  email: "[email protected]"
  socials:
    github: "john-doe"
    twitter: "john_doe"

janedoe:
  name: "Jane Doe"
  bio: "Jane Doe is a systems engineer."
  email: "[email protected]"
  socials:
    github: "jane-doe"
    twitter: "jane_doe"

Make a layout for the author page, let's say _layout/author.html. Example layout can be taken from the article.

Enable pagination and auto pages for authors in _config.yml file:

pagination:
  enabled: true
  per_page: 9
  permalink: '/page/:num/'
  title: ':title - page :num'
  sort_field: 'date'
  sort_reverse: true

autopages:
  enabled: true

  # enable auto pages for tags/categories/collections as per need. Disabling for this demo.
  tags:
    enabled: false
  categories:
    enabled: false
  collections:
    enabled: false

  authors:
    enabled: true # adding false here stops the auto-generation
    data: '_data/authors.yml' # Data file with the author details
    layouts: 
      - 'author.html' # We'll define this layout later, will be used for each author
    title: 'Posts by :author'
    permalink: '/author/:author/'
    slugify:
      mode: 'default' # choose from [raw, default, pretty, ascii or latin]
      cased: true # if true, the uppercase letters in slug will be converted to lowercase ones.

That's the initial setup!

Now drop in the author value in the front matter of posts:

---
# other configs
author: johndoe
---

This will generate a page as defined in the permalink block of the auto pages configuration. If there's pagination enabled, and per_page value is exceeded, the additional pages will be generated in /page/:num/ format.

To render the author values, the plugin exposes page.pagination.author_data value

{% assign author = page.pagination.author_data %}

<!-- Use {{ author.name }} or any such value, as defined inside the data file -->

To show next and previous buttons, you can use this logic that paginator exposes:

{% if paginator.total_pages > 1 %}
<ul>
  {% if paginator.previous_page %}
  <li>
    <a href="{{ paginator.previous_page_path | prepend: site.baseurl }}">Newer</a>
  </li>
  {% endif %}
  {% if paginator.next_page %}
  <li>
    <a href="{{ paginator.next_page_path | prepend: site.baseurl }}">Older</a>
  </li>
  {% endif %}
</ul>
{% endif %}

The initial setup is overwhelming, but once done you can then just drop in author data inside _data/authors.yml file and add author: value inside post frontmatter and it is fairly easy then!

P.S. I developed this solution for Genics Blog as managing multiple authors got hard. To learn how I've implemented it at Genics, please check out the theme-files repository.

Update

I released v1.0.1 just now, which makes adding the data parameter to author autopage configuration optional.

If data isn't defined, you can still access the author username string with page.pagination.author. You can use it to show the username on the page.

If data is defined, page.pagination.author_data variable is available. This would be a hashmap that has data as defined in the data file.

This means that you just have to:

  • Add and enable the plugin.
  • Set up pagination and author pages config.
  • Make a layout file.

And you can just drop in author: username to post files to generate autopages for them with pagination!

Speechmaker answered 11/4, 2022 at 7:0 Comment(2)
Would it also be possible to forego the authors.yml and have all the authors into in the blog posts front matter?Forethoughtful
@Forethoughtful Released v1.0.1 and updated answer. I think this is the set up that you intended to have 🚀 If this is exactly what you wanted, please mark it as accepted :)Speechmaker

© 2022 - 2024 — McMap. All rights reserved.