Files
firefrost-website/node_modules/@11ty/eleventy/src/TemplatePermalink.js
2026-04-02 18:39:00 -05:00

196 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import path from "node:path";
import { TemplatePath, isPlainObject } from "@11ty/eleventy-utils";
class TemplatePermalink {
// `link` with template syntax should have already been rendered in Template.js
constructor(link, extraSubdir) {
let isLinkAnObject = isPlainObject(link);
this._isRendered = true;
this._writeToFileSystem = true;
let buildLink;
if (isLinkAnObject) {
if ("build" in link) {
buildLink = link.build;
}
// find the first string key
for (let key in link) {
if (typeof key !== "string") {
continue;
}
break;
}
} else {
buildLink = link;
}
// permalink: false and permalink: build: false
if (typeof buildLink === "boolean") {
if (buildLink === false) {
this._writeToFileSystem = false;
} else {
throw new Error(
`\`permalink: ${
isLinkAnObject ? "build: " : ""
}true\` is not a supported feature in Eleventy. Did you mean \`permalink: ${
isLinkAnObject ? "build: " : ""
}false\`?`,
);
}
} else if (buildLink) {
if (typeof buildLink !== "string") {
let stringToString = "toString" in buildLink ? `:\n\n${buildLink.toString()}` : "";
throw new Error(
"Expected permalink value to be a string. Received `" +
typeof buildLink +
"`" +
stringToString,
);
}
this.buildLink = buildLink;
}
if (isLinkAnObject) {
// default if permalink is an Object but does not have a `build` prop
if (!("build" in link)) {
this._writeToFileSystem = false;
this._isRendered = false;
}
}
this.extraPaginationSubdir = extraSubdir || "";
}
setUrlTransforms(transforms) {
this._urlTransforms = transforms;
}
get urlTransforms() {
return this._urlTransforms || [];
}
_addDefaultLinkFilename(link) {
return link + (link.slice(-1) === "/" ? "index.html" : "");
}
toOutputPath() {
if (!this.buildLink) {
// empty or false
return false;
}
let cleanLink = this._addDefaultLinkFilename(this.buildLink);
let parsed = path.parse(cleanLink);
return TemplatePath.join(parsed.dir, this.extraPaginationSubdir, parsed.base);
}
// Used in url transforms feature
static getUrlStem(original) {
let subject = original;
if (original.endsWith(".html")) {
subject = original.slice(0, -1 * ".html".length);
}
return TemplatePermalink.normalizePathToUrl(subject);
}
static normalizePathToUrl(original) {
let compare = original || "";
let needleHtml = "/index.html";
let needleBareTrailingSlash = "/index/";
let needleBare = "/index";
if (compare.endsWith(needleHtml)) {
return compare.slice(0, compare.length - needleHtml.length) + "/";
} else if (compare.endsWith(needleBareTrailingSlash)) {
return compare.slice(0, compare.length - needleBareTrailingSlash.length) + "/";
} else if (compare.endsWith(needleBare)) {
return compare.slice(0, compare.length - needleBare.length) + "/";
}
return original;
}
// This method is used to generate the `page.url` variable.
// remove all index.htmls from links
// index.html becomes /
// test/index.html becomes test/
toHref() {
if (!this.buildLink) {
// empty or false
return false;
}
let transformedLink = this.toOutputPath();
let original = (transformedLink.charAt(0) !== "/" ? "/" : "") + transformedLink;
let normalized = TemplatePermalink.normalizePathToUrl(original) || "";
for (let transform of this.urlTransforms) {
original =
transform({
url: normalized,
urlStem: TemplatePermalink.getUrlStem(original),
}) ?? original;
}
return TemplatePermalink.normalizePathToUrl(original);
}
toPath(outputDir) {
if (!this.buildLink) {
return false;
}
let uri = this.toOutputPath();
if (uri === false) {
return false;
}
return TemplatePath.addLeadingDotSlash(TemplatePath.normalize(outputDir + "/" + uri));
}
toPathFromRoot() {
if (!this.buildLink) {
return false;
}
let uri = this.toOutputPath();
if (uri === false) {
return false;
}
return TemplatePath.addLeadingDotSlash(TemplatePath.normalize(uri));
}
static _hasDuplicateFolder(dir, base) {
let folders = dir.split("/");
if (!folders[folders.length - 1]) {
folders.pop();
}
return folders[folders.length - 1] === base;
}
static generate(dir, filenameNoExt, extraSubdir, fileExtension = "html") {
let path;
if (fileExtension === "html") {
let hasDupeFolder = TemplatePermalink._hasDuplicateFolder(dir, filenameNoExt);
path =
(dir ? dir + "/" : "") +
(filenameNoExt !== "index" && !hasDupeFolder ? filenameNoExt + "/" : "") +
"index.html";
} else {
path = (dir ? dir + "/" : "") + filenameNoExt + "." + fileExtension;
}
return new TemplatePermalink(path, extraSubdir);
}
}
export default TemplatePermalink;