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
eleventyConfig.addCollection("aboutContent", (api) =>
api.getFilteredByGlob("src/about.md")
api.getFilteredByGlob("src/content/about.md")
);
// Collection: contact window content
eleventyConfig.addCollection("contactContent", (api) =>
api.getFilteredByGlob("src/contact.md")
api.getFilteredByGlob("src/content/contact.md")
);
// Collection: projects, sorted alphabetically by title

1
.gitignore vendored
View file

@ -2,3 +2,4 @@ deploy.sh
node_modules/
_site/
.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 () {
var listing = document.getElementById('blog-listing');
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');
"use strict";
// 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';
});
function syncWindow(container) {
container.scrollTop = 0;
var win = container.closest(".window");
if (win && win._syncMore) win._syncMore();
}
function openSubPage(url, container, backUrl) {
WM.loadFragment(url, container, function () {
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.querySelectorAll('.blog-open-post').forEach(function (link) {
link.addEventListener('click', function (e) {
document.addEventListener("click", function (e) {
// Open a blog post
var postLink = e.target.closest(".blog-open-post");
if (postLink) {
e.preventDefault();
listing.classList.add('hidden');
panels.forEach(function (p) { p.classList.add('hidden'); });
var panel = document.getElementById('blog-post-' + link.dataset.postIdx);
if (panel) {
panel.classList.remove('hidden');
content.scrollTop = 0;
var win = content.closest('.window');
if (win && win._syncMore) win._syncMore();
}
});
});
var container = postLink.closest(".window-content");
openSubPage(postLink.dataset.postUrl, container, "/fragments/blog/");
return;
}
// Open a project
var projLink = e.target.closest(".project-open-item");
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";
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 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;
/* Init */
@ -90,7 +113,7 @@ const WM = (() => {
buildChrome(win);
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)
const bar = win.querySelector(".window-titlebar");
@ -156,6 +179,13 @@ const WM = (() => {
s.el.classList.remove("hidden");
s.hidden = false;
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(() => {
clampToArea(s.el);
if (s.el._syncMore) s.el._syncMore();
@ -272,5 +302,5 @@ const WM = (() => {
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"
date: 2026-03-30
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
@ -15,4 +17,4 @@ Reach out if you want to chat about exploit dev, vulnerability research, or retr
- Anything \*NIX. Practically, mostly Linux. Ask me about old UNIX or BSD.
- Systems programming, reverse engineering, exploitation
- Network services and architecture
- Rather familiar with Windows internals as well
- Rather familiar with Windows internals as well

View file

@ -1,5 +1,7 @@
---
permalink: false
layout: fragment.njk
permalink: /fragments/contact/
boringUrl: /boring/contact/
---
## 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>
{# ════════════════════════════════════════════════ #}
{# ABOUT WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden"
id="win-about"
data-wid="win-about"
data-title="$whoami"
data-src="/fragments/about/"
style="top:50px; left:120px; width:540px;">
<div class="window-content">
{{ collections.aboutContent[0].templateContent | safe }}
<p><a href="/boring/about/">→ plaintext version</a></p>
</div>
<div class="window-content"></div>
</div>
{# ════════════════════════════════════════════════ #}
{# BLOG WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden"
id="win-blog"
data-wid="win-blog"
data-title="blog/"
data-src="/fragments/blog/"
style="top:60px; left:400px; width:500px; height:460px;">
<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 class="window-content" id="blog-window-content"></div>
</div>
{# ════════════════════════════════════════════════ #}
{# PROJECTS WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden"
id="win-projects"
data-wid="win-projects"
data-title="projects/"
data-src="/fragments/projects/"
style="top:140px; left:120px; width:560px; height:380px;">
<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 class="window-content" id="projects-window-content"></div>
</div>
{# ════════════════════════════════════════════════ #}
{# CONTACT WINDOW #}
{# ════════════════════════════════════════════════ #}
<div class="window hidden"
id="win-contact"
data-wid="win-contact"
data-title="contact"
data-src="/fragments/contact/"
style="top:20px; left:240px; width:480px;">
<div class="window-content">
{{ collections.contactContent[0].templateContent | safe }}
<p style="margin-top:14px"><a href="/boring/contact/">→ plaintext version</a></p>
</div>
<div class="window-content"></div>
</div>
<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"
tags:
- x86

View file

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