Commit Redux

A software development blog in commit-sized retrospectives

Updating my Jekyll Blogging Rakefile

Friday May 23 2025 • 10:22 AM

To make the management of posts easier on my Jekyll sites, I’ve been maintaining a custom Rakefile. Today I updated it with two new tasks:

  • Listing all posts
  • Listing recent posts

I have also namespaced tasks (e.g., rake posts:all shows all posts). As I wrote in the My Writing Process post, one of the things that made Jekyll difficult to work with was the management of text files, especially when using a text editor like TextMate, which exposed post files and site files alike.

For a bit now I’ve been using nano as my text editor for blog posts on my main site, but editing older files was tedious, especially with my file hierarchy _posts/YYYY/MONTH and each file name being YEAR/MONTH/YYYY-MM-DD-some-title.md.

Now my rake tasks look like this:

$ rake -T

rake build         # Build the site with JEKYLL_ENV=production
rake posts:all     # List all blog posts
rake posts:new     # Create a new post with front matter
rake posts:recent  # List recent blog posts
rake serve         # Serve site locally

For example, running $ rake posts:recent shows something like this:

Recent Posts:

01. | _posts/2025/mayo/2025-05-23-discovery-tools-for-independent-websites.md
02. | _posts/2025/mayo/2025-05-20-back-on-gemini.md
03. | _posts/2025/mayo/2025-05-15-my-writing-process.md
04. | _posts/2025/mayo/2025-05-03-pings.md
05. | _posts/2025/abril/2025-04-05-fetching-favicons.md

Now it’s as easy as copying a path and running $nano [filename] to write / edit via the command line.

Tasks

To namespace the tasks, Rake has a namespace keyword.

namespace :posts do 

end

I added two constants in my Rakefile for the posts directory and the array of all post files.

POSTS_DIR = "_posts"
POST_FILES = Dir.glob("#{POSTS_DIR}/**/*.md").sort_by { |f| File.mtime(f) }.reverse

The Dir.glob method returns an array of the entry names selected by the argument. I set it to the _posts directory along with the /**/*.md selector, which matches all files in the current directory and all subdirectories. This is necessary because prior to 2025 my posts weren’t organized by month.

The block I’m passing to sort_by uses the File::mtime method to sort files by modification time and returns them in reverse order (most recently modified first).

Finally, I listed each post and formatted the output with a string formatter since I needed the index to be padded with a zero for single digits.

POST_FILES.each_with_index do |file, index|
  puts "%02d. | %s" % [index + 1, file]
end

That was it! 🌱