New Hugo Post and Folder Hammerspoon
I took a crack at making a new Hammerspoon Lua script. When I have posts that
contain images (like this one) or other files, in Hugo you’d create them in a
folder like content/posts/2025-04-18_simple-title/index.md
. That would then
allow you to drop things like associated images, videos and other files with
the post itself, keeping it as a self-contained unit.
The problem is: Any time I wanted to do that meant I had to open Finder or
GhosTTY, navigate to my Projects folder, find my site folder, navigate into
content/posts
and then make a new directory. THEN I would have to start a
new index.md
file elsewhere and then save it in to that directory. So much
tedium! Then I got the bright idea that I have Hammerspoon and I’ve been
looking for more ideas on how to use the hyper
key. To the bat-cave
BBEdit!
After a bit of searching, I found a simple enough to understand “slugify” lua script, and after a bit of noodling through the docs, then asking Claude to critique my work, I had a pretty usable script! Behold!
-- Slugify function to convert text to URL-friendly format
function Slugify(text)
if text == nil then
return ""
end
-- Convert to lowercase
local slug = string.lower(text)
-- Replace spaces with hyphens
slug = string.gsub(slug, "%s+", "-")
-- Remove special characters
slug = string.gsub(slug, "[^%w%-]", "")
-- Remove consecutive hyphens
slug = string.gsub(slug, "%-+", "-")
-- Remove leading and trailing hyphens
slug = string.gsub(slug, "^%-", "")
slug = string.gsub(slug, "%-$", "")
return slug
end
local function createHugoPostFolder()
-- Get the current date in YYYY-MM-DD format
local currentDate = os.date("%Y-%m-%d")
-- Prompt user for post name
local button, postName = hs.dialog.textPrompt(
"Create a new Hugo Post?", -- title
"Enter the title for your new post:", -- message
"", -- default
"Create", "Cancel" -- buttons
)
if postName == nil or postName == "" or button == "Cancel" then
return
end
-- Slugify the post name
local slug = Slugify(postName)
-- Create folder path
local hugoContentPath = os.getenv("HOME") .. "/Projects/degruchy.org/content/posts/"
local folderName = currentDate .. "_" .. slug
local fullPath = hugoContentPath .. folderName
-- Create the directory
local success, errorMessage = hs.fs.mkdir(fullPath)
if success then
hs.alert.show("Created folder: " .. folderName)
-- Optionally create an index.md file in the folder
local indexFile = io.open(fullPath .. "/index.md", "w")
if indexFile then
indexFile:write("---\n")
indexFile:write("title: \"" .. postName .. "\"\n")
indexFile:write("date: <# Date #> \n")
indexFile:write("draft: true\n")
indexFile:write("---\n\n")
indexFile:write("Your content here.\n")
indexFile:close()
end
else
hs.alert.show("Error creating folder: " .. errorMessage)
end
end
hs.hotkey.bind({"cmd", "alt", "shift", "ctrl"}, "N", createHugoPostFolder)
Now, I can press hyper
+n
, get prompted for a new post title, where I can
write a normal title with capitals and more, and have an appropriately named
folder and index.md
file created for me, in the right spot and ready for me to
fill it with stuff!
