In this tutorial, I will instruct you about how to create a page to show all of an author’s posts, without using any plugins.
This post was inspired by the Jasper2 theme, which is a port of Ghost’s Casper theme. In that theme, the author pages are generated by a plugin, which can be inconvenient.
This guide will walk you through how to setup an equivalent system without using a plugin.
Setup
This guide takes advantage of Jekyll’s Collections feature, and the fact that every item in a collection can be made to output a page.
Config
Open your _config.yml
and add the following:
collections:
authors:
output: true
permalink: author/:title/
defaults:
-
scope:
path: ""
type: authors
values:
layout: author
The first block (collections
) defines authors
as a new collection. It says that the files should be output (meaning that all files in the _authors/
directory map to pages on your site), and that the url for those pages should be your.website.url/author/title-of-your-file/
The second block (defaults
) says that all posts with the type authors
(ie, anything in the authors
collection) should use the author
layout.
Author Files
Now, let’s create a file in our collection that tells Jekyll about one of our authors.
Create the _authors
directory, and create a new file in that directory username.md
, where username
is the name that will be used in the url. I want my url to be /author/jetroid/
, so I’m going to create jetroid.md
.
Now, the specifics of what you want to put in this file will vary depending on what you want to display on your author’s pages. Here’s the setup that I’m using, which includes real names, location, personal sites URL, a short bio, a path to a picture, and social media usernames. Don’t feel restricted by what to include here; use whatever your site needs!
---
username: jetroid
name: Jet A. Holt
location: Earth 🌏
url_full: https://jetholt.com/
url_short: jetholt.com
bio: I'm Jet, a CS graduate who enjoys working on his own projects. I'm known for my Eurorack synth modules.
picture: assets/images/jet.jpg
facebook: Jetroid
twitter: jetroidmakes
instagram: jetroidmakes
---
You’ll need to create a file like this for every author on your site. Remember to create new files when adding new authors!
Specify Author Of Posts
This bit is simple!
Simply add authors: jetroid
to the front matter of your post. Be sure to replace jetroid
with the username of your author. If you have more than one author, you can create an array like this:
authors: [jetroid, jekyll, hyde]
Once done, your front matter might look something like this:
---
layout: post
title: Jekyll Author Pages
date: 2020-05-10 22:41:40 +0100
authors: jetroid
---
TIP: You can add the following to your _config.yml
’s defaults
section to have your posts default to a specific author. (You can still use a different author in individual posts using the authors
front matter variable.)
-
scope:
path: ""
type: post
values:
author: jetroid
Be sure to replace jetroid
with the username of your author!
Edit Templates
By now, we’re set up, and Jekyll knows information about our authors, and who authored which posts.
We need to display that information in the HTML of our site!
Post Written By
Let’s start by editing the template used for our posts. On my site, posts use the post.html
layout (in the _layouts/
directory), so I’ll be editing that.
Everyone’s post.html
layout will be different, so I can only provide some code here.
Modify these snippets and include them wherever you want to link to the author of a post. This will probably be in post.html
layout, and perhaps even somewhere in your index.html
to.
NB: You may have to change post
to page
to get these snippets to work!
Simple Snippet
This first simple snippet simply writes each author’s names (as hyperlinks to their author pages) to new lines, similar to the below:
This simpler example is easier for you to modify to add your own customisations, like a personal image for each author.
{% for author in site.authors %}
{% if post.authors contains author.username or author.username == post.authors %}
<a href="{{ site.url }}{{ site.baseurl }}/author/{{ author.username }}">{{ author.name }}</a>
{% endif %}
{% endfor %}
It simply iterates through every author that jekyll knows about, and if they were one of the authors of our post, creates a new link to them.
Complex Snippet
This more complex snippet writes Written by Jet A Holt, Dr. Jekyll, and Mr. Hyde
, where each name is a hyperlink to that author’s page.
{% assign authordata = '' | split:'@' %}
{% for author in site.authors %}
{% if post.authors contains author.username or author.username == post.authors %}
{% capture data %}
<a href="{{ site.url }}{{ site.baseurl }}/author/{{ author.username }}">{{ author.name }}</a>
{% endcapture %}
{% assign authordata = authordata | push: data %}
{% endif %}
{% endfor %}
<p>Written by {{ authordata | array_to_sentence_string }}</p>
It does much the same as the first snippet, but creates an array and pushes our data into it. In this case, the data is our author’s name and the hyperlink. At the end, we print the contents of the array as a ‘sentence string’, which adds punctuation (and the word ‘and’) to it as necessary.
Author Template
Next, we want to create the template for our author pages. This will be the template that is rendered when we go to the /author/jetroid/
URL.
Again, this will vary drastically from site to site, so I will just be including some useful snippets.
Note that all of the fields you created in your _authors/username.md
file are accessible here using the page
variable. For example, jetroid
’s page.name
is Jet A. Holt
.
Header, Photo, Bio
We’ll start with something easy, simply pasting their photo, name, and bio to the page:
{% if page.picture %}
<img class="author-profile-image" src="/{{ page.picture }}" alt="{{ page.name }}" />
{% endif %}
<h1 class="site-title">{{ page.name }}</h1>
{% if page.bio %}
<h2 class="author-bio">{{ page.bio }}</h2>
{% endif %}
{% if page.location %}
<div class="author-location">{{ page.location }}</div>
{% endif %}
Links to all of their posts
We might want to create a list of all of their posts.
This snippet filters all the posts to just include the ones written by the author, and includes a link to the post.
{% for post in site.posts %}
{% if post.authors contains page.username or page.username == post.authors %}
<a href="{{ site.url }}{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>
{% endif %}
{% endfor %}
NB: I tried to do a more elegant solution using where_exp, but ran into a weird bug. Sad.
How Many Posts They Wrote
In your header for this author, you might want to include some data about how many posts they have contributed to the site. This can be seen below. It writes ‘No posts’ if they haven’t posted.
{% assign number_of_posts = 0 %}
{% for post in site.posts %}
{% if post.authors contains page.username or page.username == post.authors %}
{% assign number_of_posts = number_of_posts | plus: 1 %}
{% endif %}
{% endfor %}
{% if number_of_posts == 0 %}No posts{% elsif number_of_posts == 1 %}1 post{% else %}{{ number_of_posts }} posts{% endif %}
Link To Their Website
{% if page.url_short and page.url_full %}
<a href="{{ page.url_full }}" target="_blank" rel="noopener">{{ page.url_short }}</a>
{% endif %}
Link To Their Social Media
{% if page.twitter %}
<a href="https://twitter.com/{{ page.twitter }}" target="_blank" rel="noopener">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M30.063 7.313c-.813 1.125-1.75 2.125-2.875 2.938v.75c0 1.563-.188 3.125-.688 4.625a15.088 15.088 0 0 1-2.063 4.438c-.875 1.438-2 2.688-3.25 3.813a15.015 15.015 0 0 1-4.625 2.563c-1.813.688-3.75 1-5.75 1-3.25 0-6.188-.875-8.875-2.625.438.063.875.125 1.375.125 2.688 0 5.063-.875 7.188-2.5-1.25 0-2.375-.375-3.375-1.125s-1.688-1.688-2.063-2.875c.438.063.813.125 1.125.125.5 0 1-.063 1.5-.25-1.313-.25-2.438-.938-3.313-1.938a5.673 5.673 0 0 1-1.313-3.688v-.063c.813.438 1.688.688 2.625.688a5.228 5.228 0 0 1-1.875-2c-.5-.875-.688-1.813-.688-2.75 0-1.063.25-2.063.75-2.938 1.438 1.75 3.188 3.188 5.25 4.25s4.313 1.688 6.688 1.813a5.579 5.579 0 0 1 1.5-5.438c1.125-1.125 2.5-1.688 4.125-1.688s3.063.625 4.188 1.813a11.48 11.48 0 0 0 3.688-1.375c-.438 1.375-1.313 2.438-2.563 3.188 1.125-.125 2.188-.438 3.313-.875z"/></svg>
</a>
{% endif %}
{% if page.facebook %}
<a href="https://facebook.com/{{ page.facebook }}" target="_blank" rel="noopener">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M19 6h5V0h-5c-3.86 0-7 3.14-7 7v3H8v6h4v16h6V16h5l1-6h-6V7c0-.542.458-1 1-1z"/></svg>
</a>
{% endif %}
{% if page.instagram %}
<a href="https://instagram.com/{{ page.instagram }}" target="_blank" rel="noopener">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/></svg>
</a>
{% endif %}
The following CSS might help:
svg {
height: 1.8rem;
color: white;
}
svg path {
stroke: white;
}
P.S. I'm late to the party, but I recently got a twitter account that you can follow here.