This is a short function I crafted recently to create a new Hugo article from within the Emacs. Until now, each time I wanted to create a new article, I had to spawn eshell and run hugo new command from there.

In essence, it is really a dumb function, and has no notion of hugo commands, templates, structure, or anything for that matter. It assumes my own post structure and just inserts hard-coded template into appropriate place for my site. It prompts for name of the article which is just down-cased and spaces are replaced with dashes (-) in order to generate filename.

(setq hugo-root-dir "~/Area52/tomica.net/")

(defun tomica/hugo-new-blog-post ()
  "Function to create new Hugo post."
  (interactive)
  (let* (
        (page-title (read-string "Enter the page title: "))
        (filename (replace-regexp-in-string " " "-" (downcase page-title)))
        (template (concat
                   "---\n"
                   "title: %s\n"
                   "date: %s\n"
                   "draft: true\n"
                   "type: post\n"
                   "categories: \n"
                   "  - Blog\n"
                   "tags:\n"
                   "  - \n"
                   "---\n"))
        )
    (if (not (file-exists-p hugo-root-dir))
        (message "Hugo root directory not found: %s" hugo-root-dir)
      (let* (
            (page-path (expand-file-name (concat "content/blog/" (format-time-string "%Y/%m/") filename ".md") hugo-root-dir))
            )
        (if (file-exists-p page-path)
            (message "Page already exists: %s" page-path)
          (with-temp-file page-path
            (insert (format template page-title (format-time-string "%Y-%m-%dT%H:%M:%S%z")))
            (message "New page created: %s" page-path)))
        )
      )
    )
  )

I plan on evolving this function with time, but not in the immediate future. Once I start developing more things on top of it I’ll probably move it into a separate repository and use it as a private package.

Some features I’d like to see in the future:

  • prompt for tags, give a list of existing tags in other files (such as org-mode does with its own tags)
  • have function which will collect all articles within the hugo site and allow to select one using some completion/selection framework so I can open that file and edit it
  • When generating filename, account for more special characters such as '
  • … who knows

I’m aware that there’s already easy-hugo package which might provide what I’m looking for and much more, but it would be an overkill to use it at this time. Instead, I decided to play a bit :-)