Dataview plugin snippet showcase

I have a simple table to collect my journal entries related to a given book. I’m trying to have one of the columns show a link to the heading where I wrote the entry:

table Chapters, file.link+"#Reading:: The Lost Symbol" as Link
from #my/journal where Reading="The Lost Symbol"
sort file.ctime asc

And it results in this
image

Instead of resulting in a [[2021-05-23#Reading The Lost Symbol]] link, it gives me a separate text ([[2021-05-23]] reading …)

I’m not very literate in codes, but I’ve been studying the documentation to see if there’s a way to achieve this. Do you guys know if it’s even possible?

Nevermind: found the answer here: Dataview plugin snippet showcase - #158 by jyrodgers

I want to do this (extract data from a field for use in the query) as well.
Context: I want to make a query that shows people I haven’t contacted in a defined amount of time. The people have a field ‘desired contact frequency’ and in it is ‘2 weeks’ or ‘2 months’, whatever. The query:

TABLE 
context, file.mday AS "Last Contact"
FROM "3 - Resources/People" 
WHERE desired-contact-frequency AND file.cday <= date(now) - dur(1 week) 
SORT file.mday ASC

^ Works

\/ Doesn’t work:

TABLE 
context, file.mday AS "Last Contact"
FROM "3 - Resources/People" 
WHERE desired-contact-frequency AND file.cday <= date(now) - dur(desired-contact-frequency) 
SORT file.mday ASC

There’s probably a way to do this in the js version, but 1) I’m not capable of that and 2) it seems like if there’s a way to access “desired-contact-frequency” this is a much simpler format.

Instead of this, could you try,

"[[" + file.name + "#Reading:: The Lost Symbol]]"

You can even add alias to the link if it gets long like,

"[[" + file.name + "#Reading:: The Lost Symbol|The Lost Symbol]]"

4 Likes

Oh! It worked. That’s amazing, thanks a bunch, Rishi. :smile:

1 Like

Here’s a snippet I use to make lists render as comma separated items instead of bullet points:

dv.table(
    ['File', 'Connections'],
    dv.pages('[[Foo]]').map((page) => {
        return [
            `[[${page.file.name}]]`,
            page.file.outlinks
                .reduce((acc, outlink) => {
                    acc += `[[${outlink.path.replace(/\.md$/, '')}]], `;
                    return acc;
                }, '')
                .trim()
                .replace(/,$/, '')
        ];
    })
);

Now this is very close to:

Table file.outlinks as Connections
From [[Foo]]

Except that the list renders differently. Obviously that is a lot of code to write just for a format change, but I like how the table looks quite a bit more with that.

Here’s a slightly cleaner version with .map():

dv.table(
    ['File', 'Connections'],
    dv.pages('[[Foo]]').map((page) => {
        return [
            `[[${page.file.name}]]`,
            page.file.outlinks
                .map((link) => {
                    return `[[${link.path.replace(/\.md$/, '')}]]`;
                })
                .join(', ')
        ];
    })
);

But all are superseded by @Rishi’s suggestion of the undocumented join():

8 Likes

This should make them identical,

Table join(file.outlinks, ", ") as Connections
From [[Foo]]

This function needs to be added to the docs still but you can find the relevant discussion on Github.

4 Likes

Awesome!

Hi everyone!

I’d like to implement a GAO (Got Aware Of) tracking system.

For any book or website, one note containing several records of type

GAO:
  When: [[2021-06-02]]
  What: [[Topic-name]]

Then, in each daily note, something like

```dataview
LIST GAO.What
FROM "Resources"
WHERE GAO.When = this.file.name

But this, unfortunately, doesn’t work…

Is this possible somehow? Any idea?

Thanks in advance.


silvio

Could you try,

WHERE GAO.When = this.file.link

I have not been able to get a query where multiple fields in one note are shown in a query. Only the last record in a note will be shown. So … if anybody could that working I would be very interested also.
(without falling back on multipage dataviewjs queries)

This was implemented in 0.3.10.

Thank you @Rishi… but this doesn’t work, either.

Two problems here:

  1. WHERE GAO.When = this.file.link doesn’t match.
  2. Removing the WHERE clause, just the last
GAO:
  When: [[2021-06-02]]
  What: [[Topic-name]]

is shown. In other words, if I put

GAO:
  When: [[2021-06-02]]
  What: [[Topic-name-1]]

GAO:
  When: [[2021-06-02]]
  What: [[Topic-name-2]]

in my YAML frontmatter, just the second is shown.

That is invalid YAML I am certain. Parsing it removes the duplicates and retains the last one. The feature which was implemented in Dataview 0.3.10 (and I tested it again) works only with inline dv fields and not YAML.

Regarding the first one, it works on my end. Here’s how I tested: In one file, I have your YAML with duplicate GAOs. Then I use this same query in two different files, one with daily note where it should match the condition and one where it shouldn’t.

TABLE GAO, g
FROM ""
WHERE GAO.When = this.file.link

This is the source file

Dataview output for both files with edit and preview on left and right respectively

First of all: @Rishi, thank you so much for your time, seriously!

Then:

  1. When I duplicate the GAO structure in the YAML frontmatter, Obsidian doesn’t say “invalid YAML”, but yes, it just retains the last one.

  2. I would prefer not to put them in the YAML frontmatter, but in this case (inline) how can I have field.subfield? According to my knowledge, this is not possible inline. Am I wrong (I really hope so!)?

My final goal is to show just What, provided When is matched.

You’re welcome! You are right, inline fields don’t support subfields unless there’s some syntax I’m unaware of. They do allow lists but the way where works with a list, we can’t just use contains() to find a substring from a list. I also thought perhaps using the When date as a key might work for YAML but that’s not supported either.

I can’t think of anyway to solve this except for using separate notes for each entry.

P.S. Have you considered just adding a GAO: [[2021-06-03]] to the note for the book/website?

Oh, sorry to be… right!

Let me better explain my use case, because I believe it’s not a strange one. So a work around it could be of interest for many.

Today I start to read Book_1. Then I write a new note for it, filled with all the usual stuff (author, title, etc.). At a certain point, reading it I Get Aware Of (GAO) an interesting Topic_1. Consequently, I’d like to keep track that this happened today, reading Book_1.

Tomorrow, reading Book_1 I’ll GAO an interesting Topic_2. Etc.

In today’s daily note I’d like to have all the interesting things I discovered… today! Topic_1 from Book_1, for sure, but also (say) Topic_3 form WebSite_1, etc.

In tomorrow’s daily note, Topic_2 from Book_1, etc.

(OK, as you all guessed, English is not my mother-tongue…)

:smile:

I see what you are trying to do. I do something very similar. I keep a log of things I have read and watched and this is how I track it, taking your example above.

Say I read Book_1 today and discover the Topic_1, this is what goes in my daily note:

- #Read:: Started reading [[Book_1]] recommended by [[kenNash]] and came upon the realisation that [[Topic_1]] is interesting.

I’ll then click on [[Topic_1]] to write something about it. And in that note, I’ll add the YAML GAO: 2021-06-03.

At the end of the day, I’ve dates for both the activity of reading the book as well as for creating the topic originating from/inspired by the book. Although the book and topic are not directly linked, they are linked through the daily note. That can be easily fixed if you decide to add a Source field to the topic. I’d suggest doing that outside of YAML since links in YAML don’t show up in backlinks. With that, all the three entities (daily note, book note, topic note) either link to each other or have a backlink.

Continuing to the next day, my daily note might look like,

- #Read:: Read chapter 3-4 of [[Book_1]] and it made me think of [[Topic_2]]

And follow the same process for [[Topic_2]]

Once this process is setup, I’d then create a new note for all my reading logs and call like Reading Log with a Dataview query to aggregate it all,

TABLE Read
FROM #Read
WHERE Read
SORT file.ctime DESC

It should look something like this (screenshot from my Watched Log

And for your specific use case of the GAO, I’d create another GAO Log note and use something like this in there,

TABLE GAO, Source
FROM #topic OR "ZK"
SORT file.ctime DESC

This should give you all topic notes most recent first, along with their GAO date and Book. Note that you can add multiple dates in the GAO YAML field and also multiple Sources in the Topic file in case you rediscover the same idea later from a different book. Dataview will show those as a list (you just need to ensure that you enter them both in the same order). You can see this from my screenshot where sometimes I watch multiple things during the day and it is shown just fine.

If you notice I’m using a tag for the Read key for Dataview. I do that so that it serves dual purpose. #Read:: works both as a Dataview inline key as well as a regular markdown tag. So if I’m working on my vault in another app (or if Obsidian goes away sometime in the future), I can still at least search for all these lines easily. Plus I also have a regular query in my log files which is simple like,

```query
tag: Watched

I keep this around because it gives me better context around the lines but the Dataview query allows me to sort and show multiple fields in columns.

Hope this gives you (or others) some ideas for a logging workflow.

6 Likes

This morning I was trying to show only files with a folder depth of 2. I figured out this regex:

It can be simplified, but I left it that way so you can change the depth easily. set the {1,2} to {2} and it will only show those on the 2nd level. Or you can do {1,5} and it will up to 5 levels deep.

Here is how I use it:

```dataview
table file.path, file.name from "1. Projects"
WHERE regexmatch("^1. Projects(\/[^\/]+){2}$", file.path)
```

I wanted to show only the files inside project folders, but not the sub folders of project folders

2 Likes

Do you know if there’s a current workaround to search for file names containing certain strings in Dataview?

Figured it out using regexmatch! Here’s an example of my solution to search for a string within a file name and also to exclude strings from searching file names:

```dataview
list from ""
where regexmatch("^.*title-string-to-search-for", file.name) and regexmatch("^((?!title-string-to-exclude).)*$", file.name)
```
3 Likes