mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-19 19:04:06 -06:00
Merge c097dee535 into e6cc9ba368
This commit is contained in:
commit
08fa7e8ef3
@ -2,6 +2,10 @@
|
|||||||
title: AliasRedirects
|
title: AliasRedirects
|
||||||
tags:
|
tags:
|
||||||
- plugin/emitter
|
- plugin/emitter
|
||||||
|
permalink: "permalink"
|
||||||
|
alias:
|
||||||
|
- "alias"
|
||||||
|
- "aliases"
|
||||||
---
|
---
|
||||||
|
|
||||||
This plugin emits HTML redirect pages for aliases and permalinks defined in the frontmatter of content files.
|
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"
|
```md title="foo.md"
|
||||||
---
|
---
|
||||||
title: "Foo"
|
title: "Foo"
|
||||||
|
permalink: "bar"
|
||||||
alias:
|
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:
|
The emitter supports the following aliases:
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { FullSlug, isRelativeURL, resolveRelative, simplifySlug } from "../../util/path"
|
import { FullSlug, FilePath, joinSegments, isRelativeURL, resolveRelative, simplifySlug } from "../../util/path"
|
||||||
import { QuartzEmitterPlugin } from "../types"
|
import { QuartzEmitterPlugin } from "../types"
|
||||||
import { write } from "./helpers"
|
import { write } from "./helpers"
|
||||||
import { BuildCtx } from "../../util/ctx"
|
import { BuildCtx } from "../../util/ctx"
|
||||||
@ -38,11 +38,6 @@ async function* processFile(ctx: BuildCtx, file: VFile) {
|
|||||||
|
|
||||||
export const AliasRedirects: QuartzEmitterPlugin = () => ({
|
export const AliasRedirects: QuartzEmitterPlugin = () => ({
|
||||||
name: "AliasRedirects",
|
name: "AliasRedirects",
|
||||||
async *emit(ctx, content) {
|
|
||||||
for (const [_tree, file] of content) {
|
|
||||||
yield* processFile(ctx, file)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async *partialEmit(ctx, _content, _resources, changeEvents) {
|
async *partialEmit(ctx, _content, _resources, changeEvents) {
|
||||||
for (const changeEvent of changeEvents) {
|
for (const changeEvent of changeEvents) {
|
||||||
if (!changeEvent.file) continue
|
if (!changeEvent.file) continue
|
||||||
@ -50,6 +45,39 @@ export const AliasRedirects: QuartzEmitterPlugin = () => ({
|
|||||||
// add new ones if this file still exists
|
// add new ones if this file still exists
|
||||||
yield* processFile(ctx, changeEvent.file)
|
yield* processFile(ctx, changeEvent.file)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
async emit(ctx, content, _resources): Promise<FilePath[]> {
|
||||||
|
const { argv } = ctx
|
||||||
|
const fps: FilePath[] = []
|
||||||
|
|
||||||
|
for (const [_tree, file] of content) {
|
||||||
|
const ogSlug = simplifySlug(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: `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<title>${ogSlug}</title>
|
||||||
|
<link rel="canonical" href="${redirUrl}">
|
||||||
|
<meta name="robots" content="noindex">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="refresh" content="0; url=${redirUrl}">
|
||||||
|
</head>
|
||||||
|
</html>
|
||||||
|
`,
|
||||||
|
slug: slug as FullSlug,
|
||||||
|
ext: ".html",
|
||||||
|
})
|
||||||
|
|
||||||
|
fps.push(fp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@ -3,9 +3,12 @@ import remarkFrontmatter from "remark-frontmatter"
|
|||||||
import { QuartzTransformerPlugin } from "../types"
|
import { QuartzTransformerPlugin } from "../types"
|
||||||
import yaml from "js-yaml"
|
import yaml from "js-yaml"
|
||||||
import toml from "toml"
|
import toml from "toml"
|
||||||
import { FilePath, FullSlug, getFileExtension, slugifyFilePath, slugTag } from "../../util/path"
|
import { FilePath, FullSlug, getFileExtension, joinSegments, slugifyFilePath, slugTag } from "../../util/path"
|
||||||
import { QuartzPluginData } from "../vfile"
|
import { QuartzPluginData } from "../vfile"
|
||||||
import { i18n } from "../../i18n"
|
import { i18n } from "../../i18n"
|
||||||
|
import { Argv } from "../../util/ctx"
|
||||||
|
import { VFile } from "vfile"
|
||||||
|
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
delimiters: string | [string, string]
|
delimiters: string | [string, string]
|
||||||
@ -19,7 +22,10 @@ const defaultOptions: Options = {
|
|||||||
|
|
||||||
function coalesceAliases(data: { [key: string]: any }, aliases: string[]) {
|
function coalesceAliases(data: { [key: string]: any }, aliases: string[]) {
|
||||||
for (const alias of aliases) {
|
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]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,13 +46,14 @@ function coerceToArray(input: string | string[]): string[] | undefined {
|
|||||||
.map((tag: string | number) => tag.toString())
|
.map((tag: string | number) => tag.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAliasSlugs(aliases: string[]): FullSlug[] {
|
export function getAliasSlugs(aliases: string[], _argv: Argv, file: VFile): FullSlug[] {
|
||||||
const res: FullSlug[] = []
|
const slugs: FullSlug[] = aliases.map(
|
||||||
for (const alias of aliases) {
|
(alias) => (alias.startsWith("/") ? alias : `/${alias}`) as FullSlug,
|
||||||
const isMd = getFileExtension(alias) === "md"
|
)
|
||||||
const mockFp = isMd ? alias : alias + ".md"
|
const permalink = file.data.frontmatter?.permalink
|
||||||
const slug = slugifyFilePath(mockFp as FilePath)
|
if (typeof permalink === "string") {
|
||||||
res.push(slug)
|
const absolutePermalink = permalink.startsWith("/") ? permalink : `/${permalink}`
|
||||||
|
slugs.push(absolutePermalink as FullSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -145,6 +152,7 @@ declare module "vfile" {
|
|||||||
published: string
|
published: string
|
||||||
description: string
|
description: string
|
||||||
socialDescription: string
|
socialDescription: string
|
||||||
|
permalink: string
|
||||||
publish: boolean | string
|
publish: boolean | string
|
||||||
draft: boolean | string
|
draft: boolean | string
|
||||||
lang: string
|
lang: string
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user