处理器
扩展 Lume 自定义处理器的指南
处理器是一个函数,用于在页面渲染之后转换页面内容。让我们看一个使用处理器来压缩 HTML 页面的例子:
function minifyHTML(pages) {
for (const page of pages) {
page.content = minify(page.content);
}
}
如果你想使用这个处理器来构建你的站点,你可以在 _config.js
文件中注册它:
site.process([".html"], minifyHTML);
现在,所有的 HTML 页面都会被压缩。
页面对象
正如你在前面的例子中看到的,该函数接收一个页面对象数组。页面对象不仅包含页面内容,还包含更多数据:
function process(pages) {
for (const page of pages) {
page.content; // 页面的内容
page.document; // 解析后的 HTML 代码,用于使用 DOM API
page.src; // 关于此页面的源文件的信息
page.data; // 此页面的所有可用数据(前端 matter 与 _data 合并)
}
}
例如,假设你只想压缩 minify
值为 true
的页面:
site.process([".html"], (pages) => {
for (const page of pages) {
if (page.data.minify) {
page.content = minify(page.content);
}
}
});
使用 DOM API
你可以使用 DOM API(由 deno-dom 驱动),使用诸如 querySelector
、setAttribute
等方法来修改 HTML 代码。例如,让我们创建一个处理器来自动为所有图像添加 alt
属性:
site.process([".html"], (pages) => {
for (const page of pages) {
for (const img of page.document.querySelectorAll("img")) {
if (!img.hasAttribute("alt")) {
img.setAttribute("alt", "This is a random alt");
}
}
}
});
处理 assets
对于非 HTML 页面(例如 CSS 或 JavaScript 文件),你可以使用处理器来编译 CSS,压缩 JavaScript 代码或压缩图像。
site.process([".js"], function (pages) {
for (const page of pages) {
page.content = myBundler(page.content);
// 将 .min 追加到文件名
// 以便它将保存为 example.min.js
page.data.url = page.data.url.replace(/\.js$/, ".min.js");
}
});
Note
确保你想要处理的文件扩展名已预先加载。 有关如何注册新加载器的更多信息,请参阅 如何加载 assets。
预处理器
如果你需要在渲染之前执行一个函数(例如,配置自定义模板引擎或向某些页面添加额外数据),你可以使用预处理器。预处理器的工作方式类似于处理器,但它们在渲染之前执行。
让我们创建一个预处理器来包含一个带有源文件名的变量:
site.preprocess([".html"], (pages) => {
for (const page of pages) {
page.data.filename = page.src.path + page.src.ext;
}
});
动态创建页面
处理器可以生成额外的页面(或删除它们)。(预)处理器的第二个参数包含一个包含站点所有页面的数组。你可以修改此数组以动态添加或删除页面。例如:
import { Page } from "lume/core/file.ts";
site.process([".css"], (filteredPages, allPages) => {
for (const page of filteredPages) {
// 压缩 css 内容
const { code, map } = myCssMinifier(page.content);
// 更新页面内容
page.content = code;
// 创建一个带有 sourcemap 的新页面
const pageMap = Page.create({
url: page.data.url + ".map",
content: map,
});
// 将页面添加到站点
allPages.push(pageMap);
}
});
动态删除页面
要动态删除页面,你必须从第二个参数的页面数组中删除它:
// 删除所有 language = "en" 的 html 页面
site.process([".html"], (filteredPages, allPages) => {
for (const page of filteredPages) {
if (page.data.lang === "en") {
// 在 allPages 数组中搜索页面并删除它
allPages.splice(allPages.indexOf(page), 1);
}
}
});
处理器和预处理器的工作原理
处理器和预处理器都与文件扩展名(.html
、.js
等)相关联。为了确定页面是否必须使用已注册的处理器或预处理器,Lume 搜索输入文件(如 .md
或 .vto
)或输出文件(如 .html
或 .css
)的扩展名。
另一个有趣的事情是它们按照定义的顺序执行。这允许将不同的处理器链接到相同的文件扩展名。例如:用于 .css
扩展名的两个处理器,一个用于编译代码,另一个用于压缩。
全局(预)处理器
如果你想为所有页面运行一个处理器或预处理器,请在第一个参数中使用 *
:
site.process("*", processAllPages);