adding sitemap style
All checks were successful
Build Org Website / build (push) Successful in 54s

This commit is contained in:
2026-05-08 12:28:07 +01:00
parent b8b3871650
commit dbc897370c
3 changed files with 119 additions and 13 deletions

0
assets/images/blogs/2026-05-08-time-to-100m-pic.webp Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -704,7 +704,7 @@ APP_HTML = r"""<!doctype html>
button { border: 1px solid var(--line); background: #fff; color: var(--ink); min-height: 38px; padding: 0 12px; border-radius: 6px; cursor: pointer; }
button.primary { background: var(--accent); color: white; border-color: var(--accent); }
button.icon { min-width: 38px; padding: 0 10px; font-weight: 700; }
.app { min-height: 100vh; display: grid; grid-template-columns: minmax(260px, 360px) 1fr; }
.app { min-height: 100vh; display: grid; grid-template-columns: minmax(300px, 420px) 1fr; }
aside { border-right: 1px solid var(--line); background: #eee8dc; padding: 18px; overflow: auto; max-height: 100vh; }
main { padding: 20px clamp(18px, 3vw, 42px); overflow: auto; max-height: 100vh; }
.topbar { display: flex; align-items: center; gap: 10px; justify-content: space-between; margin-bottom: 16px; }
@@ -716,10 +716,23 @@ APP_HTML = r"""<!doctype html>
.status.fail { border-color: #a12a2a; }
.quick-link { display: inline-block; color: var(--accent); font-size: 13px; margin: -6px 0 14px; }
.filters { display: grid; gap: 8px; margin-bottom: 14px; }
.page-list { display: grid; gap: 7px; }
.page-item { width: 100%; text-align: left; min-height: auto; padding: 9px 10px; background: var(--panel); }
.page-list { display: grid; gap: 3px; }
.tree-dir { margin: 1px 0; }
.tree-dir summary { list-style: none; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 8px; align-items: center; min-height: 34px; padding: 6px 8px; border-radius: 6px; cursor: pointer; color: var(--ink); }
.tree-dir summary::-webkit-details-marker { display: none; }
.tree-dir summary:hover, .page-item:hover { background: rgba(255, 253, 248, 0.78); }
.tree-dir summary::before { content: ">"; display: inline-block; width: 14px; color: var(--muted); }
.tree-dir[open] > summary::before { content: "v"; }
.tree-label { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.tree-label strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.tree-label span { color: var(--muted); font-size: 12px; white-space: nowrap; }
.tree-children { display: grid; gap: 2px; margin-left: 15px; padding-left: 10px; border-left: 1px solid var(--line); }
.tree-add { min-height: 28px; padding: 0 8px; font-size: 12px; color: var(--accent); background: transparent; }
.page-item { width: 100%; text-align: left; min-height: auto; padding: 8px 10px; background: transparent; }
.page-item.active { border-color: var(--accent); background: var(--panel); }
.page-item strong { display: block; font-size: 14px; margin-bottom: 2px; overflow-wrap: anywhere; }
.page-item span { display: block; color: var(--muted); font-size: 12px; overflow-wrap: anywhere; }
.page-item .filename { color: var(--ink); }
form { display: grid; gap: 14px; }
.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.toolbar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; border: 1px solid var(--line); background: var(--panel); border-radius: 6px; padding: 7px; }
@@ -924,21 +937,113 @@ APP_HTML = r"""<!doctype html>
const matches = state.pages
.filter((page) => (!type || page.pageType === type))
.filter((page) => `${page.title} ${page.path} ${page.tags.join(" ")}`.toLowerCase().includes(query))
.slice(0, 120);
.sort((a, b) => a.path.localeCompare(b.path));
if (!matches.length) {
pagesBox.innerHTML = `<div class="queue-item"><span>No files matched.</span></div>`;
renderStatus();
return;
}
matches.forEach((page) => {
const btn = document.createElement("button");
btn.type = "button";
btn.className = "page-item";
btn.innerHTML = `<strong>${html(page.title)}</strong><span>${html(page.path)}</span><span class="tags">${page.tags.map((tag) => `<span class="tag">${html(tag)}</span>`).join("")}</span>`;
btn.onclick = () => loadPage(page.path);
pagesBox.appendChild(btn);
});
const tree = buildPageTree(matches);
renderTree(tree, pagesBox, query !== "");
renderStatus();
}
function buildPageTree(pages) {
const root = { dirs: new Map(), pages: [], path: "" };
pages.forEach((page) => {
const parts = page.path.split("/");
const filename = parts.pop();
let node = root;
let dirPath = "";
parts.forEach((part) => {
dirPath = dirPath ? `${dirPath}/${part}` : part;
if (!node.dirs.has(part)) node.dirs.set(part, { dirs: new Map(), pages: [], path: dirPath });
node = node.dirs.get(part);
});
node.pages.push({ ...page, filename });
});
return root;
}
function renderTree(node, container, expandAll = false) {
[...node.dirs.entries()]
.sort(([a], [b]) => a.localeCompare(b))
.forEach(([name, child]) => container.appendChild(renderDirectory(name, child, expandAll)));
node.pages
.sort((a, b) => a.filename.localeCompare(b.filename))
.forEach((page) => container.appendChild(renderPageButton(page)));
}
function renderDirectory(name, node, expandAll) {
const details = document.createElement("details");
details.className = "tree-dir";
details.open = expandAll || node.path.split("/").length <= 2 || containsCurrentPath(node);
const summary = document.createElement("summary");
const label = document.createElement("span");
label.className = "tree-label";
label.innerHTML = `<strong>${html(name)}</strong><span>${countPages(node)} files</span>`;
const add = document.createElement("button");
add.type = "button";
add.className = "tree-add";
add.textContent = "New";
add.title = `New file in ${node.path}`;
add.onclick = (event) => {
event.preventDefault();
event.stopPropagation();
newPageInDirectory(node.path);
};
summary.append(label, add);
const children = document.createElement("div");
children.className = "tree-children";
renderTree(node, children, expandAll);
details.append(summary, children);
return details;
}
function renderPageButton(page) {
const btn = document.createElement("button");
btn.type = "button";
btn.className = `page-item${page.path === state.currentPath ? " active" : ""}`;
btn.innerHTML = `<strong>${html(page.title)}</strong><span class="filename">${html(page.filename || page.path)}</span><span>${html(page.path)}</span>${page.tags.length ? `<span class="tags">${page.tags.map((tag) => `<span class="tag">${html(tag)}</span>`).join("")}</span>` : ""}`;
btn.onclick = () => loadPage(page.path);
return btn;
}
function countPages(node) {
let count = node.pages.length;
node.dirs.forEach((child) => { count += countPages(child); });
return count;
}
function containsCurrentPath(node) {
return Boolean(state.currentPath && (state.currentPath.startsWith(`${node.path}/`) || node.pages.some((page) => page.path === state.currentPath)));
}
function newPageInDirectory(dirPath) {
const pageType = pageTypeForDirectory(dirPath);
setForm({ pageType, date: currentOrgDate(), comments: true });
editor.section.value = pageType === "post" ? postSectionForDirectory(dirPath) : "";
editor.targetPath.value = `${dirPath}/`;
state.pathManual = true;
updateEditorMode();
saveMessage.textContent = `New file will be created in ${dirPath}.`;
editor.title.focus();
}
function pageTypeForDirectory(dirPath) {
if (dirPath === "lima" || dirPath.startsWith("lima/")) return "lima";
if (dirPath === "posts" || dirPath.startsWith("posts/")) return "post";
if (dirPath === "blogs" || dirPath.startsWith("blogs/")) return "blog";
return "page";
}
function postSectionForDirectory(dirPath) {
if (!dirPath.startsWith("posts/")) return "";
return dirPath.slice("posts/".length);
}
function html(value) {
return String(value).replace(/[&<>"']/g, (char) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[char]));
}
@@ -1034,6 +1139,7 @@ APP_HTML = r"""<!doctype html>
updateEditorMode();
updateSuggestedPath();
updateMarkdownPreview();
if (state.pages.length) renderPages();
saveMessage.textContent = "";
}

View File

@@ -4,7 +4,7 @@
See the categories: @@html:<a href="../home/categories.html">Categories</a>@@
* Posts:
- [[file:career/career-list.org][Career List]] @@html:<span class="post-date">08-05-2026 12:09</span>@@
- [[file:career/career-list.org][Career List]] @@html:<span class="post-date">08-05-2026 12:27</span>@@
- [[file:posts-list.sync-conflict-20260417-233432-VT6366A.org][Posts List]] @@html:<span class="post-date">14-04-2026 16:36</span>@@
- [[file:career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] @@html:<span class="post-date">11-03-2026 17:18</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@
- [[file:career/javascript.org][Understands the Javascript language]] @@html:<span class="post-date">11-03-2026 16:52</span>@@ @@html:<a href="/tags/learning.html"><span class="post-tag">learning</span></a>@@ @@html:<a href="/tags/notes.html"><span class="post-tag">notes</span></a>@@