Jekyll multiple Permalinks support - jekyll

Does Jekyll support setting multiple permalinks?
For example, I currently have the following in my _config.yml:
permalink: /:categories/:title/
What I would like to have, is the following:
permalink:
- /:categories/:title/
- /:year/:month/:day/:title/
What I'm trying to achieve it that a single post will have multiple URLs. I'm well aware that I can use the "redirect_from" plugin (I'm hosting in GitHub Pages), but that would require me to manually update all my posts to include the redirect_from in the YAML

have you checked out jekyll-archives? https://github.com/jekyll/jekyll-archives
you can create other permalinks like
permalinks:
year: '/:year/'
month: '/:year/:month/'
day: '/:year/:month/:day/'
tag: '/tag/:name/'
category: '/category/:name/'
i don't think you can use :title though. it's an index page that lists posts.

Related

Fail build if two posts resolve to the same permalink in Jekyll

In my Jekyll site I have a permalink structure like this in _config.yml:
permalink: /blog/:title:output_ext
And I have two posts (in _posts) that resolve to the same permalink silently, for example:
2020-10-15-my-post.md
2020-10-16-my-post.md
Only one is written to _site/blog/my-post.html.
Is there a way to halt the building of the site, and throw an error, if two posts resolve to the same permalink (and then, one post overwriting the other)?
The Jekyll CLI has a command called doctor that outputs any deprecation or configuration issues with your site and, among other things, it detects when two posts resolve to the same permalink.
You can run it similarly to how you build your site today:
bundle exec jekyll doctor
In the example you gave in your question, jekyll doctor will show you an error message about a conflict between two pages, similar to this:
Configuration file: /your-website/_config.yml
Jekyll Feed: Generating feed for posts
Conflict: The URL '/your-website/_site/blog/my-post.html' is the destination
for the following pages: /your-website/_posts/2020-10-15-my-post.md,
/your-website/_posts/2020-10-16-my-post.md
When jekyll doctor finds a conflict like the above, its exit code will be non-zero which you can use to fail the build.

How to add permalink and variables globally to Jekyll pages inside a specified directory

I'm setting up a website with multi language support.
In the root directory I have one or more directories based on the language locale, e.g.: /en /it
I'm trying to set one language as default and let Jekyll generate its pages in the root of the _site directory, by setting the defaults section in _config.yml as described below. Other directories will be generated as usual.
I don't want:
to use a plugin since it have to work also with GitHub pages
to set a lang: en variable in each page front-matter but setting it globally in _config.yml instead if possible
put a load of files/directories in the root directory, just the various en, it, fr etc (if not having something like described below, but using a master pages directory).
I tried various solutions, including:
using collections: it works as expected with the example below but I don't want to use them for various reasons, like not having sitemap plugin working with them
using this solution, but it doesn't work with multiple pages with same name and other types of documents
This works with collections with an _en directory in the root:
collections:
en:
output: true
permalink: /:path
defaults:
...
- scope:
path: ""
type: "en"
values:
layout: "default"
lang: "en"
permalink: /:path
Not this, IMHO as it should be for pages:
defaults:
...
- scope:
path: "en"
type: "pages"
values:
layout: "default"
lang: "en"
permalink: /:path
In brief I need:
custom variables set for each page in the specified directory globally instead in each page front matter
make Jekyll to generate all pages from the specified directory to build in the root of _site directory using a global permalink

Jekyll: Group some collections but not all

I need to group some of the collections so that I can password protect that group. At the same time I want to keep the _posts collection open, so it needs to remain at the root of jekyll.
For example, this is group secure
collection:
notes:
output: true
hybrid:
output: true
collections_dir: secure
How can I exclude the collections such as _posts and also custom ones being grouped under secure?
Can I use permalinks to achieve this? For example
collection:
notes:
output: true
permalink: /secure/:path/
hybrid:
output: true
permalink: /secure/:path/
Answering my own question. The permalinks option is in fact best in this situation. That way _posts remains at the root of jekyll and other collections which do not need to be grouped are also behaving normally.
Once you build the site, all grouped collections will be under _site/secure/ locally and will be under http://example.com/secure/ on your server. Make sure to set up http authentication using htpasswd. There is plenty of material on the web on how to do this.

How to paginate posts by author

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.
how to handle multiple authors in Jekyll
adding authors to Jekyll
jekyll-author
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?
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: "john#example.com"
socials:
github: "john-doe"
twitter: "john_doe"
janedoe:
name: "Jane Doe"
bio: "Jane Doe is a systems engineer."
email: "jane#example.com"
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>
Newer
</li>
{% endif %}
{% if paginator.next_page %}
<li>
Older
</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!
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.

Generate index pages showing posts for each date in Jekyll

This seems really basic and yet I've been searching for it and can't find anything. I'm working on converting an old legacy/proprietary blog I have into Jekyll. So far it's going well and I have most things working well. I've run into an issue with generating indexs per date.
I'd like to have something like the following:
http://example.org/2012/01/03
http://example.org/2012/02/02
etc...
Where each of those paths pulls up a listing of posts for that date. So on the Jekyll side, I'd guess I'd see something like:
_site/2012/01/03/index.html
_site/2012/02/02/index.html
etc...
...where I can specify a template for generating those listing pages. How do you go about doing this in Jekyll?
Turns out there was already a plugin for this solution:
https://github.com/jekyll/jekyll-archives/
I simply followed the documentation and creating a configuration like the following:
jekyll-archives:
enabled: ['day']
layout: 'archive'
permalinks:
day: '/:year/:month/:day/'