主题半闭源
前些天写小结的时候在github的feed页看到我写博文的仓库又多了一个star. 点进用户主页, 发现这位网友也有自己的blog, 本着回访的目的点了进去, 好家伙, 直接套用了我的主题, 当然我并非斥责抵制这一行为, 但这位网友似乎直接用ai生成了readme.md, 其中声明了这个主题是heavily inspired by a web, 这个web页是一个以极简高度出名的blog template, 并不是我的主题, 也不是我二次开发前的miniblog.
这件事中, 令我生气的地方在于这个网友似乎不屑于修改ai定义的readme, 抑或是他觉得这无关紧要, 在他博文的字里行间, 我闻到了一种刻意装出来地看破一切地清高, 然而他却把网络上的自留地完全交给了ai.
鉴于这种情况, 以及在最近添加了未完成博文的的过滤, 我已不能将我的所有博文放在public的仓库中, 于是决定将GitHub repo修改为private, 但主题依然欢迎大家在遵循 CC BY-NC-SA 4.0的前提下使用, 本文发布时, 我已调整了主题页面的详情.
拼图逻辑的实现
时至今日亲手用上cursor才意识到之前用的别的工具有多么笨拙, 下面是拼图逻辑的实现(by cursor): 实现思路本质上是 DOM 重写:
- 识别候选块:遍历文章 article 的直接子元素,用 isImageContainer() 判断它是不是“图片容器”(p/figure/img),且排除 .db-card。
- 找连续序列:把连续的图片容器聚成序列 sequences;只处理长度 ≥2≥2 的序列。
- 扁平化图片列表:把序列里的容器全部展开成 imgs(按 DOM 顺序)。
- 分组规则:用队列把图片按 每组最多 3 张切块;尾巴只接受 2 张(queue.length === 2 才入组)。
- 生成拼图 DOM:为每个 group 创建一个 .image-mosaic(grid 容器),每张图包一层 .image-mosaic-item,并用 CSS 变量 —mosaic-cols 控制列数(2 张=2列,3 张=3列)。
- 替换原内容:把拼图 fragment 插到序列第一个容器前,然后移除旧的 p/figure/img 容器。
此外, 我之前写了一个组件用来显示图片的文字信息, 为了在拼图上能有更好的效果, 我又让cursor生成了一个动画:
(() => { if (window.__imgAltOverlayInstalled) return; window.__imgAltOverlayInstalled = true;
const trimAlt = (s) => (typeof s === "string" ? s.trim() : "");
const install = (root = document) => { // 仅拼图图片:在 item 上挂 data-alt(不改 DOM 结构) const items = root.querySelectorAll("article[data-pagefind-body] .image-mosaic-item"); items.forEach((item) => { const img = item.querySelector("img"); if (!img) return; const alt = trimAlt(img.getAttribute("alt")); if (!alt) { item.removeAttribute("data-alt"); return; } item.dataset.alt = alt; }); };
// 注意:文章页有“图片拼图”脚本会依赖原始 DOM 结构(p/figure 里直接是 img)。 // 这里稍微延后执行,避免先 wrap 破坏拼图的容器识别逻辑。 const run = () => { setTimeout(() => install(document), 160); }; if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", run); } else { run(); } document.addEventListener("astro:page-load", run); document.addEventListener("astro:after-swap", run); })();效果是这样的:
