我使用特殊的后处理构建步骤遍历所有生成的 HTML文件并将其中包含的链接转换为其相关变体。
此方法适用于任何模板语言(例如nunjucks),因为它不会修改模板,而是修改最终的可交付成果。
它不适用于 Wintersmith 的实时预览服务器。
我使用Cheerio HTML 解析器。
核心功能是这样的:
var cheerio = require("cheerio");
var fs = require("fs");
$ = cheerio.load(fs.readFileSync(expandFileName("build/test.html"), 'utf-8'));
// change all links in the cheerio document from absolute to relative.
// document's absolute location is supposed to be /test/test.html
rebaseDocument("/test/test.html", $);
fs.writeFileSync(expandFileName("build/test.new.html"), $.html());
return;
function rebaseDocument(documentLocation, $) {
debugLog(documentLocation);
rebaseElements(documentLocation, $, "a", "href");
rebaseElements(documentLocation, $, "link", "href");
rebaseElements(documentLocation, $, "script", "src");
rebaseElements(documentLocation, $, "img", "src");
}
function rebaseElements(documentLocation, $, tagName, attributeName) {
$(tagName).each(function() { $(this).attr(attributeName, rebaseLink(documentLocation, $(this).attr(attributeName))); });
}
function rebaseLink(documentLocation, link) {
if (link == null)
return link;
// check if link denotes absolute hyperlink. If so, nothing to do here
// absolute hyperlink is either scheme:// or protocol relative url //
if ((new RegExp('^([a-z]+://|//)')).test(link))
return link;
// check another special forms of absolute hyperlinks
if (link.substring(0, 7) == "mailto:")
return link;
// if link is already relative, nothing to do
if (link.charAt(0) != '/')
return link;
if (documentLocation.charAt(0) != '/')
documentLocation = '/' + documentLocation;
var path = require("path");
var documentName = path.basename(documentLocation);
var from = path.dirname(documentLocation);
var newLink = path.relative(from, link).replaceAll("\\", "/");
// reduce 'document.htm#anchor' to '#anchor'
if (newLink.slice(0, documentName.length + 1) == documentName + '#')
newLink = newLink.slice(documentName.length);
return newLink;
}