Can the notes filtered by dataview be set to automatically add a link to the current note?

Simple? Well, that depends on eyes viewing, but here is something which works in my world, at least.

Instructions on how to setup the template, optional with a hotkey

There is some setup, which might seem a lot the first few times, but it’s not as bad as it seems.

  • Install the Templater plugin: Installation - Templater
  • Dedicate a folder for templates in your vault, like templates
  • Create a file in this folder, i.e. staticDataview (or whatever you feel like)
  • Copy the content from below into it
  • If you want to trigger it by hotkey, also do this:
    • Go to Settings > Templater > Template Hotkeys
    • If there isn’t a free field, hit “Add new hotkey for template”
    • In a free field, enter your template, like templates/staticDataview.md
    • Hit the + icon, which gives you a new dialog
    • Find your “Templater: Insert … staticDataview”, and hit the + icon here
    • Hit the hotkey you want to use to trigger this template. Hover with your mouse over it to check that it’s valid, and not in conflict with other hotkeys. If in conflict, hit the x icon, and try another…
<%*
const dv = this.DataviewAPI

const pages = await dv.query(`
LIST
FROM #game
`)

if (pages.successful) {
  const gameLinks = pages.value.values
  // console.log(gameLinks, typeof gameLinks)
  
  // Alternative 1: A simple markdownList from dv
  tR += `## Games in a list\n\n`
  tR += dv.markdownList(gameLinks)
  
  // Alternative 2: One game on each line
  tR += `\n## Games\n`
  const games = gameLinks
    .map(g => {
      // Extract the gamename _after_ the last "/" and without the ".md"
      const gameName = /\/([^\/]+)\.md$/.exec(g.path)[1]
      return `[[${ g.path } | ${ gameName }]]\n`
    })
    .join("")
    
  tR += games
  // console.log(games)
  
} else {
  tR += `\n~~~~\n${ pages.error }\n~~~~`
}  
%>

The template starts of with grabbing a shortcut for the dv api, always nice to have around. Then it executes the query. I’ve formatted this so that you should be able to easily change it to another query by just replacing the query. Be sure to keep the line in front, and the line afterwards (the one with only `))

If the query is successful, we’ll handle it, and if not it’ll show an error message which hopefully will help you resolve the error and get a better result later on.

Inside the handling I present two alternatives for handling this result. The actual list result from the query is found in pages.value.values, so let’s store that away.

In the first alternative a header is written to the page where we started the template, by doing tR += ... . This way of handling the output is due to the template being a dynamic execution template, indicated by starting the template with <%*. Then I use a version of generating the list from the Dataview API which generates markdown (and not html).

In the second alternative, we need to do some more steps to only output one game link on each line. Going from the array into the lines is called mapping, and is done using .map(). The first thing in the mapping is to extract the game name from the full path to the note. Kind of cryptic, but it works, at least if the game is in a folder. If not, come back to me, and we can fix that case.

With the game name, and the full path, we can return (to be written into our note) a full link with the g.path for the full path, and the gameName in the alias. Adding a newline, so it looks nice. And after the mapping, join the lines together, before adding to the output, using tR += games.

How to debug dynamic execution templates?

You do it painfully. Sorry to say, but it’s a little cumbersome to debug these script, but what I’m doing is that I’ve got a dummy template, which I’ve got a hotkey to run, so that I run it over and over again.

Then I open up a workspace setup with the following files/panes:

  • The dummy template
  • A log file in both editing and reading view, so that I can see the rendered result
  • The Console from Developers Tools to view all my console.log() messages

And the latter is the true secret to debugging. Use plenty of console.log(something) in the template for starters. I’ve left some of them in this template, which you could uncomment, and see the result. When we log an object, the console allows us to uncollapse and dig into the details of that object, and then we can see what’s available.

So for example, for the gameLinks output, one can see something like the following:
image

Revealing that the full link is in path, and that this link has no subpath (to a header/section/block), and no alias, in display. This output will of course vary depending on the object, but it allows you see what’s available for further coding.

Hopefully, I’ve not made to many glaring errors when writing about this, and that it makes some sense. Always a challenge to get to the right level of explanation. Feel free to ask if something was extremely unclear, and good luck in implementing your own variation of templates like this.

Two caveats: Firstly, the regex will most likely fail if your games are in the root folder, if so ask me. Secondly, the query as it stands could very well report false positives, and the template doesn’t handle that. If this is the case for you, then refine the query until it just returns the games you want to add using the templates.

PS! Lastly, in this reply, another version of how to interact between dataview and a template is shown. Could possibly be interesting.

3 Likes