Denote's file naming scheme and org-roam

I still have to take advantage of org-roam’s capturing…

Probably not, both. :wink:

That could be nice, but, maybe, not essential.

Do you consider that org-roam could potentially handle heavier load in regard to the size of (Zettelkasten) notes?

This is a question for @jethro and people with more software engineering skills. At the current pace, for me, I will have maximum some thousand notes in some tens of years. I do not foresee my notes will hit the performance issues that some people talk about.

It sounds like you don’t really need Denote…

I have what seems to be an initial approximation of the format:

  (setq org-roam-capture-templates
        '(("z" "zettel" plain "%?"
           :if-new
           (file+head "%<%Y%m%dT%H%M%S>--${slug}__%(hiddyn/select-tag).org" ":PROPERTIES:\n:ID:          %<%Y%m%dT%H%M%S>\n:END:\n#+title:      ${title}\n#+date:       [%<%Y-%m-%d %a %H:%S>]\n#+filetags:   %^G\n\n")
           :immediate-finish t
           :unnarrowed t)))

This should do basically everything that a normal denote note does, with one exception: I’m very new to Lisp and have no idea how to prompt for multiple filetags and reuse those in both the filename and the #+filetags section.

(defun hiddyn/select-tag ()
  (completing-read "Select a tag: " (org-roam-tag-completions)))

seems to get me the former, but it’s brittle and doesn’t apply to the latter.

Would anyone have an idea of how to prompt for a comma-separated list of tags, store those temporarily for the file, and then reuse those in #+filetags? I’ve looked at Denote’s logic, but it’s not quite applicable given that org-roam pulls those from a database.

Actually, I think I’ve got a working proof-of-concept now, in case this helps anyone else in future who, like me, doesn’t really know Lisp very well:

(setq org-roam-capture-templates
        '(("m" "molecule" plain "%?"
           :if-new
           (file+head "%<%Y%m%dT%H%M%S>--${slug}__%(hiddyn/select-tag).org" ":PROPERTIES:\n:ID:          %<%Y%m%dT%H%M%S>\n:END:\n#+title:      ${title}\n#+date:       [%<%Y-%m-%d %a %H:%S>]\n#+filetags:   %(hiddyn/filetags)\n\n")
           :immediate-finish t
           :unnarrowed t)))

(defun hiddyn/select-tag ()
  (setq hiddyn/tag-list (sort (completing-read-multiple "Select a tag: " (org-roam-tag-completions)) #'string<))
  (mapconcat 'identity hiddyn/tag-list "_"))

(defun hiddyn/filetags ()
  (concat ":" (mapconcat 'identity hiddyn/tag-list ":") ":"))

Combine that with the org-roam-node-slug override from the org-roam wiki, and you should be good to go!

2 Likes

Slightly rewritten version of the previous code

(setq org-roam-capture-templates
      `(("d" "denote" plain "%?"
         :target (file+head "%(my-new-org-roam-filename \"${title}\")"
                            "%(my-new-org-roam-template)")
         :immediate-finish t
         :unnarrowed t)))

(defun my-new-org-roam-filename (title)
  (let ((id (denote-get-identifier (current-time)))
        (tags (completing-read-multiple "New note KEYWORDS: "
                                        (org-roam-tag-completions))))
    (setq my-org-roam-capture-id id
          my-org-roam-capture-title title
          my-org-roam-capture-tags tags)
    (denote--keywords-add-to-history tags)
    (thread-first
      (denote-format-file-name "/" id tags title ".org" nil)
      (substring 1))))

(defun my-new-org-roam-template ()
  (let* ((filetags (if my-org-roam-capture-tags
                       (concat ":" (mapconcat #'identity my-org-roam-capture-tags ":") ":")))
         (front-matter (concat ":PROPERTIES:\n"
                               ":ID:        " my-org-roam-capture-id "\n"
                               ":END:\n"
                               "#+title:    " my-org-roam-capture-title "\n"
                               "#+filetags: " filetags "\n")))
    (setq my-org-roam-capture-id nil
          my-org-roam-capture-title nil
          my-org-roam-capture-tags nil)
    front-matter))

1 Like