I’m trying to replace my dataview scripts with Bases as much as possible.
Now I’m looking for a way to embed a base inside a file that I will embed on multiple locations, trying to keep maintenance on only one place.
What I want:
I have a template/file for people, let’s say writers. In the file of each person-writer, I want a section where I list:
what books he wrote (base-view)
what blog-articles her wrote (base-view)
what podcasts he appeared on (base view)
I want these base views to be separated by headers, so I made a file to create (and edit) that, but I can’t get the bases to refer to the original file.
The current structure would be (for example):
Original file: Cal Newport.md
Embedded file: writer statistics.md with H2-heading “Books”
Embedded base: books.base
How can I filter the Base, based on the original file (Cal Newport.md in this case)?
If you create a base file (as opposed to a base block in an existing file), then you can use the this keyword to refer to the file in which the base is embedded.
For example, I have a “Backlinks.base” file which has the following filter:
The problem is that an embedded file seems to be completely agnostic of the embedding file. Embedding a .base file into your writer/person file works because the writer file parses the base as if it were part of the writer file itself (like using the code block form of bases), not because the base file “knows” anything about the writer file. So the solution by Craig above works for if you filter by writer == this.person_name in my example below, but it won’t work for nested embeds, i.e. a base that is more than one level “below” the writer file.
Cal Newport.md
---
person_name: Cal Newport
---
# Cal Newport
Some text about this writer here ...
![[writer statistics]]
You could have that directly in your writer/person template. Of course it would be convenient to have writer statistics.md as a reusable component that will have any modifications reflected in all writer files, but that doesn’t seem possible for now. I can think of a middle-ground solution where you have it as a “sub-template” that you include in the main writer template via Templater:
The information is available, but it’s a matter of showing it the right way. When I use your setup, I can get this to work (“creator_statistics.md” as an embedded file inside “Cal Newport.md”. A Base called backlinks embedded inside “creator_statistics.md”).
It’s now just a matter of getting file.backlinks as a list in the first column…
I was looking for help with this, and I think I have the same issue.
I have Quick Notes tagged “Inbox”. The template also has the property “created_link” which is the link to the current daily note.
I have a “boilerplate” note called “Daily Note Header”, which is embedded in every Daily Note. This includes a navigation bar with useful links, and I want to include an embedded Base which will show notes with “created_link” containing the current daily note.
The problem is that the Base uses the filter created_link.contains(this.file.name), and in the context of the embedded base, this is referring to “Daily Note Header” and not the daily note that the header is included in.
Is there any way to specify the required context of this? Is there another way to do what I want?
In setting up a vault to do genealogy research, I ran into a similar problem of including another file and having the included file use the frontmatter context of the including file. There are three plugins that I have tried: Meta Bind, Dynamic Embed and Virtual Content. All three allow bases references to inherit the including file’s frontmatter
Meta Bind or Dynamic Embed: Place meta-bind-embed or dynamic-embed block in the file that embeds another markdown file which contains bases link references or bases blocks.
Virtual Content: This lets you select which files get embedded and in which files by rules in the settings. This does not require blocks to be defined in the including file, and it can be used more dynamically to with a switch in each rule to turn it on and off.
With the requirement of frontmatter inheritence met for Bases, I required definition of the views a base (filters, properties, formulas, etc.) start from a default definition. This led to the use of base block definitions. This makes maintenance a pain. Include a file that references the base as a Name.base file (which you keep squirreled away), make the changes than copy the text into the base block definitions. Works, but by using the following dataviewjs code in the included file it becomes more automated. This keeps the “master” definition intact, but lets the user interact with the database. When the page is refreshed the definition of the view is restored to the default.
// Define the paths to your Bases .base files
// that will be converted to inline blocks
const filePath = "Bases/Related.base";
// Get the file object from the Obsidian vault
const file = app.vault.getAbstractFileByPath(filePath);
// Check if the file exists and is actually a TFile (Obsidian's file type)
if (file && file.extension === 'base') {
// Read the content of the file
app.vault.read(file).then(content => {
let embeddedbase = ''
// Render the file content as a paragraph in the current note
embeddedbase = '\n'
embeddedbase += '```base'
embeddedbase += '\n'
embeddedbase += content
embeddedbase += '\n'
embeddedbase += '```'
embeddedbase += '\n'
dv.paragraph(embeddedbase)
});
} else {
dv.paragraph(`File not found at path: ${filePath}`);
}
The documentation also says this only refers to the note that the base is embedded in, so I think there is currently no way to get the open note from inside an embedded note with the base.
It probably make sense that this still points to the embedded note in most cases, but I agree it would be great to get some kind of way to access the “root” note that is currently active.
@ThurMeijer@MatthewPetty it seems I have found a workaround for now, bit hacky but works. It’s very heavily inspired by what @eagonza posted,
To make sure I got you right - you have three files -
books.base - where you list all the books and probably have a view like author.bookswhich filters books based on property author==this.file.name
writer_template.md- where you embed with ![[books.base#author.books]]
Cal Newport.md - where you want to embed your writer_template.mdbut in a way that lists Cal’s books
the solution from @eagonza of embeddind a base codeblock didn’t work for me, the this keyword in the base filter still pointed to the template writer_template file for me.
and the writer file inserts the text of the template file
%% Cal Newport.md %%
Some comments specific to Cal Newport go here
```dataviewjs
// Define the paths to your template file
const filePath = "templates/writer_template.md";
// Get the file object from the Obsidian vault
const file = app.vault.getAbstractFileByPath(filePath);
// Check if the file exists and is actually a TFile (Obsidian's file type)
if (file && file.extension === 'md') {
// Read the content of the file
app.vault.read(file).then(content => {
let embedfile = ''
// Render the file content as a paragraph in the current note
embedfile = '\n'
embedfile += content
embedfile += '\n'
dv.paragraph(embedfile)
});
} else {
dv.paragraph(`File not found at path: ${filePath}`);
}
```