Technical Site Notes

I've been intrigued by statically-generated sites, and as sort of an experiment, decided to build the latest iteration of my personal website using markdown files managed in Obsidian and published via the Obsidian Digital Garden plugin.

Below are notes on how I built the site, in part for me when I undoubtedly start wondering why or how the heck I did something!

Table of Contents

Obsidian setup

I spun up a separate vault for this site, since I didn't want to publish everything in my current personal vault and figured it'd be easier to separate what should and shouldn't be published if I used separate vaults. Also this vault is structured a little differently than my personal vault, and is a little more disciplined when it comes to random Obsidian plugins.

The theme in use is the standard Minimal Theme using the Atom color scheme, with a few differences (mostly increasing header sizes.)

Obsidian plugins in use:

Aside from the Digital Garden plugin, these are the standard plugins I tend to use across all of my Obsidian vaults.


Digital Garden setup

I basically followed the standard directions, but opted to publish to Netlify instead of Vercel. Dude, That's Erin has a helpful, detailed writeup that walks you through the Github and Netlify steps (unfortunately no longer online but you can still refer to the Netlify section in the official doc's Hosting Alternatives page.)

Templater template

The Obsidian Digital Garden plugin makes use of a number of YAML properties, and it was a no-brainer to use Templater to pre-populate those with some default values. (You can do this with the core template plugin as well, but I tend to just use Templater for all my templates by default.)

My basic draft template looks like this:

---
dg-publish: false
dg-home: false
dg-hide: true
dg-metatags:
 "og:description": ""
date-created: 
date-modified: 
---
# Title

This is my template for draft files, so dg-publish is set to false to begin with and I just manually toggle it to true when I'm ready to include the file in publishing. I hide the majority of new notes from the filetree, so dg-hide is set by default to true. The rest of the properties, and other options you can use, are explained in the official docs: Note Specific Settings and Timestamp Settings

(I manually update date-modified because I do tinker with the site a fair amount and I didn't want to the dates to update every single time a page was republished. And yes, I do use a little Templater template to populate the date/time for me so I don't need to worry about entering it exactly right.)

One-click publish a page

Sometimes I'm making a quick edit to a page and want to just one-click republish that single page. Using the Commander plugin, I've got the Publish single note command assigned to a button on the Tab Bar so republishing that note is just a click away.

Where the new button appears on the Tab Bar:
the top of a tab in Obsidian, to the right is highlighted a button labeled "Digital Garden: Publish Single Note"

Corresponding setting in Commander:
Commander settings for the Tab Bar showing an added command for "Digital Garden: Publish Single Note"

I do still keep the Digital Garden Publication Center on the Obsidian ribbon and use it whenever I've got more than one page to publish or if I'm just unsure all necessary changes have been published to the site.


Customizations

In no particular order, except maybe chronological for when I addressed them.

Adding a robots.txt file

This helpful Github comment explains where to upload your robots.txt file and what changes need to be made to .eleventy.js: https://github.com/oleeskild/obsidian-digital-garden/issues/208#issuecomment-1765797620

(My own robots.txt file does not look like the one in the linked comment; I use mine mostly to block known AI/LLM crawlers.)

Hiding empty folders in the filetree

Another helpful Github comment explains how this can be done: https://github.com/oleeskild/obsidian-digital-garden/issues/356#issuecomment-1749921461

(Like with the edit to support robots.txt, I expect I might need to reconcile these edits with future updates to the Digital Garden plugin.)

Adding icons for top-level pages that appear in the filetree

These icons are the book, pen nib, luggage, etc. icons you see in the filetree in the left sidebar menu. Custom icons are supported in Obsidian Digital Garden using properties and custom CSS. See: https://dg-docs.ole.dev/advanced/note-specific-settings/#note-icons

The icons I use are all from: https://icons.getbootstrap.com/

Partially addressing printing issue

Out of the box, none of the pages published via Obsidian Digital Garden would print for me. This has been previously reported: https://github.com/oleeskild/digitalgarden/issues/218

This appears to be a css issue. The below bit included in obsidian-base.scss would seem to prevent anything that doesn't have a print class from printing:

@media print {

  body > :not(.print) {
      display: none !important;
    }
}

I manually added the print class to the main element in both note.njk and index.njk so at least something prints for now.

<main class="content cm-s-obsidian print {{contentClasses}}">

A little hacky, admittedly. Does lead to a known issue where the left sidebar will prevent some content from printing. The workaround for now is just to resize the browser window (make it smaller/narrower) so the left sidebar is hidden before printing.

My css is pretty rusty and a more elegant fix is going to need someone with more expertise than me!

Appending site name to html title element

I wanted the site name to appear as part of the html title element. This was another note.njk edit, just appending - {{meta.siteName}} to the end of the existing title element.

Depending on how you've named your homepage, you may or may not need to make a similar edit to index.njk.

Hardcoding some metatags

Metatags are supported using properties: https://dg-docs.ole.dev/advanced/note-specific-settings/#metatags

I wanted to hardcode a few metatags though, so I wouldn't have to enter them in every note. I felt ok entering/editing description, for example, but wanted fields like title and especially url to be populated automatically.

Metatags are handled in pageheader.njk and prior to my local edits, the relevant part looked like this:

{% if metatags %}
    {% for name, content in metatags %}
        <meta name="{{ name }}" content="{{ content }}">
    {% endfor %}
{% endif %}

After edits, now looks like this:

{% if metatags %}
    <meta property="og:type" content="website">
    <meta property="og:title" content="{% if title %}{{ title }}{% else %}{{ page.fileSlug }}{% endif %} - {{meta.siteName}}">
    {% for name, content in metatags %}
        <meta property="{{ name }}" content="{{ content }}">
    {% endfor %}
    <meta property="og:url" content="{{ meta.siteBaseUrl }}{{page.url | url }}">
{% endif %}

Can see that type is now hardcoded, and title and url are automatically populated with the same fields used elsewhere on the site. I also broadly changed the name attribute to property following: https://ogp.me/

Definitely not using the Open Graph Protocol fully, but some semblance of a card at least appears now when I post on social media!

Highlighting filetree for nested notes

By default, the filetree in the left sidebar only highlights the menu item for the exact note. With the way I have my notes organized, I also wanted it to highlight matching menu items for nested notes as well. For example, I have this Technical Site Notes note stored under my Tinkering folder. I also have a note at root called Tinkering. By default, the Tinkering menu item in the left sidebar would only be highlighted if I were actually visiting the higher-level Tinkering note and not if I were visiting any of the notes I have stored under the Tinkering folder. I wanted the higher-level menu item to be highlighted for nested notes as well.

This change is handled in filetree.njk. Before edits, the relevant portion looked like this:

{%if fileOrFolder.isNote and not fileOrFolder.hide %}
     <div @click.stop class="notelink {{ 'active-note' if fileOrFolder.permalink === permalink}}">

After edits, now looks like this:

{%if fileOrFolder.isNote and not fileOrFolder.hide %}
    <div @click.stop class="notelink {{ 'active-note' if permalink.startsWith(fileOrFolder.permalink) }}">

Basically, altering the logic so it just looks for the note permalink to start with the path and not necessarily be an exact match.