nobiot

Org-roam Basics: Part 2 - How to Prompt for User Input and Pass Values Throughout Capture Process

Purpose of This Article

This article is Part 2 of Org-roam Basics: How org-roam-capture-templates Work. In this article, I will expand on the use of org-roam-capture-templates by addressing some common questions discussed on the Org-roam Discourse forum.

  1. How to create a capture template that prompts for details such as an author or book title, and how to incorporate these answers into the node’s title, properties, and file name.

  2. How to configure org-roam-capture-templates to prevent repeated prompts during the capture process, effectively passing your answers as variables throughout.

I use examples from these exchanges on Org-roam Discourse:

Prompting for User Inputs

One common challenge is configuring a capture template to prompt for user input. You can find guidance in the docstring of org-roam-capture-templates, which mentions a couple of options. I will focus on the most frequently requested method on the Org-roam Discourse forum.

%^{prompt}  Prompt the user for a string and replace this sequence with it.
            A default value and a completion table can be specified like this:
            %^{prompt|default|completion2|completion3|...}.

Exhibit 1. org-roam-capture-templatesDocstring Excerpt for User Prompt

Consider this example: you use Org-roam for academic notes and want to include basic book information, such as the author, title, and publication year. The capture template below (Exhibit 2) prompts you for the author and publication year, in addition to the title. This results in a capture buffer illustrated in the image below (Figure 1).

(setopt org-roam-capture-templates
        (add-to-list 'org-roam-capture-templates
                     '("b" "Literature note (book or article)" plain
                       "%?"
                       :target (file+head
                                "lit/%<%Y%m%d%H%M%S>-${slug}.org"
                                ":PROPERTIES:
:Author:        %^{Author}
:Year:          %^{Year}
:END:
#+title: %\\1 (%\\2), ${title}
#+filetags: :literature:")
                       :unnarrowed t)))

Exhibit 2. Capture Template for Prompting Author and Year

Figure 1. Resultant capture buffer with the author and year

Figure 1. Resultant capture buffer with the author and year

The template uses %^{prompt}in the head content of the target property (Exhibit 3) to request author and year details, adding them to the file-node’s property drawer.

:Author:        %^{Author}
:Year:          %^{Year}

Exhibit 3. Head Content Part of the Capture Template

In addition, this head content (Exhibit 4) reuses my answers for the title, formatted as [Author] ([Year]), [Title]. This results in the note entitled “Ota, Noboru (2024), The Way of Org-roam Capture” in the screenshot in Figure 1.

#+title: %\\1 (%\\2), ${title}

Exhibit 4. Reusing Prompted Values in Node Title

This part of the docstring explains the syntax (Exhibit 5). Note that you need to add an additional backslash “\” as an escape character in this case (which is why we have double backslashes “\\” in our example capture template).

%\1 ... %\N Insert the text entered at the nth %^{prompt}, where N
            is a number, starting from 1.

Exhibit 5. org-roam-capture-templatesDocstring Excerpt for Reusing Prompted Values

Reusing Answers to Prompts Across the Capture Template

Once you’ve configured prompt-based inputs for properties like the author, you might also want to use these inputs in the target file name and notes content as well as head content. However, org-roam-capture does not automatically share answers across different parts of a capture template. A template like the one in Exhibit 6 will prompt you for the author three separate times within a single capture process.

(setopt org-roam-capture-templates
        (add-to-list 'org-roam-capture-templates
                     '("b" "Literature note (book or article)" plain
                       "* Source:
Author: %^{Author}
Title: ${title}"
                       :target (file+head
                                "lit/%<%Y%m%d%H%M%S>-%^{Author}-${slug}.org"
                                ":PROPERTIES:
:Author:        %^{Author}
:END:
#+title: %\\1 ${title}
#+filetags: :literature:")
                       :unnarrowed t)))

Exhibit 6. Capture Template with Repeated Prompts for Author

One way to overcome repeated prompts is to create a custom org-roam-node property. As the node along its property values persist across the entire capture process, you set a value to it and access it in different parts of the capture template.. As a bonus, you can store node properties in the database and get them displayed in org-roam-node-find by simply adding them to org-roam-node-display-template.

Here is how to add a custom node property named author (Exhibit 7). This function (method) serves as both a setter and getter. If the author property is missing, the function prompts you to enter a value and returns it. If it already exists in the node’s property drawer as “AUTHOR,” it retrieves the value without prompt.

(cl-defmethod org-roam-node-author ((node org-roam-node))
  (let ((author (cdr (assoc-string "AUTHOR" (org-roam-node-properties node)))))
    (if author author
      (when org-roam-capture--node ; non-nil only during org-roam-capture
        (setq author (read-string "Author: "))
        (push (cons "AUTHOR" author) (org-roam-node-properties node)))
      author)))

Exhibit 7. Method to Add and Access Custom author Property

With this setup, modify your capture template to use the new author property (Exhibit 8). The method ensures the capture process prompts for input only as needed, integrating the author into the file name, content template, and head content that adds property drawers and title).

(setopt org-roam-capture-templates
        (add-to-list 'org-roam-capture-templates
                     '("B" "Literature note (book or article)" plain
                       "* Source:
Author: ${author}
Title: ${title}"
                       :target (file+head
                                "lit/%<%Y%m%d%H%M%S>-${author}-${slug}.org"
                                ":PROPERTIES:
:Author:        ${author}
:END:
#+title: ${author} ${title}
#+filetags: :literature:")
                       :unnarrowed t)))

Exhibit 8. Capture Template Using Custom author Property

This way, you can also display the author property in the org-roam-node-find list (Figure 2). To achieve this, include the property in org-roam-node-display-template (Exhibit 9).

(setopt org-roam-node-display-template
        "${author:16} ${directories:10} ${tags:10} ${title:60}")

Exhibit 9. Display Template Configuration for Node Properties Including author

Figure 2. org-roam-node-find showing the author property

Figure 2. org-roam-node-find showing the author property

Summary

In this article, we explored advanced org-roam-capture-templates techniques, focusing on how to prompt for user input and reuse this data across capture templates.