How to insert a function to the file name in org-roam-capture-templates

How can I change the org-capture templates to dynamically format the file name?

The following example doesn’t work because it will only call the function once - when I evaluate the variable. I need to make it call a function every time I create the template.

The function simply returns the current buffer’s file-name and appends _anki.org to the name.

(setq org-roam-capture-templates
      `(("a" "anki-cards" plain "%?"
         :if-new (file+head ,(format "%s_anki.org"
                                     (file-name-nondirectory
                                      (file-name-sans-extension
                                       (org-roam-node-file (org-roam-node-at-point)))))
                            "#+title: ${title}\nDescription: ")
         :unnarrowed t)))

Try %(sexp) per documentation: “%(function)_anki.org”, or something along those lines.

Not sure if the at-point func gives you what you intend to get, though (the function may be called within a temp buffer).

On a side note, I suggest to use :target, instead of :if-new, which is being deprecated.

2 Likes

Is it possible to pass a variable or to get the buffer from where I called org-capture? As you said, the at-point function returns nil. Is it possible to at least get a link to the current buffer?

Does this mean that you can now call a function and confirm that the at-point function didn’t return the node’s filename correctly as you expect it would?

An easy way would be to define a global variable and set it just before calling the capture command. I’d wrap it with a custom function. You could consider advising, too.

I’ve tried and this is the template works:

("a" "anki-cards" plain "%?"
  :target (file+head "%(my-org-roam-anki-card-filename \"${at-point}\")_anki.org"
  "#+title: Anki Cards") :unnarrowed t)

This is the function (it is more of an hack as I have to pass a string with the node information and regex the id):

(defun my-org-roam-anki-card-filename (node)
  (let* ((file (file-name-nondirectory
                (file-name-sans-extension
                 (replace-regexp-in-string
                  ".*org-roam-node \\(.*?\\)\\.org\\b.*"
                  "\\1"
                  node)))))
    (format "%s" file)))

Now I want to pass the title to the template, or at least a link to the original file but the expansion %a doesn’t work.

Edit: Forget it. I misread what %a does. To have a link to file I just need to insert [[%f]]