HUGE rework of the site to not generate static content into the main

page. Page now loads windows and blog posts at runtime, reducing page
size dramatically.
This commit is contained in:
lordtet 2026-03-30 20:30:39 -04:00
parent 4ac4bbb2f7
commit ddc223846e
17 changed files with 211 additions and 239 deletions

View file

@ -8,12 +8,12 @@ module.exports = function (eleventyConfig) {
// Collection: about window content // Collection: about window content
eleventyConfig.addCollection("aboutContent", (api) => eleventyConfig.addCollection("aboutContent", (api) =>
api.getFilteredByGlob("src/about.md") api.getFilteredByGlob("src/content/about.md")
); );
// Collection: contact window content // Collection: contact window content
eleventyConfig.addCollection("contactContent", (api) => eleventyConfig.addCollection("contactContent", (api) =>
api.getFilteredByGlob("src/contact.md") api.getFilteredByGlob("src/content/contact.md")
); );
// Collection: projects, sorted alphabetically by title // Collection: projects, sorted alphabetically by title

1
.gitignore vendored
View file

@ -2,3 +2,4 @@ deploy.sh
node_modules/ node_modules/
_site/ _site/
.claude .claude
CLAUDE.md

View file

@ -0,0 +1,14 @@
{% if title %}
<h2>{{ title }}</h2>
{% if date or tags %}
<p class="post-meta">
{%- if date %}{{ date | readableDate }}{% if tags %} &middot; {% endif %}{% endif -%}
{%- if tags %}{{ tags | join(', ') }}{% endif %}
</p>
<hr class="post-rule">
{% endif %}
{% endif %}
{{ content | safe }}
{%- if boringUrl %}
<p><a href="{{ boringUrl }}">&rarr; plaintext version</a></p>
{% endif %}

View file

@ -1,98 +1,80 @@
(function () { (function () {
var listing = document.getElementById('blog-listing'); "use strict";
var content = document.getElementById('blog-window-content');
var panels = document.querySelectorAll('.blog-post-panel');
var tagBtns = document.querySelectorAll('.blog-tag');
var items = document.querySelectorAll('.post-list-item');
// Tag filtering function syncWindow(container) {
tagBtns.forEach(function (btn) { container.scrollTop = 0;
btn.addEventListener('click', function () { var win = container.closest(".window");
tagBtns.forEach(function (b) { b.classList.remove('active'); }); if (win && win._syncMore) win._syncMore();
btn.classList.add('active'); }
var tag = btn.dataset.tag;
items.forEach(function (li) { function openSubPage(url, container, backUrl) {
var tags = li.dataset.tags ? li.dataset.tags.split(' ') : []; WM.loadFragment(url, container, function () {
li.style.display = (tag === '*' || tags.indexOf(tag) !== -1) ? '' : 'none'; var back = document.createElement("button");
}); back.className = "blog-back";
back.dataset.backUrl = backUrl;
back.textContent = "\u2190 back";
container.insertBefore(back, container.firstChild);
syncWindow(container);
}); });
}); }
// Open a post document.addEventListener("click", function (e) {
document.querySelectorAll('.blog-open-post').forEach(function (link) {
link.addEventListener('click', function (e) { // Open a blog post
var postLink = e.target.closest(".blog-open-post");
if (postLink) {
e.preventDefault(); e.preventDefault();
listing.classList.add('hidden'); var container = postLink.closest(".window-content");
panels.forEach(function (p) { p.classList.add('hidden'); }); openSubPage(postLink.dataset.postUrl, container, "/fragments/blog/");
var panel = document.getElementById('blog-post-' + link.dataset.postIdx); return;
if (panel) { }
panel.classList.remove('hidden');
content.scrollTop = 0; // Open a project
var win = content.closest('.window'); var projLink = e.target.closest(".project-open-item");
if (win && win._syncMore) win._syncMore(); if (projLink) {
} e.preventDefault();
}); var container = projLink.closest(".window-content");
}); openSubPage(projLink.dataset.projectUrl, container, "/fragments/projects/");
return;
}
// Back button (shared by blog and projects)
var backBtn = e.target.closest(".blog-back");
if (backBtn) {
var container = backBtn.closest(".window-content");
WM.loadFragment(backBtn.dataset.backUrl, container, function () {
syncWindow(container);
});
return;
}
// Blog tag filtering
var blogTag = e.target.closest(".blog-tag");
if (blogTag) {
var content = blogTag.closest(".window-content");
content.querySelectorAll(".blog-tag").forEach(function (b) { b.classList.remove("active"); });
blogTag.classList.add("active");
var tag = blogTag.dataset.tag;
content.querySelectorAll(".post-list-item").forEach(function (li) {
var tags = li.dataset.tags ? li.dataset.tags.split(" ") : [];
li.style.display = (tag === "*" || tags.indexOf(tag) !== -1) ? "" : "none";
});
return;
}
// Project tag filtering
var projTag = e.target.closest(".project-tag");
if (projTag) {
var content = projTag.closest(".window-content");
content.querySelectorAll(".project-tag").forEach(function (b) { b.classList.remove("active"); });
projTag.classList.add("active");
var tag = projTag.dataset.tag;
content.querySelectorAll(".project-list-item").forEach(function (li) {
var tags = li.dataset.tags ? li.dataset.tags.split(" ") : [];
li.style.display = (tag === "*" || tags.indexOf(tag) !== -1) ? "" : "none";
});
return;
}
// Back to listing
document.querySelectorAll('.blog-back').forEach(function (btn) {
btn.addEventListener('click', function () {
panels.forEach(function (p) { p.classList.add('hidden'); });
listing.classList.remove('hidden');
content.scrollTop = 0;
var win = content.closest('.window');
if (win && win._syncMore) win._syncMore();
});
});
}());
// Projects panel
(function () {
var listing = document.getElementById('projects-listing');
var content = document.getElementById('projects-window-content');
var panels = document.querySelectorAll('.project-detail-panel');
var tagBtns = document.querySelectorAll('.project-tag');
var items = document.querySelectorAll('.project-list-item');
if (!listing) return;
// Tag filtering
tagBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
tagBtns.forEach(function (b) { b.classList.remove('active'); });
btn.classList.add('active');
var tag = btn.dataset.tag;
items.forEach(function (li) {
var tags = li.dataset.tags ? li.dataset.tags.split(' ') : [];
li.style.display = (tag === '*' || tags.indexOf(tag) !== -1) ? '' : 'none';
});
});
});
// Open a project
document.querySelectorAll('.project-open-item').forEach(function (link) {
link.addEventListener('click', function (e) {
e.preventDefault();
listing.classList.add('hidden');
panels.forEach(function (p) { p.classList.add('hidden'); });
var panel = document.getElementById('project-item-' + link.dataset.projectIdx);
if (panel) {
panel.classList.remove('hidden');
content.scrollTop = 0;
var win = content.closest('.window');
if (win && win._syncMore) win._syncMore();
}
})
});
// Back to listing
document.querySelectorAll('.project-back').forEach(function (btn) {
btn.addEventListener('click', function () {
panels.forEach(function (p) { p.classList.add('hidden'); });
listing.classList.remove('hidden');
content.scrollTop = 0;
var win = content.closest('.window');
if (win && win._syncMore) win._syncMore();
});
}); });
}()); }());

View file

@ -6,10 +6,33 @@ const WM = (() => {
"use strict"; "use strict";
let topZ = 100; let topZ = 100;
const state = new Map(); // wid → { el, hidden, maximized, savedStyle } const state = new Map(); // wid → { el, hidden, maximized, savedStyle, contentLoaded }
let drag = null; let drag = null;
let resize = null; let resize = null;
/* Fragment loader */
const fragmentCache = {};
function loadFragment(url, container, onDone) {
if (fragmentCache[url]) {
container.innerHTML = fragmentCache[url];
if (onDone) onDone();
return;
}
container.innerHTML = "<p style=\"color:var(--p-dim);\">Loading\u2026</p>";
fetch(url)
.then(r => r.ok ? r.text() : Promise.reject(r.status))
.then(html => {
fragmentCache[url] = html;
container.innerHTML = html;
if (onDone) onDone();
})
.catch(() => {
container.innerHTML = "<p style=\"color:var(--p-dim);\">Failed to load.</p>";
});
}
const mobile = () => window.matchMedia("(pointer: coarse)").matches; const mobile = () => window.matchMedia("(pointer: coarse)").matches;
/* Init */ /* Init */
@ -90,7 +113,7 @@ const WM = (() => {
buildChrome(win); buildChrome(win);
const hidden = win.classList.contains("hidden"); const hidden = win.classList.contains("hidden");
state.set(id, { el: win, hidden, maximized: false, savedStyle: null }); state.set(id, { el: win, hidden, maximized: false, savedStyle: null, contentLoaded: false });
// Draggable title bar (desktop only) // Draggable title bar (desktop only)
const bar = win.querySelector(".window-titlebar"); const bar = win.querySelector(".window-titlebar");
@ -156,6 +179,13 @@ const WM = (() => {
s.el.classList.remove("hidden"); s.el.classList.remove("hidden");
s.hidden = false; s.hidden = false;
focusEl(s.el); focusEl(s.el);
if (s.el.dataset.src && !s.contentLoaded) {
s.contentLoaded = true;
const contentEl = s.el.querySelector(".window-content");
if (contentEl) loadFragment(s.el.dataset.src, contentEl, () => {
if (s.el._syncMore) s.el._syncMore();
});
}
requestAnimationFrame(() => { requestAnimationFrame(() => {
clampToArea(s.el); clampToArea(s.el);
if (s.el._syncMore) s.el._syncMore(); if (s.el._syncMore) s.el._syncMore();
@ -272,5 +302,5 @@ const WM = (() => {
document.addEventListener("DOMContentLoaded", init); document.addEventListener("DOMContentLoaded", init);
return { show, hide, toggle, focus }; return { show, hide, toggle, focus, loadFragment };
})(); })();

View file

@ -1,5 +1,4 @@
--- ---
permalink: false
title: "Over The Wire - Behemoth retrospective" title: "Over The Wire - Behemoth retrospective"
date: 2026-03-30 date: 2026-03-30
tags: tags:

View file

@ -0,0 +1,4 @@
module.exports = {
layout: "fragment.njk",
permalink: data => `/fragments/blog/${data.page.fileSlug}/`
};

View file

@ -1,3 +0,0 @@
{
"layout": "post-plain.njk"
}

View file

@ -1,5 +1,7 @@
--- ---
permalink: false layout: fragment.njk
permalink: /fragments/about/
boringUrl: /boring/about/
--- ---
## $whoami ## $whoami

View file

@ -1,5 +1,7 @@
--- ---
permalink: false layout: fragment.njk
permalink: /fragments/contact/
boringUrl: /boring/contact/
--- ---
## Jake "**lordtet**" Holtham ## Jake "**lordtet**" Holtham

33
src/fragments/blog.njk Normal file
View file

@ -0,0 +1,33 @@
---
permalink: /fragments/blog/
eleventyExcludeFromCollections: true
---
{% set tagCounts = collections.posts | tagCounts %}
{% if tagCounts.length %}
<div class="blog-tags">
<button class="blog-tag active" data-tag="*">all <span class="tag-count">{{ collections.posts.length }}</span></button>
{% for tc in tagCounts %}
<button class="blog-tag" data-tag="{{ tc.tag }}">{{ tc.tag }} <span class="tag-count">{{ tc.count }}</span></button>
{% endfor %}
</div>
{% endif %}
{% if collections.posts.length %}
<ul class="post-list" id="blog-post-list">
{% for post in collections.posts %}
<li class="post-list-item"
data-tags="{{ post.data.tags | join(' ') if post.data.tags else '' }}">
<a href="#"
class="blog-open-post"
data-post-url="/fragments/blog/{{ post.fileSlug }}/">{{ post.data.title }}</a>
<span class="post-date">{{ post.date | readableDate }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<p style="color:var(--p-dim);">No posts yet &mdash; check back soon.</p>
{% endif %}
<p style="margin-top:14px; border-top:1px solid var(--p-dim); padding-top:10px;">
<a href="/boring/blog/">&rarr; plaintext version</a>
</p>

View file

@ -0,0 +1,32 @@
---
permalink: /fragments/projects/
eleventyExcludeFromCollections: true
---
{% set projectTagCounts = collections.projects | tagCounts %}
{% if projectTagCounts.length %}
<div class="blog-tags">
<button class="project-tag active" data-tag="*">all <span class="tag-count">{{ collections.projects.length }}</span></button>
{% for tc in projectTagCounts %}
<button class="project-tag" data-tag="{{ tc.tag }}">{{ tc.tag }} <span class="tag-count">{{ tc.count }}</span></button>
{% endfor %}
</div>
{% endif %}
{% if collections.projects.length %}
<ul class="post-list" id="projects-list">
{% for project in collections.projects %}
<li class="project-list-item"
data-tags="{{ project.data.tags | join(' ') if project.data.tags else '' }}">
<a href="#"
class="project-open-item"
data-project-url="/fragments/projects/{{ project.fileSlug }}/">{{ project.data.title }}</a>
</li>
{% endfor %}
</ul>
{% else %}
<p style="color:var(--p-dim);">No projects yet.</p>
{% endif %}
<p style="margin-top:14px; border-top:1px solid var(--p-dim); padding-top:10px;">
<a href="/boring/projects/">&rarr; plaintext version</a>
</p>

View file

@ -24,163 +24,40 @@ permalink: /
</div> </div>
</div> </div>
{# ════════════════════════════════════════════════ #}
{# ABOUT WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden" <div class="window hidden"
id="win-about" id="win-about"
data-wid="win-about" data-wid="win-about"
data-title="$whoami" data-title="$whoami"
data-src="/fragments/about/"
style="top:50px; left:120px; width:540px;"> style="top:50px; left:120px; width:540px;">
<div class="window-content"></div>
<div class="window-content">
{{ collections.aboutContent[0].templateContent | safe }}
<p><a href="/boring/about/">→ plaintext version</a></p>
</div>
</div> </div>
{# ════════════════════════════════════════════════ #}
{# BLOG WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden" <div class="window hidden"
id="win-blog" id="win-blog"
data-wid="win-blog" data-wid="win-blog"
data-title="blog/" data-title="blog/"
data-src="/fragments/blog/"
style="top:60px; left:400px; width:500px; height:460px;"> style="top:60px; left:400px; width:500px; height:460px;">
<div class="window-content" id="blog-window-content"></div>
<div class="window-content" id="blog-window-content">
{# ── Listing view ─────────────────────────── #}
<div id="blog-listing">
{# Tag filters #}
{% set tagCounts = collections.posts | tagCounts %}
{% if tagCounts.length %}
<div class="blog-tags">
<button class="blog-tag active" data-tag="*">all <span class="tag-count">{{ collections.posts.length }}</span></button>
{% for tc in tagCounts %}
<button class="blog-tag" data-tag="{{ tc.tag }}">{{ tc.tag }} <span class="tag-count">{{ tc.count }}</span></button>
{% endfor %}
</div>
{% endif %}
{# Post list #}
{% if collections.posts.length %}
<ul class="post-list" id="blog-post-list">
{% for post in collections.posts %}
<li class="post-list-item"
data-tags="{{ post.data.tags | join(' ') if post.data.tags else '' }}">
<a href="#"
class="blog-open-post"
data-post-idx="{{ loop.index0 }}">{{ post.data.title }}</a>
<span class="post-date">{{ post.date | readableDate }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<p style="color:var(--p-dim);">No posts yet — check back soon.</p>
{% endif %}
<p style="margin-top:14px; border-top:1px solid var(--p-dim); padding-top:10px;">
<a href="/boring/blog/">→ plaintext version</a>
</p>
</div>
{# ── Per-post views (built at compile time, hidden by default) ── #}
{% for post in collections.posts %}
<div class="blog-post-panel hidden" id="blog-post-{{ loop.index0 }}">
<button class="blog-back">← back</button>
<h2 style="margin-top:10px;">{{ post.data.title }}</h2>
<p class="post-meta">
{{ post.date | readableDate }}
{% if post.data.tags %}· {{ post.data.tags | join(', ') }}{% endif %}
</p>
<hr class="post-rule">
{{ post.templateContent | safe }}
</div>
{% endfor %}
</div>
</div> </div>
{# ════════════════════════════════════════════════ #}
{# PROJECTS WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden" <div class="window hidden"
id="win-projects" id="win-projects"
data-wid="win-projects" data-wid="win-projects"
data-title="projects/" data-title="projects/"
data-src="/fragments/projects/"
style="top:140px; left:120px; width:560px; height:380px;"> style="top:140px; left:120px; width:560px; height:380px;">
<div class="window-content" id="projects-window-content"></div>
<div class="window-content" id="projects-window-content">
{# ── Listing view ─────────────────────────── #}
<div id="projects-listing">
{# Tag filters #}
{% set projectTagCounts = collections.projects | tagCounts %}
{% if projectTagCounts.length %}
<div class="blog-tags">
<button class="project-tag active" data-tag="*">all <span class="tag-count">{{ collections.projects.length }}</span></button>
{% for tc in projectTagCounts %}
<button class="project-tag" data-tag="{{ tc.tag }}">{{ tc.tag }} <span class="tag-count">{{ tc.count }}</span></button>
{% endfor %}
</div>
{% endif %}
{# Project list #}
{% if collections.projects.length %}
<ul class="post-list" id="projects-list">
{% for project in collections.projects %}
<li class="project-list-item"
data-tags="{{ project.data.tags | join(' ') if project.data.tags else '' }}">
<a href="#"
class="project-open-item"
data-project-idx="{{ loop.index0 }}">{{ project.data.title }}</a>
</li>
{% endfor %}
</ul>
{% else %}
<p style="color:var(--p-dim);">No projects yet.</p>
{% endif %}
<p style="margin-top:14px; border-top:1px solid var(--p-dim); padding-top:10px;">
<a href="/boring/projects/">→ plaintext version</a>
</p>
</div>
{# ── Per-project detail panels (built at compile time, hidden by default) ── #}
{% for project in collections.projects %}
<div class="project-detail-panel hidden" id="project-item-{{ loop.index0 }}">
<button class="project-back">← back</button>
<h2 style="margin-top:10px;">{{ project.data.title }}</h2>
{% if project.data.tags %}
<p class="post-meta">{{ project.data.tags | join(' · ') }}</p>
{% endif %}
<hr class="post-rule">
{{ project.templateContent | safe }}
</div>
{% endfor %}
</div>
</div> </div>
{# ════════════════════════════════════════════════ #}
{# CONTACT WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden" <div class="window hidden"
id="win-contact" id="win-contact"
data-wid="win-contact" data-wid="win-contact"
data-title="contact" data-title="contact"
data-src="/fragments/contact/"
style="top:20px; left:240px; width:480px;"> style="top:20px; left:240px; width:480px;">
<div class="window-content"></div>
<div class="window-content">
{{ collections.contactContent[0].templateContent | safe }}
<p style="margin-top:14px"><a href="/boring/contact/">→ plaintext version</a></p>
</div>
</div> </div>
<script src="/assets/js/blog.js"></script> <script src="/assets/js/blog.js"></script>

View file

@ -0,0 +1,4 @@
module.exports = {
layout: "fragment.njk",
permalink: data => `/fragments/projects/${data.page.fileSlug}/`
};

View file

@ -1,3 +0,0 @@
{
"permalink": false
}

View file

@ -1,5 +1,4 @@
--- ---
permalink: false
title: "Test Project 1" title: "Test Project 1"
tags: tags:
- x86 - x86

View file

@ -1,5 +1,4 @@
--- ---
permalink: false
title: "Test Project 2" title: "Test Project 2"
tags: tags:
- arm - arm