I have the following in my org-roam-capture-templates list:

("tt" "tomorrow task" plain
 ,(concat "*** %(org-read-date nil nil '+1')\n\n"
 :target (file "agenda.org"))

The overall list is backticked so concat will be evaluated with the preceding comma. I have other very similar templates that work just fine, and the unique element to this one is %(org-read-date nil nil '+1'). It's the only template in which I try to leverage the %(sexp) template form. When I try to use it, it opens a *Capture* buffer and successfully writes the plain text in the template, but the org-read-date form does not get expanded/evaluated, just written to the buffer literally. I thought it might be that it doesn't evaluate to a string, but it does when I evaluate it by itself in an elisp buffer.

What am I missing? Or is there a better way to represent 'tomorrow's date' in a roam template?

1 Answer 1


I don't think the %(org-read-date ...) form is the problem. Now I don't know anything about org-roam, so I don't know if org-roam-capture-templates (N.B: plural) requires different syntax, but the following seems to work:

(setq org-roam-capture-templates `(("tt" "tomorrow task" plain
                                    ,(concat "*** %(org-read-date nil nil \"+1\")\n\n"
                                             "Description: \n\n"
                                             "Results: \n\n")
                                    :target (file "agenda.org"))))

The difference is the syntax of the fourth argument of org-read-date: it's a string and needs to be enclosed by double-quotes (which need to be escaped inside a string - maybe you are used to Python where you can use either single- or double-quotes?)

  • 1
    This worked, thanks.
    – lmkerbey
    Commented May 10 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.