From 6ffbd905fbc31bdc97589743ebfbd1037a212eea Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Tue, 4 Mar 2025 14:22:18 +0000 Subject: [PATCH 1/2] fix(alias): Fix permalink and alias resolution --- docs/plugins/AliasRedirects.md | 11 ++++++++--- quartz/plugins/emitters/aliases.ts | 11 +++++++---- quartz/plugins/transformers/frontmatter.ts | 17 ++++++++++------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/docs/plugins/AliasRedirects.md b/docs/plugins/AliasRedirects.md index 8c0365377..caf656cee 100644 --- a/docs/plugins/AliasRedirects.md +++ b/docs/plugins/AliasRedirects.md @@ -2,6 +2,10 @@ title: AliasRedirects tags: - plugin/emitter +permalink: "permalink" +alias: + - "alias" + - "aliases" --- This plugin emits HTML redirect pages for aliases and permalinks defined in the frontmatter of content files. @@ -11,14 +15,15 @@ For example, A `foo.md` has the following frontmatter ```md title="foo.md" --- title: "Foo" +permalink: "bar" alias: - - "bar" + - "baz" --- ``` -The target `host.me/bar` will be redirected to `host.me/foo` +The target `host.me/bar` and `host.me/baz` will be redirected to `host.me/foo` -Note that these are permanent redirect. +Note that these are permanent redirects. The emitter supports the following aliases: diff --git a/quartz/plugins/emitters/aliases.ts b/quartz/plugins/emitters/aliases.ts index b5bfff061..d209544dc 100644 --- a/quartz/plugins/emitters/aliases.ts +++ b/quartz/plugins/emitters/aliases.ts @@ -1,4 +1,4 @@ -import { FilePath, joinSegments, resolveRelative, simplifySlug } from "../../util/path" +import { FilePath, joinSegments, simplifySlug, FullSlug } from "../../util/path" import { QuartzEmitterPlugin } from "../types" import { write } from "./helpers" import DepGraph from "../../depgraph" @@ -28,8 +28,11 @@ export const AliasRedirects: QuartzEmitterPlugin = () => ({ for (const [_tree, file] of content) { const ogSlug = simplifySlug(file.data.slug!) - for (const slug of file.data.aliases ?? []) { - const redirUrl = resolveRelative(slug, file.data.slug!) + const slugs = [file.data.frontmatter?.permalink || [], ...(file.data.aliases || [])] + + for (const slug of slugs ?? []) { + if (typeof slug !== "string") continue + const redirUrl = file.data.slug! const fp = await write({ ctx, content: ` @@ -44,7 +47,7 @@ export const AliasRedirects: QuartzEmitterPlugin = () => ({ `, - slug, + slug: slug as FullSlug, ext: ".html", }) diff --git a/quartz/plugins/transformers/frontmatter.ts b/quartz/plugins/transformers/frontmatter.ts index 625cf607a..fee1eff76 100644 --- a/quartz/plugins/transformers/frontmatter.ts +++ b/quartz/plugins/transformers/frontmatter.ts @@ -3,12 +3,11 @@ import remarkFrontmatter from "remark-frontmatter" import { QuartzTransformerPlugin } from "../types" import yaml from "js-yaml" import toml from "toml" -import { FilePath, FullSlug, joinSegments, slugifyFilePath, slugTag } from "../../util/path" +import { FullSlug, joinSegments, slugTag } from "../../util/path" import { QuartzPluginData } from "../vfile" import { i18n } from "../../i18n" import { Argv } from "../../util/ctx" import { VFile } from "vfile" -import path from "path" export interface Options { delimiters: string | [string, string] @@ -22,7 +21,10 @@ const defaultOptions: Options = { function coalesceAliases(data: { [key: string]: any }, aliases: string[]) { for (const alias of aliases) { - if (data[alias] !== undefined && data[alias] !== null) return data[alias] + if (data[alias] !== undefined && data[alias] !== null) { + if (typeof data[alias] === "string") return [data[alias]] + return data[alias] + } } } @@ -43,14 +45,14 @@ function coerceToArray(input: string | string[]): string[] | undefined { .map((tag: string | number) => tag.toString()) } -export function getAliasSlugs(aliases: string[], argv: Argv, file: VFile): FullSlug[] { - const dir = path.posix.relative(argv.directory, path.dirname(file.data.filePath!)) +export function getAliasSlugs(aliases: string[], _argv: Argv, file: VFile): FullSlug[] { const slugs: FullSlug[] = aliases.map( - (alias) => path.posix.join(dir, slugifyFilePath(alias as FilePath)) as FullSlug, + (alias) => (alias.startsWith("/") ? alias : `/${alias}`) as FullSlug, ) const permalink = file.data.frontmatter?.permalink if (typeof permalink === "string") { - slugs.push(permalink as FullSlug) + const absolutePermalink = permalink.startsWith("?") ? permalink : `/${permalink}` + slugs.push(absolutePermalink as FullSlug) } // fix any slugs that have trailing slash return slugs.map((slug) => @@ -130,6 +132,7 @@ declare module "vfile" { created: string published: string description: string + permalink: string publish: boolean | string draft: boolean | string lang: string From 8df33942eb3a909ed25416c779e6ecd90080bba4 Mon Sep 17 00:00:00 2001 From: Emile Bangma Date: Wed, 5 Mar 2025 12:53:55 +0100 Subject: [PATCH 2/2] fix: typo in permalink check --- quartz/plugins/transformers/frontmatter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/plugins/transformers/frontmatter.ts b/quartz/plugins/transformers/frontmatter.ts index fee1eff76..bbc5ea58d 100644 --- a/quartz/plugins/transformers/frontmatter.ts +++ b/quartz/plugins/transformers/frontmatter.ts @@ -51,7 +51,7 @@ export function getAliasSlugs(aliases: string[], _argv: Argv, file: VFile): Full ) const permalink = file.data.frontmatter?.permalink if (typeof permalink === "string") { - const absolutePermalink = permalink.startsWith("?") ? permalink : `/${permalink}` + const absolutePermalink = permalink.startsWith("/") ? permalink : `/${permalink}` slugs.push(absolutePermalink as FullSlug) } // fix any slugs that have trailing slash