My Digital Garden Setup
This page is dedicated to my current website setup, my customizations, bugs, rough edges which still exist and potential workarounds.
The Setup
- I write texts within Obsidian.md.
- I use the plugin Obsidian Digital Garden, which publishes notes of my choosing firstly into a GitHub Repository.
- Said repo is derived from this template, which houses an 11ty project.
- 11ty produces a static page which is then deployed with GitHub Pages.
Customizations and Bug Fixes
Here I track any issues I've encountered so far and how I deal with them. In most cases, I fix them within the Digital Garden template. I try to customize this the way it's meant to be customized, to avoid hassle when updating the template in the future, but this is often not possible for the issues I encountered.
General Issues, Bugs, Customizations
Deploying to GitHub Pages
Status: Resolved ✅
Description: The plugin is mainly aimed at Vercel, and lists Github Pages only somewhere in the "Other" section. There is no documentation on how to deploy to GitHub Pages.
Solution:
- Clone the Template Repository. It needs to be public, and it needs to be named
(yourname).github.io
as per the GitHub Pages Documentation. - Follow the set up of the Digital Garden plugin to connect Obsidian to that repository.
- In the repository settings, under "Pages", finish the setup of the page. As "Source", select "GitHub Actions".
- If GitHub comes with its own workflow, remove it (you can do this in the Actions tab in GitHub). You should also remove the build workflow the template comes with by deleting
.github/workflows/build.yaml
from the repository. - Place the
main.yaml
from below into.github/workflows/
to activate the workflow that builds the site. - Done! (Note that 404s do not work properly in all cases at this stage, there's a description on how to resolve it below.
main.yaml
to deploy the Digital Garden to GitHub Pages
name: GH Pages
on:
push:
branches:
- main # Set a branch name to trigger deployment
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
pull_request:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '23'
- run: npm install
- run: npm run build
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'dist'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Formatting breaks if there is no line break above a heading
Status: Worked around ✅
Description: Obsidian renders just fine if you put content directly above a heading, but formatting for a Digital Garden note breaks in this case.
Solution: I am using Obsidian Linter anyways , so all I had to do was to enable the rule "Heading Blank Lines". This prevents the offending formatting from happening.
Inefficient Transclusions
Status: Worked around ✅
Description: The plugin doesn't cache transclusions, so if you transclude e.g. a header in every note, then that header file is compiled for every single note again. This results in performance degradation during publishing.
Solution: Using transclusions as a header has other drawbacks as well, such as the header showing up in the RSS Feed or the built-in search. The Digital Garden plugin has a capability to add custom components, such as a Header, which I used instead of transclusions.
Opening the Publication Center on Mobile sometimes causes an app reload
Status: Watching 👀
Description: Pretty much what it says on the tin.
Solution: My current assumption is that this is due to the performance issues caused by DataviewJS and that this issue will go away once I solve these performance bottlenecks.
The first ---
below the front matter is not rendered
Status: Resolved ✅
Description: In any markdown file, the first line below the front matter which only contains ---
will disappear instead of rendering a horizontal line.
Solution: This is because of the following setting in the template's eleventy.js
:
eleventyConfig.setFrontMatterParsingOptions({
excerpt: true
});
This treats the first ---
as a signal that everything between the front matter and this separator should be made available as an excerpt, and the ---
is then removed. This can be solved, while retaining the functionality, by changing the options as follows:
eleventyConfig.setFrontMatterParsingOptions({
excerpt: true,
excerpt_separator: ""
});
This makes 11ty use the given separator, keeping the ---
intact.
Unnamed links are not supported
Status: Not a Bug ☑️
Description: Links without a title in the form of [[note-name]]
are ignored by the plugin.
Solution: Works as intended, and since I don't need this feature, I haven't invested in fixing this.
Links to headers in the same file are not supported
Status: Resolved ✅
Description: A link to a heading in the same file, as in: A link to the previous section
is not supported and leads to dead links.
Solution: In getAnchorAttributes()
within the .eleventy.js
, check if fileName
is empty and if so, set permalink
to ""
right away instead of attempting to load the file. Lo and behold: A link to the previous section.
Publishing fails without a visible error
Status: Open 🐛
Description: When publishing a lot of notes (e.g. by changing a setting which requires a re-publishing of all notes), then publishing of some notes fails. The developer console states that you have hit a secondary rate limit at GitHub. Yet, the plugin shows success for all notes.
Solution: None yet. Best workaround is to open the publication center again and check if there are still notes showing up.
Callout "names" are visible in search
Status: Resolved ✅
Description: Obsidian supports different callouts, and their type is define by a string like [!info]
. This string shows up in the search.
Solution: Extend the function userEleventySetup
in src/helpers/userSetup.js
as follows:
eleventyConfig.addFilter("removeObsidianCallouts", function(contentValue) {
if (!contentValue || typeof contentValue !== 'string') {
return contentValue;
}
const calloutRegex = /\[![a-zA-Z0-9-]+(?:\|[a-zA-Z0-9-]+)?\]/g;
return contentValue.replace(calloutRegex, '');
});
This filter actually filters out all kinds of names as long as they are in square brackets and start with an !
.
Then, in src/site/search-index.njk
, use this filter for the content as follows:
"content": {{ post.templateContent | removeObsidianCallouts // rest of line
Adding this filter to src/site/feed.njk
removes these callout names also from the RSS feed.
Preventing Dead Links
Status: Resolved ✅
Description: The plugin does a great job in gracefully handling dead links. Dead links can happen if:
- A published note is linking to a non-existing note
- A published note is linking to a non-published note
In either case, the plugin redirects to the 404 page. However, I do not want dead links at all.
Solution:
In the .eleventy.js
, I modified the function getAnchorAttributes
as follows:
function getAnchorAttributes(filePath, linkTitle) {
// .. other parts of this function..
if (deadLink) {
// Start addition
console.log("Dead link detected! Filepath: " + filePath + " | Link title: " + linkTitle);
throw new Error("Dead link detected! Filepath: " + filePath + " | Link title: " + linkTitle);
// End addition. Even though the following is dead code I leave it around.
return {
attributes: {
"class": "internal-link is-unresolved",
"href": "/404",
"target": "",
},
innerHTML: title,
}
}
With this, any build will fail on GitHub if a dead link is detected.
Issues with DataView
The digital garden plugin supports Dataview, but I have run into a couple of issues with this. This section covers them.
dv.current()
is empty in inline dataview JS queries
Status: Worked Around ✅
Description: Using dv.current()
to access the current file in an inline dataview JS query renders just fine in Obsidian but the result is empty on compiling.
Solution: My first solution was to use dv.pages()
in combination with Templater to get what I wanted. But given the performance issues I observed with dataview as well as the locale issues with Dataview, I decided to move away from js dataviews. Since I used them effectively for values that belong into the header and footer, I was able to get rid of them by moving that rendering logic to 11ty.
Dates are parsed inconsistently across devices
Status: Worked around ✅
Description: Using dataview to parse dates in a specific format yields to inconsistent results across devices. This is actually an issue with DataView, as on iOS, it uses the locale based on the system device settings for formatting instead of a locale based on the language Obsidian is in. DataView's documentation even states that formatting might have locale issues.
Solution: As mentioned in other sections as well, I was using this functionality mainly to replicate header/footer functionality. I moved this to 11ty.
Regular Dataviews produce bogus output
Status: Worked around ✅
Description: Dataviews sometimes produce a single { .block-language-dataview}
below the desired result.
Solution: I migrated to JS Dataviews first, but I ran into performance issues. Instead, I now remove that line during markdown pre-processing. I do this by extending the userMarkdownSetup
in the template file src/helpers/userSetup.js
as follows:
function preProcessRule(state) {
let currentContent = state.src;
currentContent = currentContent
.split('\n')
.filter(line =>
!line
.trim()
.startsWith('{ .block-language-dataview}'))
.join('\n');
state.src = currentContent;
}
md.core.ruler.before('normalize', 'user_markdown_preprocessor', preProcessRule);
This removes the offending line.
JS Dataviews have performance issues
Status: Partially Resolved ⏳
Description: JS Dataviews come with a significant performance overhead, as a JS environment needs to be spun up for every note that uses one. I had JS Dataviews in every file, which increased the compile time (needed for publishing) from seconds to minutes.
Solution: since most of these dataviews were built to create some kind of header or footer, I replaced most of them with custom components, as described above. There are still some dataviews remaining that I need to migrate.
Getting the 404 right
The default setup with 404 has a couple of issues:
- Ideally, I'd like to style/edit them directly from within Obsidian
- They don't work with GitHub Pages (GitHub doesn't use it as the default 404)
- They show up on the sitemap and on the feed, which doesn't make sense. Since the feed and sitemap have more issues, this will be handled in a dedicated section below
Edit 404s within Obsidian
Status: Resolved ✅
Description: To have better control over what the 404 page looks like, I would like to edit it in Obsidian.
Solution:
This one is fairly easy:
- In the template repository, delete
src/site/404.njk
- In Obsidian, create a note for your 404
- Set
dg-permalink
to404
Done!
Make 404s work with GitHub Pages
Status: Resolved ✅
Description: For internal broken links, the Digital Garden links correctly to its 404 page (unless you disabled this, as I did here. For invalid URLs, the default GitHub Pages 404 is displayed.
Solution:
If you did not set up your own 404 in Obsidian, all you need to do is to add the following front matter to the src/site/404.njk
:
---
permalink: 404.html
---
If you have set up your own 404, this requires more work. Simply setting dg-permalink
to 404.html
does not work, because the plugin transforms this to /404.html/
, which is not something GitHub Pages can work with. Even setting dg-pass-frontmatter
to true
does not prevent this.
To solve this, you need to add a file to your template. It needs to be placed right into the same directory where your 404 note ends up (somewhere in src/site/notes
), and it needs to be called (notename).11tydata.js
. In my case, the 404 note is located in src/site/notes/public
and is called 404.md
, so I need to create the following file in the following folder: src/site/notes/public/404.11tydata.js
.
The file needs to contain the following:
module.exports = {
eleventyComputed: {
permalink: data => {
return "/404.html";
}
}
};
This overrides the plugin setting for dg-permalink
and ensures the 404.html is written appropriately.
The following is not strictly needed, as without it, the 404 would still be displayed correctly, but for the sake of completeness I have also modified the getAnchorAttributes
within .eleventy.js
as follows:
function getAnchorAttributes(filePath, linkTitle) {
// .. other code ..
if (deadLink) {
//.. (potentially) other code ..
}
//.. remainder of the function..
return {
attributes: {
"class": "internal-link is-unresolved",
"href": "/404.html", // ⇐ add .html here
"target": "",
},
innerHTML: title,
}
}
Getting the Page Metadata right
Besides the layout and the notes, there are other metadata which need attention:
- The feed and the sitemap produce invalid XML
- To be a valid RSS feed, some more fields need to be added to the feed
- Besides what 11ty comes with out of the box, there is more I would like to add to the feed (such as the published date)
- The 404 shows up in the feed and the sitemap
- I would like to have some "fixed" metadata, like the author, available where appropriate.
The Feed and the Sitemap create incompliant output
Status: Resolved ✅
Description: Validation of e.g. the RSS feed fails because of invalid XML. Also, the respective files look a bit weird. For example, look at the following line in src/site/feed.njk
(notice the extra slashes at the end):
<link href="{{ meta.siteBaseUrl }}{{note.url | url }}" ////>
Solution: 11ty puts all files through a series of transformations in order to produce the result. These are defined in the .eleventy.js
and are added with eleventyConfig.addTransform
.
All transforms which call parse()
, so dataview-js-links
, callout-block
, picture
and table
transform, by the way they are using the result of parse
, a tag which is valid HTML to a tag which is invalid XHTML (needed for RSS).
Luckily, none of the transformations are actually needed for the feeds, so to fix this, all these transforms need to ignore files which will produce an XML file.
This can be fixed by amending the transformers as follows (taking the one named table
as an example):
eleventyConfig.addTransform("table", function (str, outputPath) {
if (outputPath.endsWith(".xml")) { // ↑↑ note the outputPath up there ↑↑
return str;
}
// .. remaining code
}
With this, the extra slashes in the feed.njk
and the sitemap.njk
can be removed.
I want to add more meta data to the feed, meta tags to the page and more data outside of my notes
Status: Resolved ✅
Description: The RSS feed isn't compliant out of the box, as it is missing some basic fields that apply to the entire feed, such as the author
. I also would like to add more fields to the feed, such as the published date.
And while we are at it:
- For anything that is not the index page, I would like to add my page's title to the end of the title, like "My notes - philipp's blog"
- I would like to add great social media previews, using for example the open graph protocol, and would like to make use of the relevant meta tags in the header.
- The 404 page should not show up in the feed(s).
Solution: The Digital Garden plugin comes with some very limited abilities to add meta tags, but only on a per-note level, which is not sufficient. Besides that, while I do have the created date of my notes available in the front matter property created-date
, I can only make this available in the 11ty template if I turn on the option to show timestamps. However, I dislike how the time stamps look and the lack of fine-tuning abilities, so I need to take a different approach.
Firstly, I am enabling dg-pass-frontmatter
in the global note settings. Despite the plugin's sternest warnings, the side effects were: None. But the desired effect was that now all my front matter keys and values that I use in Obsidian are available in 11ty.
However, this comes with a minor snag: My keys are mostly using kebab-case , and accessing kebab-cased variable names from within 11ty templates is awkward. And I am unwilling to change my kebab-casing in Obsidian.
This can be fixed by editing src/helpers/userUtils.js
. While I am at it, I will add some more stuff in there which will be useful in the upcoming steps. The entire file looks like this:
const { DateTime } = require('luxon');
function userComputed(data) {
return {
author: "Philipp Flenker",
email: "hello@philippflenker.com",
description: "thoughts on stuff, views on things",
builtAt: new Date(),
created: DateTime.fromISO(data["created-date"], { zone: "Europe/Berlin" }).toJSDate(),
updated: DateTime.fromISO(data["updated-date"], { zone: "Europe/Berlin" }).toJSDate()
};
}
exports.userComputed = userComputed;
All these keys are now available to me. You will soon see where I will use author
, description
and builtAt
. I map my front matter value created-date
to created
, and updated-date
to updated
, circumventing the kebab-case issue. At the same time, I take care of another issue:
My obsidian dates are without timezone information (as I don't need this), but I'd like to display timezone information in the RSS feed. And especially for builtAt
I need to be mindful of the timezone as I can't guess in which timezone the GitHub servers are located and which value this will produce for builtAt
if I'm not looking at the timezones. Since 11ty comes with the luxon library right away, I can make use of it as dealing with JS dates directly is very painful.
With this, I can update src/site/feed.njk
as follows ( I placed a logo.svg in src/site/img for the logo tag):
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="{{ meta.siteBaseUrl }}">
<!-- Other tags -->
<updated>{{ userComputed.builtAt | dateToRfc3339 }}</updated>
<id>{{ meta.siteBaseUrl }}/</id>
<author>
<name>{{ userComputed.author }}</name>
<email>{{ userComputed.email }}</email>
</author>
<subtitle>{{userComputed.description}}</subtitle>
<icon>/img/logo.svg</icon>
{%- for note in collections.note | reverse %}
<entry>
<!-- title tag -->
<updated>{{note.data.userComputed.created | dateToRfc3339 }}</updated>
<published>{{note.data.userComputed.updated | dateToRfc3339 }}</published>
<!-- remaining tags -->
</entry>
{%- endfor %}
</feed>
As you can see, I replaced the updated
date of the feed with my new builtAt
. The template was using some other means to find it, which works just fine as well, but this one is closer to what I think constitutes an update, as I expect any change to my page resulting in a change in one of the items exposed via the feed.
Let's also use these dates in the sitemap. We do so by adjusting the src/site/sitemap.njk
as follows:
<!-- Other tags -->
<url>
<loc>{{ meta.siteBaseUrl }}{{ page.url | url }}</loc>
<lastmod>{{ page.data.userComputed.updated | dateToRfc3339 }}</lastmod>
</url>
<!-- Other tags -→
Adjusting the title next is easy. Open the file src/site/_includes/layouts/note.njk
, look out for the <title>
tag and change it as follows:
<title>{% if title %}{{ title }}{% else %}{{ page.fileSlug }}{% endif %} ・ {{ meta.siteName }}</title>
siteName
is the name of the page defined in the Obsidinan plugin description. This layout (note.njk
) is used for every file except the one that is defined as the home page.
We're going to add all the relevant meta tags next. For this, we are going to leverage the ability to add custom components and create the following new file: src/site/_includes/components/user/common/head/metatags.njk
. This file will house all the metadata that are common between "regular" files and the index/main page.
This is what I added:
<link rel="canonical" href="{{ meta.siteBaseUrl }}{{ page.url | url }}" />
<meta name="author" content="{{userComputed.author}}" />
<meta property="og:title" content="{% if title %}{{ title }}{% else %}{{ page.fileSlug }}{% endif %}" />
<meta property="og:image" content="{{ meta.siteBaseUrl }}/img/logo.png" />
<meta property="og:url" content="{{ meta.siteBaseUrl }}{{ page.url | url }}" />
<meta property="og:site_name" content="{{meta.siteName}}" />
<meta property="og:locale" content="{{meta.mainLanguage}}" />
There are also some properties I only want to show up on the main page. These go into src/site/_includes/components/user/index/head/metatags.njk
(The only difference is the folder name "index" instead of "common"):
<link rel="alternate" type="application/rss+xml" title="{{ meta.siteName }} - {{ userComputed.description }}" href="{{ meta.siteBaseUrl }}/feed.xml" />
<meta name="description" content="{{ userComputed.description }}">
<meta name="og:description" content="{{ userComputed.description }}" />
<meta property="og:type" content="profile" />
Last but not least, there are some tags I only want to show up everywhere except for the index page. For these pages, it would be great to add a short description to one of the meta tags if it's available. I want to be able to use a front matter key - excerpt
- for this, or alternatively the "excerpt" feature explained in this section above. So we create another file with the same name and a similar path, src/site/_includes/components/user/notes/head/metatags.njk
:
<meta name="og:type" content="article" />
<meta property="article:author" content="{{ userComputed.author }}">
<meta property="article:published_time" content="{{ userComputed.created }}">
<meta property="article:modified_time" content="{{ userComputed.updated }}">
{%- set description = excerpt or page.excerpt %}
{%- if excerpt %}
<meta name="description" content="{{ description }}">
<meta name="og:description" content="{{ description }}" />
{%- endif %}
excerpt
will be filed by the property we set in obsidian. page.excerpt
will be filled if the given note made use of the excerpt modified described above. If neither is present, no description will be generated.
Since we've enabled passing the front matter, let's also hide the 404 from the feed. It's as easy as setting a new property, eleventyExcludeFromCollections
, to true
in the front matter of the 404.md
.
Setting up Pagination
Status: Resolved ✅
Description: I have a few items for which I want to set up an overview page. I can do this with DataView, but this comes at a couple of drawbacks:
- Performance in Obsidian: Especially for large numbers of notes, the performance within Obsidian degrades.
- Publication Performance: Every time you open the Publication Center, all notes need to be compiled again, and the ones which are heavy on DataView drag down the overall performance.
- Lack of (dynamic) Pagination: You can't automatically create pagination. Either you go with one huge page that shows all entries, or you manually need to set up notes for each page, which contributes to the aforementioned performance issues.
Solution: I generally have two types of notes where I need pagination for: Articles and Blips. Their respective "needs" when it comes to pagination differ from one another, so I will describe how I made both work.
Let's start with Articles. I want all my articles to show up as a paginated list. I also want the 3 most recent articles to be part of my front page.
11ty has the concept of collections and provides means to handle collections in various ways. The Digital Garden template makes use of this, as it puts all notes except the index page (and the ones for which we specifically requested to be taken out of any collection witheleventyExcludeFromCollections
) into the collection note
.
Collections are best defined using tags, so the first step is to assign a tag to all my Obsidian notes which I want to show up in the pagination. A word of caution: If you want to display tags later on as well, you need to be careful with the tag you assign here. Either you will need to live with the fact that any note with the tag you used will show that as a tag in the pagination, or you will have to live with the fact that the tag will not show up even if you want it to. Inline tags will still show up, but beware of conflicts with the "clickable tag" feature.
I decided to use the tag dgarticle
.
Next, I want to define a custom filter that turns my dates into a nice human-readable format. I do this in the userSetup.js
as follows:
const { DateTime } = require('luxon');
//.. other content ..
function userEleventySetup(eleventyConfig) {
eleventyConfig.addFilter("dateToShortString", function (date) {
return DateTime.fromJSDate(date).toFormat("dd LLL, yyyy");
});
// .. other content ..
}
//.. other content ..
OK, now let's create the page which will house the pagination itself. This page will live directly within the 11ty repository, as making this work with a note within Obsidian is pretty complex.
Next, let's add a new file, articles.njk
. It should look like this:
---js
{
"updated-date": new Date().toISOString(),
"title": "All Articles",
"layout": "layouts/note.njk",
"permalink": "articles/{% if pagination.pageNumber > 0 %}{{ pagination.pageNumber + 1 }}/{% endif %}",
"pagination": {
"addAllPagesToCollections": true,
"data": "collections.dgarticle",
"size": 25,
"before": (paginationData) => {
const dataToSort = [...paginationData];
return dataToSort.sort((a, b) => b.data.userComputed.created - a.data.userComputed.created);
}
}
}
---
<ul class="paginated-list">
{%- for item in pagination.items %}
<li>
<time datetime="{{ item.data.userComputed.created | dateToRfc3339 }}">{{ item.data.userComputed.created | dateToShortString }}</time>
</time>
</span>
<a href="{{item.url | url}}">{{item.data.title}}</a>
</li>
{% endfor -%}
</ul>
<span>
{%- if pagination.previousPageHref %}
<a href="{{ pagination.previousPageHref | url }}">⏪ Previous</a>
{%- endif %}
{%- if pagination.previousPageHref and pagination.nextPageHref %}
⋮
{%- endif %}
{%- if pagination.nextPageHref %}
<a href="{{ pagination.nextPageHref | url }}">Next ⏩</a>
{%- endif %}
</span>
This will create all pages, starting with articles
, then articles/1/
, articles/2/
and so on. The lastmod
date in the sitemap will be the date on which the site is generated. A pinch of CSS makes this pagination look good.
There's one snag though: Linking from within Obsidian to this will result in a dead link. Since I do want to link to the article overview, I am going to fix this. To do so, I amend the function getAnchorAttributes
in .eleventy.js
as follows:
function getAnchorAttributes(filePath, linkTitle) {
const passThroughPaths = ["articles"];
// ..
if (!fileName) {
// This is from the "Heading Link Fix" above
permalink= "";
} else if (passThroughPaths.includes(filePath)) {
permalink = "/" + filePath;
} else {
// ..
}
// ..
}
OK, with that being done: I also want to display the latest 3 articles on the main page. Let's implement this as well.
I do this directly in Obsidian. The note which should contain the 3 articles gets a new prop: templateEngineOverride
will be set to njk,md
.
Then, I can simply add the following directly into the note where I want the articles to show up:
<ul>
{%- for item in collections.dgarticle | sort(attribute="data.userComputed.created") | reverse %}
{%- if loop.index <= 3 %}
<li>
<span>
<i>
<time datetime="{{ item.data.userComputed.created | dateToRfc3339 }}">{{ item.data.userComputed.created | dateToShortString }}</time>
</time>
</i>
</span>
<a href="{{item.url | url}}">{{item.data.title}}</a>
</li>
{%- endif%}
{%- endfor %}
</ul>
That's pretty cool!
OK, with Articles now working as expected, I want to set my eye onto the next thing: Blips. For Blips, I don't only want to list their titles (in fact, the titles are rather less interesting). Instead, I want to transclude the entire blip into the overview.
The setup is pretty much the same as for articles. The difference is in what we do to display each blip in the blips.njk
:
<!-- other stuff unchanged -->
{%- for item in pagination.items %}
{{ item.templateContent | safe }}
{%- if not loop.last %}
<hr/>
{%- endif %}
{% endfor -%}
Displaying the first blip in the index file is almost straightforward. It requires adding the following to the Index:
{%- set item = collections.dgblip | sort(attribute="data.userComputed.created") | reverse | first%}
{{ item.templateContent | safe }}
I say almost, because this runs into an error claiming that I access templateContent
too early.
This can be solved by adding the following to the frontmatter:
eleventyImport:
collections: [dgblip]
The space in front of collections
is crucial. dgblip
is the tag I assigned to this collection. I found it easier to set in Obsidian's source mode.