Writing an org-capture template and defun for blog posts

hi! I’m new here and an Emacs noob of about four years now. I’m currently trying to set up a website using org-publish for building (which I’m pretty much done with) and an org-capture template with a supporting function for writing blog posts.

now, getting down to specific, my setup has blog posts in a specific directory and I’ve just moved from an ox-hugo/Hugo based setup here so posts are all individual org files. so I want the function to help take the post title (from a prompt) and generate a slug/filename and to reuse the title as the title of the org file. i also want to prompt for a description. so far, I’ve written this much, badly, and it doesn’t work. it doesn’t even allow me to select a capture template when i do C-c c or run org-capture

and org-hugo-slug is a function that makes a slug out of the title string, reused from ox-hugo

 (defun org-new-blog-post ()
      (setq org-new-blog-post-date (format-time-string (org-time-stamp-format :long :inactive) (org-current-time)))
      (setq org-new-blog-post-title (read-string "Post Title: "))
      (setq org-new-blog-post-fname (org-hugo-slug title))
      (setq org-new-blog-post-description (read-string "Description: "))
      ;; CHANGED THIS BIT:
      (find-file (expand-file-name (format "%s.org" org-new-blog-post-fname) "~/git/personal/blog/org/blog/")))
    
(setq org-capture-templates
    '(("n" "new post"
    plain
    (function org-new-blog-post)
    "%(format \"#+title: %s\n#+date: %s\n#+description: %s\n\n\" org-new-blog-post-title org-new-blog-post-date org-new-blog-post-description)")))

so, any help on how I could go about this?

1 Like

So I’d asked a couple of friends and one of them was kind enough to help me write this function. i mean, they wrote it and i just changed it up to make it work according to my needs:

(with-eval-after-load 'org-capture
  (defun taingram/org-new-blog-post ()
    "Gets user input for blog post title and uses it to construct the
filename to create. Also uses the title in the capture form so I don't have to type it out again."
    (interactive)
    (let* ((title (read-string "Post Title: "))
           (filename
            (read-string "Filename: "
                         (concat (org-hugo-slug title) ".org"))))
      (set-buffer (find-file-noselect
                   (file-name-concat "~/git/personal/blog/org/drafts/" filename)))
      (insert "#+title: " title)
      (newline))))

(setq org-capture-templates
      '(("b" "New blog post"
         plain
         (function taingram/org-new-blog-post)
         "#+date: %u
#+description: %^{Description} \n
%?"))

the title doesn’t show up till after the file is opened but it works. for a version of this that shows the title too paste.sr.ht

1 Like