<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ssg on Idan Goldman</title><link>https://idan.goldman.work/notebook/tags/ssg/</link><description>Recent content in Ssg on Idan Goldman</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 14 Jun 2026 11:15:00 +0300</lastBuildDate><atom:link href="https://idan.goldman.work/notebook/tags/ssg/index.xml" rel="self" type="application/rss+xml"/><item><title>Content is King: A Thesis on Personal Website Architecture</title><link>https://idan.goldman.work/content-is-king-a-thesis-on-personal-website-architecture/</link><pubDate>Sun, 14 Jun 2026 11:15:00 +0300</pubDate><guid>https://idan.goldman.work/content-is-king-a-thesis-on-personal-website-architecture/</guid><description>&lt;img src="https://idan.goldman.work/content-is-king-a-thesis-on-personal-website-architecture/post-image-by-gemini.png" alt="Featured image of post Content is King: A Thesis on Personal Website Architecture" /&gt;&lt;p&gt;For years, I had developer&amp;rsquo;s block as a writer — trying to build/rebuild/optimize the website, putting my writings aside, chasing the perfect structure worthy enough to exhibit my thoughts, ideas, feelings, and work. All I wanted was a way to write and post the damn thing… yet all I did was code the damn thing, which got me blocked from writing the damn thing again and again. Now, I&amp;rsquo;m trying a new thing (for me): writing about how to build the damn thing while building the damn thing — dogfooding myself, if you will.&lt;/p&gt;
&lt;p&gt;So… my current thesis is: content should be front and center, with everything else kept aside and to a minimum.&lt;/p&gt;
&lt;h2 id="focus-on-content"&gt;Focus on Content
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;&lt;em&gt;Write &amp;gt; Publish &amp;gt; Read&lt;/em&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;Pretty simple, isn&amp;rsquo;t it? While it looks like any other generic content-publishing flow out there, my peace of mind lies in the details — keeping plumbing code out of sight, hidden in a dot folder, while content resides in the git repository&amp;rsquo;s root folder. Let me explain what I mean by that.&lt;/p&gt;
&lt;p&gt;In any other SSG/CMS setup, the codebase is front and center and the content is just a folder or database entry that plays its part. I don&amp;rsquo;t like that, because it takes my focus from writing the content to maintaining the codebase, as any other ADHD developer would.&lt;/p&gt;
&lt;p&gt;This time, content files are the main focus — as they always should have been — while the code setup files sit in a &amp;ldquo;hidden&amp;rdquo; folder at the top of the git repository. That way, when I open the main folder in any editor, the content is right there and not in a side folder a couple of clicks down.&lt;/p&gt;
&lt;h2 id="how-it-looks"&gt;How it looks
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;web/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ .forgejo/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ about.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─ home.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─ notebook/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ april-fools-beginning.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ i-want-to-tell-you-a-story.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ month-of-flying-by.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ public-beta-is-out/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ content.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ staticpage-logo.png
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ staticpage-landing-page.png
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ ready-to-go-full-time.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ studio.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Well, what do you think? To my eyes the codebase clutter is gone, and all I&amp;rsquo;m left with is structured content — files and folders translated into web paths, with some code plumbing underneath, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;about.md&lt;/code&gt; becomes &lt;code&gt;/about/index.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;home.md&lt;/code&gt; becomes &lt;code&gt;/index.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content.md&lt;/code&gt; files inside folders become &lt;code&gt;index.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Any media files (like images) related to a piece of content live beside it, in a folder named after that piece of content.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="how-it-works"&gt;How it works
&lt;/h2&gt;&lt;p&gt;The hidden piece of code plumbing (the magic) is done inside the &lt;code&gt;.forgejo&lt;/code&gt; folder. Take a look:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;web/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─ .forgejo/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ workflows/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ build.yml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ deploy.yml
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ quartz/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ custom.scss
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ quartz.config.ts
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ quartz.layout.ts
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So, what do we have here? &lt;code&gt;workflows&lt;/code&gt; and &lt;code&gt;quartz&lt;/code&gt; folders — one for building and deploying the website&amp;rsquo;s content you read here, and the other for the website&amp;rsquo;s configuration and customization you see here.&lt;/p&gt;
&lt;h2 id="why-forgejo-and-quartz"&gt;Why Forgejo and Quartz?
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Forgejo&lt;/strong&gt; is easy: I already enjoy using it as my self-hosted git server and action runner. It runs blazing fast (in my setup) and has a snappy web UI, which helps.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quartz&lt;/strong&gt;… don&amp;rsquo;t know yet, we will see. Seems like it&amp;rsquo;s made for generating websites out of folder-based content structures like &lt;em&gt;Obsidian&lt;/em&gt;&amp;rsquo;s, and comes with supporting plugins to make life easier.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="workflows"&gt;Workflows
&lt;/h2&gt;&lt;p&gt;The last part of this piece, before I jump into proving my thesis right, is how it all actually comes together — from writing a piece of content, through publishing it, to reading it on this website. The best way for me to explain is with a flowchart. So, here it is:&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TD
 A["Write Content"]:::write --&gt; B["Save Changes"]:::action

 subgraph pipeline ["Automatic Pipeline"]
 direction TB
 C{"Were any\ncontent files\nchanged?"}:::decision
 C --&gt;|No| D["Nothing to do"]:::skip
 C --&gt;|Yes| E["What changed?"]:::action

 E --&gt; F["New file"]:::change
 E --&gt; G["Edited file"]:::change
 E --&gt; H["Removed file"]:::change
 E --&gt; I["Moved / renamed file"]:::change

 F --&gt; J{"Marked as\npublished?"}:::decision
 G --&gt; K{"Marked as\npublished?"}:::decision
 I --&gt; L{"Marked as\npublished?"}:::decision

 J --&gt;|Yes| M["Add to website"]:::publish
 J --&gt;|No| N["Skip, it's a draft"]:::skip
 K --&gt;|Yes| O["Update on website"]:::publish
 K --&gt;|No| P["Remove from website"]:::remove
 H --&gt; Q["Remove from website"]:::remove
 L --&gt;|Yes| R["Remove old location\nAdd new location"]:::publish
 L --&gt;|No| S["Remove old location"]:::remove

 M --&gt; T["Get current\nwebsite version"]:::action
 N --&gt; T
 O --&gt; T
 P --&gt; T
 Q --&gt; T
 R --&gt; T
 S --&gt; T

 T --&gt; U["Rebuild website\nwith all changes applied"]:::build
 U --&gt; V["Save new\nwebsite version"]:::action
 end

 B --&gt; C
 V --&gt; W["Publish website"]:::deploy
 W --&gt; X["Live at\nidan.goldman.work"]:::live

 classDef write fill:#4a9eff,stroke:#2d7cd6,color:#fff
 classDef action fill:#6c757d,stroke:#545b62,color:#fff
 classDef decision fill:#ffc107,stroke:#d4a106,color:#333
 classDef skip fill:#dc3545,stroke:#b02a37,color:#fff
 classDef change fill:#6c757d,stroke:#545b62,color:#fff
 classDef publish fill:#198754,stroke:#13653f,color:#fff
 classDef remove fill:#dc3545,stroke:#b02a37,color:#fff
 classDef build fill:#6f42c1,stroke:#5a32a3,color:#fff
 classDef deploy fill:#198754,stroke:#13653f,color:#fff
 classDef live fill:#0dcaf0,stroke:#0aa2c0,color:#333&lt;/pre&gt;&lt;p&gt;Yeah, I know it&amp;rsquo;s a bit much for a personal website, and might change later.&lt;/p&gt;
&lt;h2 id="the-end"&gt;The End
&lt;/h2&gt;&lt;p&gt;…and that&amp;rsquo;s it, folks — thank you for reading! See you next time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; If you are reading this, the website is already up and this content piece is already outdated on how the actual website got built. Still the same idea — just different tools and workflows.&lt;/p&gt;</description></item></channel></rss>