As part of refactoring the way that I store and manage knowledge, I started looking into a note-taking method called Zettelkasten. I became interested in this method after watching this video and decided to purchase the book How to Take Smart Notes and read it for myself.

One of the key features of the Zettelkasten method is the linking of one idea to another. To be able to link one idea to another, each note needs to have a unique identifier. For many of the tools that try to implement this method digitally, that comes in the form of a date/time string that is added to the title. As I started to think how I could implement this method, I came across this article by Stefan Imhoff on how to implement Zettelkasten within DEVONthink.

While the article started me in the right direction, the one thing that I did not like was the way that the WikiLinks were implemented. DEVONthink supports the use of square bracketed WikiLinks, so you can add a link to another article by adding the name of the item in square brackets.

[[20200910140315 Vault KV Update]]

While I liked the format of id/title for the document’s name field, I do not like using it for the WikiLink. I want to be able to add context that may not specifically include the title, it looks really out of place. If I have a master HashiCorp Vault note/index, I might want to write something like:

Updating Key/Value Pairs [[20200910140315 Vault KV Update]]

There is just too much redundant text for me. Other Zettelkasten based tools are able to use only the unique identifier in their links, so it would look like this:

Updating Key/Value Pairs [[20200910140315]]

This looks much cleaner to me. As I was looking for ways to implement something like this, I came across this post on how Bernardo Vasconcelos uses WikiLinks and Aliases in DEVONthink. This is exactly what I was looking for! I could use the original id/title for the name of the DEVONthink page, but then add just the id to the aliases and then link to that.

One problem remained. With my Drafts->DEVONthink workflow, I do not want to manually add the alias every time. Thankfully, Bernardo came to the rescue again with a script that he posted in the DEVONthink forum. I took the original script that he posted and updated it a little bit to meet my needs. Primarily, I changed thePattern variable and removed the bits where it pulled any aliases that were already set (I only use one alias).

use AppleScript version "2.4" -- Yosemite (10.10) or later
use script "RegexAndStuffLib"
use scripting additions

property thePattern : "(\\d{14})"

on performSmartRule(theRecords)
	tell application id "DNtp"
		repeat with theRecord in theRecords
			set theText to the plain text of theRecord
			set theID to regex search once theText search pattern thePattern replace template "$1"
			set theAliases to the aliases of theRecord
			--set the aliases of theRecord to theID & ", " & theAliases
			set the aliases of theRecord to theID
			log message "Aliases of " & (the name of theRecord) & " updated"
		end repeat
	end tell
end performSmartRule

For this to work properly, you will need to download and install the RegexAndStuffLib script to /Users/Username/Library/Script Libraries/ and restart DEVONthink. Finally, I created a Smart Rule in DEVONthink to run every time a markdown file was imported into my Zettelkasten Inbox and embedded the above script as the action.

Smart Rule

Now, any time I import a markdown file from Drafts it will automatically update the aliases with my unique ID.