Exclude title/heading from the results of `org-roam-node-find` but show the aliases

Sometimes I create a headline note inside a regular file. Here is an contrived example:

:PROPERTIES:...
#+title: Cars

Cars are ...

* Classification
:PROPERTIES:
:ID:  <some uuid here>
:ROAM_ALIASES: "Classification of Cars"
:END:

A car can be a Supermini, a large family car, ...

Now when I do a org-roam-node-find I get the following suggestions:

Classification
Classification of Cars

The second one is as desired but I don’t want to see the the rather generic suggestion “Classification”. On the other hand I don’t want to change the heading since it is already in a note called “cars” so it would be needlessly verbose to expand the title itself to “Classification of Cars”. In a real example the difference in verbosity can be more extreme (most of the time I find my nodes by just searching for the title and hence the title must be at least a bit verbose, on the other hand I try to be brief inside my notes).

I know about ROAM_EXCLUDE but it seems to be just a boolean flag which can only “turn off” the whole node. Is there an option which lets org-roam-node-find ignore the heading but still show the aliases? I couldn’t find something.

So… you want to list nodes only by aliases. Correct?

I believe this below should work (it works on my end).

It’s not easy. You need to do two things:

  1. Override function org-roam-node-list to list only aliases (without including title)
  2. Adjust org-roam-node-display-template to show aliases instead of title

Below, the two above are done temporarily without interfering your normal functions

I think you need lexical binding.

;; -*- lexical-binding: t; -*-
(defun my/org-roam-node-find-alias-only ()
  "It's like `org-roam-node-find' but only aliases without title.
This means if a node does not have an alias, it is not shown."
  (interactive)
  ;; Temporarily replace `org-roam-node-list' to get only nodes from
  ;; aliases table
  (cl-letf (((symbol-function 'org-roam-node-list)
             ;; Anonymus function. Return list of nodes from aliases table
             ;; only.
             (lambda () (mapcar (lambda (e)
                                  (org-roam-node-from-id (car e)))
                                (org-roam-db-query
                                 [:select [node-id alias]
                                          :from aliases])))))
    ;; Temporarily set `org-roam-node-display-template' to show aliases
    ;; instead of title by replacing ${title with ${aliases
    (let ((org-roam-node-display-template
           (string-replace "${title" "${aliases" org-roam-node-display-template)))
      (org-roam-node-find))))

@nobiot many thanks for your quick reply.

It goes in the right direction but it is not exactly what I want. I want an explicit way to say that for a particular node I want to ignore the title. In the Car Example it is the heading “Classification”. In fact, my use case - so far - only involves nodes which are just headings - because only for them it can happen that I choose a short title which is meaningless without context (of the “Parent-Node” - the file-node - which contains it).

Almost all my nodes are files, and often I do not use aliases. So a lot of nodes would be effectively “hidden” when I do my/org-roam-node-find-alias-only (I tried it).

I was hoping to accomplish the goal by writing something like this in my node:

* Classification
:PROPERTIES:
:ID:  <some uuid here>
:EXCLUDE_TITLE_FROM_NODE_FIND: t
:ROAM_ALIASES: "Classification of Cars"
:END:

I mean the :EXCLUDE_TITLE_FROM_NODE_FIND: t. I suppose for this to be efficiently doable the database had to be aware of this property - don’t know how it works. Do you think this could be doable, maybe some adaption of your my/org-roam-node-find-alias-only?

For this, I would probably avoid using aliases, and instead I’d show the “context” for heading-node titles with something like this.

1 Like

Thanks @nobiot this is a very good solution which solves the core problem!

Hello !

I think I have found your solution. For that, you need the “vulpea” package available here: GitHub - d12frosted/vulpea: A collection of functions for note taking based on `org` and `org-roam`..

My configuration (using straight) :

(use-package vulpea
    :straight (vulpea
               :type git
               :host github
               :repo "d12frosted/vulpea")
    ;; hook into org-roam-db-autosync-mode you wish to enable
    ;; persistence of meta values (see respective section in README to
    ;; find out what meta means)
    :hook ((org-roam-db-autosync-mode . vulpea-db-autosync-enable))
    )
  (require 'vulpea)

Then, you have to set the “:ROAM_EXCLUDE_TITLE:” property to “t” with a node.

Concrete example:

* Title that I don't want to see
:PROPERTIES:
:ID: a3668606-b9e0-48f8-ae8e-a79e332ba361
:ROAM_EXCLUDE_TITLE: t
:ROAM_ALIASES: "Alias that I want"
:END:

Finally, you can call the following piece of code:

(vulpea-find
 :filter-fn (lambda (note)
	      (if (not (cdr (assoc-string "ROAM_EXCLUDE_TITLE"
					  (org-roam-node-properties
					   (org-roam-node-from-id (vulpea-note-id note))))))
		  t
		(vulpea-note-primary-title note))))

I hope this solves your problem :slight_smile:

@Cletip thanks for you feedback (although my reply is a little late)! I didn’t know about vulpea, looks interesting on its own right.

But I am very satisfied with nobiots solution. It really solves the “true” problem, which basically is: “How to make sure to have enough context in my note title while not repeating myself in case of headline notes”. This in turn is part of the much broader problem of “How to make sure that I will find my note when I need it”.

My initial idea was based on a certain lack of creativity. I also just started to learn org-roam at the time so I had no idea what is possible. I am actually happy that I did not succeed in making it work. Nobiot’s solution solves the “true” problem while having no overhead. Compare this to my solution which requires me to set some stuff in the PROPERTIES.

Now that I have already a few notes like this I can say that Nobiot’s solution is really great. It accomplishes the goal, my workflow has no overhead, and it introduced no new dependencies. The latter is also very important to me.

1 Like