Creating my jekyll post files with emacs
Michael Christensen-Calvin / March 2023 (521 Words, 3 Minutes)
Easing the path into blogging
I have started so many blog sites over the years where I post for like a week and then totally lose track of it. The biggest blog I have ever made was -maybe- 5 posts. I’d really rather not fall into that pattern again. In order to facilitate that, I want to give myself the path of least resistence when it comes to making new posts.
I have used emacs for the last 12 years or so of development, and so making myself some nice functions in order to easily create a file with the correct naming and boilerplate seemed like a good place to start. So I spent an hour or so boning up on my elisp and writing a couple functions to get this working.
Eventually I would like to explore writing these posts in org-mode and then using the org-export functionality to create the posts completely, but I wanted to make this faster and not go down a rabbit hole at the beginning.
Defining the customization variables
First I new I wanted to make this portable between my different machines, and I don’t always keep the same file structure, so I needed to create some variables that I could customize on a per machine basis. This defgroup and defcustom:
(defgroup my/jekyll nil
"Settings for jekyll creation setup."
)
(defcustom my/jekyll-website-root "~/Development/devblog-jekyll"
"Path to the root of the jekyll project"
:type 'directory
:group 'my/jekyll
)
(defcustom my/jekyll-post-directory "_posts"
"Path from the website root to the posts directory"
:type 'directory
:group 'my/jekyll
)
(defcustom my/jekyll-author-name "Michael Christensen-Calvin"
"The author name to insert in post headers."
:type 'string
:group 'my/jekyll
)
Defining my functions
Next I wanted to create a couple functions to separate my logic. I needed:
- a function to create the correct filename from the path/title
(defun my/jekyll-post-sluggify-file-name (title) "Add add the date slug to the title." (if (file-directory-p my/jekyll-website-root) (let* ((date-str (format-time-string "%Y-%m-%d")) (post-dir (expand-file-name my/jekyll-post-directory my/jekyll-website-root)) (my/filename (expand-file-name (format "%s-%s.md" date-str title) post-dir))) my/filename) (error (format "Directory %s does not exist" my/jekyll-website-root))))
- a function to open up the new file
(defun my/jekyll-create-post (title) "Create a file in the correct directory (if it exists) and open that file in a buffer." (interactive (list (read-string "Post Title: " "new-post"))) (let ((fname (my/jekyll-post-sluggify-file-name title))) (find-file fname) (my/jekyll-insert-front-matter title)))
- a function to insert the header front-matter text to the new file
(defun my/jekyll-insert-front-matter (title) "Insert the front matter for a new jekyll post." (let ((layout-str "layout: post\n") (date-str (format "date: %s\n" (format-time-string "%Y-%m-%d %H:%M:%S"))) (title-str (format "title: \"%s\"\n" title)) (author-str (format "author: %s\n" my/jekyll-author-name))) (insert "---\n") (insert layout-str) (insert title-str) (insert date-str) (insert author-str) (insert "---\n\n")))
Binding to a key
This is pure personal preference, but since (C-c n) is my keybind for my org-roam map, I figured (C-c j) would work for making a new jekyll post.
(global-set-key (kbd "C-c j") 'my/jekyll-create-post)