Line-level links to tasks in Obsidian
Task links: going further on custom query rendering
As part of our custom rendering we of course would add links to the notes and ideally the tasks but this can prove difficult.
Obsidian does not really have line-level or task-level link, it is a common problem.
But we can get there using a few things:
- dataview's task field specify a
task.position.start.line - AdancedURI: which has
lineparameter to open a file at a given line but also anopenmodeone to control how does the file open. (silent, popup etc)
This is why initnermediary our query earlier we were recording the line of the tasks, now we can leverage it.
Our custom rendering script can build a markdown link element with target being an advancedURI to our current Vault with a given filename/line essentially making it a task link.
Here is what it can look like:
const createAdvancedLink = (filePath, displayText, options = {}) => {
const encodedPath = encodeURIComponent(filePath);
let uri = `obsidian://advanced-uri?filepath=${encodedPath}`;
// probably better to specify a vault or retrieve the current active ones
// Or use it for cross vault communication
if (options.line) {
uri += `&line=${options.line}`;
}
if (options.openmode) {
uri += `&openmode=${options.openmode}`;
}
return `[${tp.user.truncate(displayText)}](${uri})`; // a lot of the utilities can be shared across rendering script as Templater module
};
then later in the rendering script, import the previous function and when going over the rows of the collected query result.
if (row.type === "task") {
newRow.summary = createAdvancedLink(newRow.file, truncatedText, {
line: row.line + 1,
openmode: "tab",
});
}
if(row.type === "file") {
newRow.summary = createAdvancedLink(newRow.file, truncatedText, {
openmode: "tab",
});
}
In order to get target links like:
obsidian://advanced-uri?filepath=myFileHere.md&openmode=tab&line=12
and markdown table cells like [Some Title Here for a task](obsidian://advanced-uri?filepath=myFileHere.md&openmode=tab&line=12)
Conclusion
We've lost some functionality: we can't see a preview of a file on hover in our queries and we can't group rows (well we could actually we just need to add it in one of the rendering script).
We have:
- stopped dataview's constant re-render/query runs
- collected both tasks and files in the same queries
- got the ability to copy and annotate our restuls
- documented our queries with code in a single place
- created re-usable rendering templates to replace dataview's basic table rendering
- created links to tasks
- created a basic inter-process communication loop with dataview, templater, advanced URI and json's on disk.
Because the queries don't run nearly as often we also have improved performance and user experience with no flickering an re-rendering.
Despite sounding involved and requiring some overhead in mapping out all the elements, documenting a new query takes very little effort:
a simple js file in for the core and a new entry in the serialAllQuery.js module.