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.
Related
In my Jekyll page I have huge collections that take 35s to render and sometimes I just delete the biggest folders to iterate faster but I figure it should also be possible to have a secondary _config.dev.yml that undoes the _config.yml's collection definition. But I fail to get it to work.
How do I get jekyll to disregard a folder that is configured for a collection in _config.yml?
To have Jekyll pretend folders to be empty, simply exclude these folders in your _config.dev.yml:
exclude:
- _bigCollection
- _otherBigCollection
You could do it the other way round:
Do not define the collection in _config.yml.
When you deploy your site to production (or when you do want to render the big collections locally), use a secondary _config_with_collections.yml which includes just the collection definitions.
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.
I want to prepare a newsletter archive page, using the Jekyll and github pages. Each edition has several content categories. I however intend to use pages instead of posts, as all posts would have the same date. The page category should be set by folder structure.
My plan was to have each edition as a collection with subfolders, which would assign the category tag:
root
\_edition1
\cars
\Skoda.md
\Volvo.md
\boats
\BoatyMcBoatface.md
\QueenElizabeth.md
\_edition2
\cars
\Trabant.md
\Volvo.md
\boats
\BoatyMcBoatface.md
\LittleBoat.md
The question is, how to assign category by directory structure to pages in collection?
I suppose this is a common use case, however even jekyll homepage use a workaround (manually build index with custom categories in _data section). Could this functionality be somewhat automatically generated by folder structure?
Thanks for any comments!
I am trying to add a new post to my Jekyll site, but I cannot see it on the generated pages when I run jekyll serve.
What are some common reasons for a Jekyll post to not be generated?
The post is not placed in the _posts directory.
When you change the collections_dir in your config from . (default) to my_col_folder all your posts have to move as well below my_col_folder/_posts jekyll defaults
The post has incorrect title. Posts should be named YEAR-MONTH-DAY-title.MARKUP (Note the MARKUP extension, which is usually .md or .markdown)
The post's date is in the future. You can make the post visible by setting future: true in _config.yml (documentation)
The post has published: false in its front matter. Set it to true.
The title contains a : character. Replace it with :. Works in jekyll 3.8.3 (and probably in other 'recent' releases).
You can use jekyll build --verbose to view build process in detail.
Exmaple output:
Logging at level: debug
Configuration file: /home/fangxing/fffx.github.io/_config.yml
Logging at level: debug
Requiring: jekyll-archives
Requiring: jekyll-livereload
Requiring: kramdown
Source: /home/fangxing/fffx.github.io
Destination: /home/fangxing/fffx.github.io/_site
Incremental build: enabled
Generating...
EntryFilter: excluded /Gemfile
EntryFilter: excluded /Gemfile.lock
Reading: _posts/2018-01-14-new-post.md
Reading: _posts/2014-01-01-example-content.md
Reading: _posts/2014-01-02-introducing-lanyon.md
Reading: _posts/2017-11-21-welcome-to-jekyll.markdown
Reading: _posts/2018-01-14-boot-android-on-charge.md
Reading: _posts/2013-12-31-whats-jekyll.md
Skipping: _posts/2018-01-14-boot-android-on-charge.md has a future date
Generating: Jekyll::Archives::Archives finished in 0.000122873 seconds.
Generating: JekyllFeed::Generator finished in 0.000468846 seconds.
...
from the log I found jeklly skipped 2018-01-14-boot-android-on-charge.md because it has a future date.
One possible reason is that the date specified in the front matter does not contain a time zone offset, in which case it defaults to UTC, not the time zone of the local machine as you might expect. I wasted an hour on this until UTC "caught up" with my current local time zone, BST.
I haven't found a definitive answer to this but I think the date in the front matter must be given in UTC with a timezone offset (which defaults to zero if omitted).
So date: 2018-05-03 12:34:27 is in UTC irrespective of where in the world you are, and irrespective of the timezone setting in _config.yml.
So be careful to specify datetimes like this:
date: 2018-05-03 12:34:27 +0100
Or it can be browser cache as well if you are looking not in the _site folder but directly on the blog's main page with the list of posts.
I have written Rspec tests for my blog that express these rules:
require 'spec_helper'
require 'yaml'
# Documented at https://jekyllrb.com/news/2017/03/02/jekyll-3-4-1-released/
post_regex = %r!^(?:.+/)*(\d{2,4}-\d{1,2}-\d{1,2})-(.*)(\.[^.]+)$!
def date_in_front_matter(date)
return date if date.is_a?(Date)
return date.to_date if date.is_a?(Time)
return Date.parse(date) if date.is_a?(String)
end
describe 'posts' do
Dir.glob("_posts/*md").each do |file|
basename = File.basename(file)
context basename do
front_matter = YAML.load(File.read(file).split(/---/)[1])
it 'filename must match documented post regex' do
expect(basename).to match post_regex
end
it 'date in file name same day as date in front matter' do
date_in_file_name = Date.parse(post_regex.match(basename).captures[0])
expect(date_in_front_matter(front_matter['date'])).to eq date_in_file_name
end
it 'title in front matter should not contain a colon' do
expect(front_matter['title']).to_not match /:/
end
it 'front matter should not have published: false' do
expect(front_matter['published']).to_not be false
end
end
end
end
This may be of use to others as I was losing a lot of time due to typos in the date etc.
These tests along with the rest of the Rspec config can be seen in context here.
Just to add one more reason, when you move an article from _drafts to _post, you sometimes need to delete the _site for the article to be regenerated.
In my case it often happens that _site will not be entirely deleted before re-generation so the new article won't appear.
Anyway rm -rf _site and bundle exec jekyll serve works :)
If you are unable to track the file in --verbose and if the file is silently ignored then try removing collections_dir in the config.yml file. That solved the issue for me.
My post also did not appear an the error was, that in my name I used a dot, e.g. 2017-10-18-test.2.md.
This is not accepted, you have to use 2017-10-18-test2.md.
If you have checked your front matter, and all seems well, and even jekyll build --verbose doesn't reveal anything (in my case, it just acted as if the file didn't exist at all, not even listing it as excluded), check the encoding of your file. Apparently, it needs to be UTF-8 without signature. It it's UTF-8 BOM (or UTF-8 with Signature as some text editors call it), then it will be silently ignored. To make matters worse, some editors will display both types as just UTF-8, making the difference even harder to spot.
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.