Git Push ultrainsync.github.io repo will start GitHub workflow of serving GitHub Pages (with no-indexing business and tax folders)
run npm run build:adsvise and put it inside /on/ folder inside adsvise.me
npm run dev will default to GitHub workflow (which is no-indexing adsvise.me/on blogpost)
compare customized Digital Garden repo with main dev at .tmp/digitalgarden
use insert margin note + ;; for sensitive information (it will omit from publishing it)
Gripes
Operon todo
embedding operon task (with its Id) dont show stylized checklist.png\|410
Customizations (Divergence from Upstream)
1. Obsidian Plugin (obsidian-digital-garden)
We maintain a custom fork of the Obsidian plugin to enforce a strict security boundary for transclusions.
- Why: The upstream plugin blindly resolves all embeds, meaning if you embedded a private file inside a public file, the private file's contents would leak into the static site.
- Our Fix: Modified
src/compiler/GardenPageCompiler.ts(for Markdown embeds) andsrc/compiler/CanvasCompiler.ts(for Canvas file nodes) so that if an embedded file (Markdown or Canvas) is not marked for publishing, it intercepts the embed and replaces it with a beautiful, natively-styledProtected blockUI lock box (omitting iframes and broken 404 links entirely). - Maintenance: We maintain this patch on the remote
feat/redact-private-transclusionsbranch. We bumped the version to99.99.99inmanifest.jsonto prevent Obsidian from auto-overwriting it. If you ever want to update the plugin from upstream:- Fetch and merge the upstream release tag into the
.tmprepo. - Merge the
feat/redact-private-transclusionsbranch into your active branch to apply the "Protected block" patch. - Run
npm installandnpm run build. - Copy
main.js,manifest.json, andstyles.cssback to your.obsidian/plugins/digitalgardenfolder.
- Fetch and merge the upstream release tag into the
2. Static Site Template (ultrainsync.github.io)
When pulling updates from https://github.com/oleeskild/digitalgarden, be aware of the following local customizations we've made to support dual deployment (ultrainsync.github.io and adsvise.me/on/).
Date: July 26, 2026
Conversation ID: 902be4ad-e781-42a1-91d2-67c77defc3e7
Haft Decisions: prob-20260725-a2fdb368, dec-20260725-27f791ac
Changes Made:
-
.eleventy.js: Added dynamicpathPrefixinjection.- What changed: Appended
pathPrefix: process.env.PATH_PREFIX || "/",to the returned configuration object at the end of the file. - Why: Allows Eleventy 3.0's HTML Base Plugin to automatically rewrite all
hrefandsrcpaths in the generated HTML based on the deployment target (e.g., prepending/on/for adsvise.me).
- What changed: Appended
-
package.json: Added custom dev and build scripts.- What changed: Added
"build:adsvise": "cross-env PATH_PREFIX=/on/ npm-run-all get-theme build:sass build:eleventy"and"dev:adsvise": "cross-env PATH_PREFIX=/on/ npm-run-all get-theme build:sass --parallel watch:*"to thescriptsobject. - Why: Used to build and preview the site targeting the subfolder deployment (Adsvise) with the correct
PATH_PREFIXenvironment variable.
- What changed: Added
-
src/site/_data/meta.js&src/site/_includes/components/pageheader.njk: Added Conditional SEO NoIndex.- What changed: Exported
pathPrefixinmeta.jsand added Jinja if-statements inpageheader.njkto inject<meta name="robots" content="noindex, nofollow">. - Why: Prevents duplicate content SEO penalties. Prime/Public rank on Github Pages; Profession/Passion rank on Adsvise.me.
- What changed: Exported
-
src/helpers/filetreeUtils.js: Dynamic File Tree Hiding.- What changed: Intercepted the
getFileTree(data)function to check thenote.filePathStem. Ifprocess.env.PATH_PREFIX === '/on/'(Adsvise), it skips adding notes fromon/Primeandon/Publicto the tree. If it's Github Pages, it skipson/Passionandon/Profession. - Why: This hides the irrelevant folders from the left sidebar UI, while respecting the Obsidian Path Rewrite rules, and without needing to physically ignore files during Eleventy build (which would break search/graph).
- What changed: Intercepted the
-
.eleventy.js: Operon tag stripping and task transclusion (embeds).- What changed: Added custom
markdown-itcore rules near line 163. Thetransclude_operonrule interceptspathwikilinks, synchronously fetches the target file fromsrc/site/notes/, extracts the specific task by itsoperonId, and directly replaces the wikilink with the raw markdown task text. Then,strip_operonsilently strips out `` metadata tags from the raw markdown. - Why: This replicates the Obsidian Operon plugin's behavior by turning dead anchor links into basic native checklists on your website, avoiding complex HTML wrappers and styling conflicts while keeping backend parameters hidden.
- What changed: Added custom
-
.eleventy.js: Internal LinkpathPrefixfixing.- What changed: Added an
applyPathPrefixhelper and wrapped thehrefoutput ofgetAnchorAttributesto ensure it dynamically injectsprocess.env.PATH_PREFIX. - Why: The built-in markdown renderer for Canvas and wikilinks bypassed Eleventy's
urlfilter. When deployed to a subfolder (/on/), internal links in Canvas files were broken (pointing to the root/instead of/on/). This patch ensures internal links correctly respect the deployment prefix.
- What changed: Added an
-
linkUtils.js&.eleventy.js: Link Graph standard wikilink extraction.- What changed: Updated
wikiLinkRegexfrom/\[\[(.*?\|.*?)\]\]/gto/\[\[(.*?)\]\]/gacross the parsing logic. - Why: Previously, only aliased wikilinks (with a pipe
|) were registered as edges in the graph. This fix ensures standard wikilinksNoteare accurately captured to populate the link graph.
- What changed: Updated
-
graphScript.njk: Subfolder deployment path resolution for Link Graph.- What changed: Replaced the hardcoded
fetch('/graph.json')withfetch('{{ "/graph.json" | url }}'), and updatedfilterLocalGraphDatato stripmeta.pathPrefixbefore performing node lookups. - Why: The frontend widget was attempting to fetch graph payloads from the root domain and failing to identify the active node when deployed to
/on/. This ensures the link graph functions dynamically in subfolder deployments.
- What changed: Replaced the hardcoded
-
.eleventy.js: Optimized nested Canvas embeds.- What changed: Expanded the
canvas-markdownbuild transform to intercept any<iframe class="canvas-file-iframe">embedding a nested.canvasfile, swapping it out entirely at build-time with a lightweight blurred placeholder link (<a class="canvas-placeholder">). - Why: Recursively loading iframes for nested canvases causes massive performance drops and "flickering" UI bugs on the client side. A static placeholder eliminates DOM explosion, improves page load speeds, and boosts SEO while maintaining navigational UX.
- What changed: Expanded the
-
src/helpers/linkUtils.js: Graph View Standard Wikilink Fix.- What changed: Maintained
const wikiLinkRegex = /\[\[(.*?)\]\]/g;instead of upstream's strictly piped(.*?\|.*?). - Why: Upstream's regex strictly targets aliased wikilinks with a pipe. This customization ensures standard wikilinks (e.g.,
Actual Note Name) are correctly extracted as edges for the Graph View, rather than being ignored.
- What changed: Maintained
SOP: How to Safely Update the Template (Upstream Merges)
CRITICAL: DO NOT use the Obsidian Digital Garden plugin's "Update Template" button. It generates a PR that force-overwrites all customized files (like .eleventy.js, .njk, and .scss) back to the stock state, which will destroy our dual deployment, Operon transclusions, and custom SEO logic.
To safely update the template from Upstream Tags:
- Fetch Upstream: Ensure the upstream remote is tracked and fetch the latest tags via the terminal.
git remote add upstream https://github.com/oleeskild/digitalgarden.git git fetch upstream --tags - Merge the Tag: Use Git to merge the specific release tag (e.g.,
1.81.6) into our main branch.git merge refs/tags/1.81.6 - Resolve Conflicts Carefully: Git will successfully auto-merge core files we haven't touched. However, it will throw a merge conflict for files we have heavily customized. When resolving conflicts in these files, you must manually merge the code to ensure our custom logic remains intact while adopting the upstream dev's bug fixes:
.eleventy.js,package.json, andsrc/helpers/filetreeUtils.js: These contain logic vital for dual deployment (PATH_PREFIX).pageheader.njk: Contains custom conditional SEO NoIndex logic.src/helpers/linkUtils.js: Contains our critical regex override (wikiLinkRegex = /\[\[(.*?)\]\]/g) that ensures standard (non-aliased) wikilinks are extracted as edges for the Graph View.src/site/styles/digital-garden-base.scss: Contains our custom Image Captions and iframe UI contexts.