Jekyll Filename Without Date
Asked Answered
Z

6

47

I want to build documentation site using Jekyll and GitHub Pages. The problem is Jekyll only accept a filename under _posts with exact pattern like YYYY-MM-DD-your-title-is-here.md.

How can I post a page in Jekyll without this filename pattern? Something like:

  • awesome-title.md
  • yet-another-title.md
  • etc.md

Thanks for your advance.

Zebulon answered 24/11, 2014 at 6:59 Comment(0)
S
39

Don't use posts; posts are things with dates. Sounds like you probably want to use collections instead; you get all the power of Posts; but without the pesky date / naming requirements.

https://jekyllrb.com/docs/collections/

I use collections for almost everything that isn't a post. This is how my own site is configured to use collections for 'pages' as well as more specific sections of my site:

My config.yaml

My Pages collection

Sweet answered 6/10, 2016 at 20:35 Comment(0)
C
29

I guess that you are annoyed with the post url http://domaine.tld/category/2014/11/22/post.html.

You cannot bypass the filename pattern for posts, but you can use permalink (see documentation).

_posts/2014-11-22-other-post.md

---
title:  "Other post"
date:   2014-11-22 09:49:00
permalink: anything-you-want
---

File will be anything-you-want/index.html.

Url will be http://domaine.tld/anything-you-want.

Colly answered 24/11, 2014 at 9:0 Comment(3)
Ok, posts get special processing, but my site, built with Jekyll, does not use any posts. IOW, it is quite easy to have normal .html, .md or .textile files in your paths. My filenames are like the examples the OP gives.Fresnel
Rudy, you're absolutely right ! An other option is to use Pages instead of Posts.Colly
You can actually bypass the filename patterns using the permalink configuration in _config.yml. For example if you just want the filename as the link you can add permalink: /:title.html.Nadda
C
12

The way I solved it was by adding _plugins/no_date.rb:

class Jekyll::PostReader
  # Don't use DATE_FILENAME_MATCHER so we don't need to put those stupid dates
  # in the filename. Also limit to just *.md, so it won't process binary
  # files from e.g. drafts.
  def read_posts(dir)
    read_publishable(dir, "_posts", /.*\.md$/)
  end
  def read_drafts(dir)
    read_publishable(dir, "_drafts", /.*\.md$/)
  end
end

This overrides ("monkey patches") the standard Jekyll functions; the defaults for these are:

# Read all the files in <source>/<dir>/_drafts and create a new
# Document object with each one.
#
# dir - The String relative path of the directory to read.
#
# Returns nothing.
def read_drafts(dir)
  read_publishable(dir, "_drafts", Document::DATELESS_FILENAME_MATCHER)
end

# Read all the files in <source>/<dir>/_posts and create a new Document
# object with each one.
#
# dir - The String relative path of the directory to read.
#
# Returns nothing.
def read_posts(dir)
  read_publishable(dir, "_posts", Document::DATE_FILENAME_MATCHER)
end

With the referenced constants being:

DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!.freeze
DATE_FILENAME_MATCHER = %r!^(?>.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.]+)$!.freeze

As you can see, DATE_FILENAME_MATCHER as used in read_posts() requires a date ((\d{2,4}-\d{1,2}-\d{1,2})); I put date: 2021-07-06 in the frontmatter.

I couldn't really get collections to work, and this also solves another problem I had where storing binary files such as images in _drafts would error out as it tried to process them.

Arguably a bit ugly, but it works well. Downside is that it may break on update, although I've been patching various things for years and never really had any issues with it thus far. This is with Jekyll 4.2.0.

Choler answered 7/7, 2021 at 14:11 Comment(3)
Not sure why this got downvoted so much, but it works. Posts provide more functionality like the post_url-method, categories and tags which collections don't. If you're not planning on using timestamps at all, you have to set the permalink option to omit the date.Tyra
Yes this is the real answerGushy
It works, but you need to change /.*\.markdown$/ to /.*\.md$/. Other than that it is the actual correct answer.Respectively
I
8

What I did without "abandoning" the posts (looks like using collections or pages is a better and deeper solution) is a combination of what @igneousaur says in a comment plus using the same date as prefix of file names:

  1. Use permalink: /:title.html in _config.yml (no dates in published URLs).
  2. Use the format 0001-01-01-name.md for all files in _posts folder (jekyll is happy about the file names and I'm happy about the sorting of the files).

Of course, we can include any "extra information" on the name, maybe some incremental id o anything that help us to organize the files, e.g.: 0001-01-01-001-name.md.

Interrelation answered 3/3, 2020 at 22:15 Comment(0)
N
0

I wanted to use posts but not have the filenames in the date. The closest I got was naming the posts with an arbitrary 'date' like 0001-01-01cool-post.md and then use a different property to access the date.

If you use the last-modified-at plugin - https://github.com/gjtorikian/jekyll-last-modified-at - then you can use page.last_modified_at in your _layouts/post.html and whatever file you are running {% for post in site.posts %} in.

Now the dates are retrieved from the last git commit date (not author date) and the page.date is unused.

Nahuatlan answered 16/9, 2021 at 14:32 Comment(0)
R
0

In the json schema for the config file are actually some useful information. See below code block for some examples.

I have set it to /:categories/:title. That drops the date and file extension, while preserving the categories.

I still use a proper date for the file name because you can use that date in your templates. I.e. to display the date on a post using {{ page.date }}.

{
 "global-permalink": {
      "description": "The global permalink format\nhttps://jekyllrb.com/docs/permalinks/#global",
      "type": "string",
      "default": "date",
      "examples": [
        "/:year",
        "/:short_year",
        "/:month",
        "/:i_month",
        "/:short_month",
        "/:day",
        "/:i_day",
        "/:y_day",
        "/:w_year",
        "/:week",
        "/:w_day",
        "/:short_day",
        "/:long_day",
        "/:hour",
        "/:minute",
        "/:second",
        "/:title",
        "/:slug",
        "/:categories",
        "/:slugified_categories",
        "date",
        "pretty",
        "ordinal",
        "weekdate",
        "none",
        "/:categories/:year/:month/:day/:title:output_ext",
        "/:categories/:year/:month/:day/:title/",
        "/:categories/:year/:y_day/:title:output_ext",
        "/:categories/:year/:week/:short_day/:title:output_ext",
        "/:categories/:title:output_ext"
      ],
      "pattern": "^((/(:(year|short_year|month|i_month|short_month|long_month|day|i_day|y_day|w_year|week|w_day|short_day|long_day|hour|minute|second|title|slug|categories|slugified_categories))+)+|date|pretty|ordinal|weekdate|none)$"
    }
}
Rubetta answered 29/5, 2022 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.