mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-03-21 21:45:42 -05:00
refactor: delete old page-rendering emitters
Remove ContentPage, FolderPage, TagPage, and NotFoundPage emitters now replaced by community PageType plugins and the PageTypeDispatcher.
This commit is contained in:
parent
4d47086cab
commit
ce19b13808
@ -1,63 +0,0 @@
|
|||||||
import { QuartzEmitterPlugin } from "../types"
|
|
||||||
import { QuartzComponentProps } from "../../components/types"
|
|
||||||
import BodyConstructor from "../../components/Body"
|
|
||||||
import { pageResources, renderPage } from "../../components/renderPage"
|
|
||||||
import { FullPageLayout } from "../../cfg"
|
|
||||||
import { FullSlug } from "../../util/path"
|
|
||||||
import { sharedPageComponents } from "../../../quartz.layout"
|
|
||||||
import { NotFound } from "../../components"
|
|
||||||
import { defaultProcessedContent } from "../vfile"
|
|
||||||
import { write } from "./helpers"
|
|
||||||
import { i18n } from "../../i18n"
|
|
||||||
|
|
||||||
export const NotFoundPage: QuartzEmitterPlugin = () => {
|
|
||||||
const opts: FullPageLayout = {
|
|
||||||
...sharedPageComponents,
|
|
||||||
pageBody: NotFound(),
|
|
||||||
beforeBody: [],
|
|
||||||
left: [],
|
|
||||||
right: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
const { head: Head, pageBody, footer: Footer } = opts
|
|
||||||
const Body = BodyConstructor()
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: "404Page",
|
|
||||||
getQuartzComponents() {
|
|
||||||
return [Head, Body, pageBody, Footer]
|
|
||||||
},
|
|
||||||
async *emit(ctx, _content, resources) {
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
const slug = "404" as FullSlug
|
|
||||||
|
|
||||||
const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`)
|
|
||||||
const path = url.pathname as FullSlug
|
|
||||||
const notFound = i18n(cfg.locale).pages.error.title
|
|
||||||
const [tree, vfile] = defaultProcessedContent({
|
|
||||||
slug,
|
|
||||||
text: notFound,
|
|
||||||
description: notFound,
|
|
||||||
frontmatter: { title: notFound, tags: [] },
|
|
||||||
})
|
|
||||||
const externalResources = pageResources(path, resources)
|
|
||||||
const componentData: QuartzComponentProps = {
|
|
||||||
ctx,
|
|
||||||
fileData: vfile.data,
|
|
||||||
externalResources,
|
|
||||||
cfg,
|
|
||||||
children: [],
|
|
||||||
tree,
|
|
||||||
allFiles: [],
|
|
||||||
}
|
|
||||||
|
|
||||||
yield write({
|
|
||||||
ctx,
|
|
||||||
content: renderPage(cfg, slug, componentData, opts, externalResources),
|
|
||||||
slug,
|
|
||||||
ext: ".html",
|
|
||||||
})
|
|
||||||
},
|
|
||||||
async *partialEmit() {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
import path from "path"
|
|
||||||
import { QuartzEmitterPlugin } from "../types"
|
|
||||||
import { QuartzComponentProps } from "../../components/types"
|
|
||||||
import HeaderConstructor from "../../components/Header"
|
|
||||||
import BodyConstructor from "../../components/Body"
|
|
||||||
import { pageResources, renderPage } from "../../components/renderPage"
|
|
||||||
import { FullPageLayout } from "../../cfg"
|
|
||||||
import { pathToRoot } from "../../util/path"
|
|
||||||
import { defaultContentPageLayout, sharedPageComponents } from "../../../quartz.layout"
|
|
||||||
import { Content } from "../../components"
|
|
||||||
import { styleText } from "util"
|
|
||||||
import { write } from "./helpers"
|
|
||||||
import { BuildCtx } from "../../util/ctx"
|
|
||||||
import { Node } from "unist"
|
|
||||||
import { StaticResources } from "../../util/resources"
|
|
||||||
import { QuartzPluginData } from "../vfile"
|
|
||||||
|
|
||||||
async function processContent(
|
|
||||||
ctx: BuildCtx,
|
|
||||||
tree: Node,
|
|
||||||
fileData: QuartzPluginData,
|
|
||||||
allFiles: QuartzPluginData[],
|
|
||||||
opts: FullPageLayout,
|
|
||||||
resources: StaticResources,
|
|
||||||
) {
|
|
||||||
const slug = fileData.slug!
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
const externalResources = pageResources(pathToRoot(slug), resources)
|
|
||||||
const componentData: QuartzComponentProps = {
|
|
||||||
ctx,
|
|
||||||
fileData,
|
|
||||||
externalResources,
|
|
||||||
cfg,
|
|
||||||
children: [],
|
|
||||||
tree,
|
|
||||||
allFiles,
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = renderPage(cfg, slug, componentData, opts, externalResources)
|
|
||||||
return write({
|
|
||||||
ctx,
|
|
||||||
content,
|
|
||||||
slug,
|
|
||||||
ext: ".html",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOpts) => {
|
|
||||||
const opts: FullPageLayout = {
|
|
||||||
...sharedPageComponents,
|
|
||||||
...defaultContentPageLayout,
|
|
||||||
pageBody: Content(),
|
|
||||||
...userOpts,
|
|
||||||
}
|
|
||||||
|
|
||||||
const { head: Head, header, beforeBody, pageBody, afterBody, left, right, footer: Footer } = opts
|
|
||||||
const Header = HeaderConstructor()
|
|
||||||
const Body = BodyConstructor()
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: "ContentPage",
|
|
||||||
getQuartzComponents() {
|
|
||||||
return [
|
|
||||||
Head,
|
|
||||||
Header,
|
|
||||||
Body,
|
|
||||||
...header,
|
|
||||||
...beforeBody,
|
|
||||||
pageBody,
|
|
||||||
...afterBody,
|
|
||||||
...left,
|
|
||||||
...right,
|
|
||||||
Footer,
|
|
||||||
]
|
|
||||||
},
|
|
||||||
async *emit(ctx, content, resources) {
|
|
||||||
const allFiles = content.map((c) => c[1].data)
|
|
||||||
let containsIndex = false
|
|
||||||
|
|
||||||
for (const [tree, file] of content) {
|
|
||||||
const slug = file.data.slug!
|
|
||||||
if (slug === "index") {
|
|
||||||
containsIndex = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// only process home page, non-tag pages, and non-index pages
|
|
||||||
if (slug.endsWith("/index") || slug.startsWith("tags/")) continue
|
|
||||||
yield processContent(ctx, tree, file.data, allFiles, opts, resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!containsIndex) {
|
|
||||||
console.log(
|
|
||||||
styleText(
|
|
||||||
"yellow",
|
|
||||||
`\nWarning: you seem to be missing an \`index.md\` home page file at the root of your \`${ctx.argv.directory}\` folder (\`${path.join(ctx.argv.directory, "index.md")} does not exist\`). This may cause errors when deploying.`,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async *partialEmit(ctx, content, resources, changeEvents) {
|
|
||||||
const allFiles = content.map((c) => c[1].data)
|
|
||||||
|
|
||||||
// find all slugs that changed or were added
|
|
||||||
const changedSlugs = new Set<string>()
|
|
||||||
for (const changeEvent of changeEvents) {
|
|
||||||
if (!changeEvent.file) continue
|
|
||||||
if (changeEvent.type === "add" || changeEvent.type === "change") {
|
|
||||||
changedSlugs.add(changeEvent.file.data.slug!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [tree, file] of content) {
|
|
||||||
const slug = file.data.slug!
|
|
||||||
if (!changedSlugs.has(slug)) continue
|
|
||||||
if (slug.endsWith("/index") || slug.startsWith("tags/")) continue
|
|
||||||
|
|
||||||
yield processContent(ctx, tree, file.data, allFiles, opts, resources)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,170 +0,0 @@
|
|||||||
import { QuartzEmitterPlugin } from "../types"
|
|
||||||
import { QuartzComponentProps } from "../../components/types"
|
|
||||||
import HeaderConstructor from "../../components/Header"
|
|
||||||
import BodyConstructor from "../../components/Body"
|
|
||||||
import { pageResources, renderPage } from "../../components/renderPage"
|
|
||||||
import { ProcessedContent, QuartzPluginData, defaultProcessedContent } from "../vfile"
|
|
||||||
import { FullPageLayout } from "../../cfg"
|
|
||||||
import path from "path"
|
|
||||||
import {
|
|
||||||
FullSlug,
|
|
||||||
SimpleSlug,
|
|
||||||
stripSlashes,
|
|
||||||
joinSegments,
|
|
||||||
pathToRoot,
|
|
||||||
simplifySlug,
|
|
||||||
} from "../../util/path"
|
|
||||||
import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
|
|
||||||
import { FolderContent } from "../../components"
|
|
||||||
import { write } from "./helpers"
|
|
||||||
import { i18n, TRANSLATIONS } from "../../i18n"
|
|
||||||
import { BuildCtx } from "../../util/ctx"
|
|
||||||
import { StaticResources } from "../../util/resources"
|
|
||||||
interface FolderPageOptions extends FullPageLayout {
|
|
||||||
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
|
|
||||||
}
|
|
||||||
|
|
||||||
async function* processFolderInfo(
|
|
||||||
ctx: BuildCtx,
|
|
||||||
folderInfo: Record<SimpleSlug, ProcessedContent>,
|
|
||||||
allFiles: QuartzPluginData[],
|
|
||||||
opts: FullPageLayout,
|
|
||||||
resources: StaticResources,
|
|
||||||
) {
|
|
||||||
for (const [folder, folderContent] of Object.entries(folderInfo) as [
|
|
||||||
SimpleSlug,
|
|
||||||
ProcessedContent,
|
|
||||||
][]) {
|
|
||||||
const slug = joinSegments(folder, "index") as FullSlug
|
|
||||||
const [tree, file] = folderContent
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
const externalResources = pageResources(pathToRoot(slug), resources)
|
|
||||||
const componentData: QuartzComponentProps = {
|
|
||||||
ctx,
|
|
||||||
fileData: file.data,
|
|
||||||
externalResources,
|
|
||||||
cfg,
|
|
||||||
children: [],
|
|
||||||
tree,
|
|
||||||
allFiles,
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = renderPage(cfg, slug, componentData, opts, externalResources)
|
|
||||||
yield write({
|
|
||||||
ctx,
|
|
||||||
content,
|
|
||||||
slug,
|
|
||||||
ext: ".html",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function computeFolderInfo(
|
|
||||||
folders: Set<SimpleSlug>,
|
|
||||||
content: ProcessedContent[],
|
|
||||||
locale: keyof typeof TRANSLATIONS,
|
|
||||||
): Record<SimpleSlug, ProcessedContent> {
|
|
||||||
// Create default folder descriptions
|
|
||||||
const folderInfo: Record<SimpleSlug, ProcessedContent> = Object.fromEntries(
|
|
||||||
[...folders].map((folder) => [
|
|
||||||
folder,
|
|
||||||
defaultProcessedContent({
|
|
||||||
slug: joinSegments(folder, "index") as FullSlug,
|
|
||||||
frontmatter: {
|
|
||||||
title: `${i18n(locale).pages.folderContent.folder}: ${folder}`,
|
|
||||||
tags: [],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
]),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update with actual content if available
|
|
||||||
for (const [tree, file] of content) {
|
|
||||||
const slug = stripSlashes(simplifySlug(file.data.slug!)) as SimpleSlug
|
|
||||||
if (folders.has(slug)) {
|
|
||||||
folderInfo[slug] = [tree, file]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return folderInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
function _getFolders(slug: FullSlug): SimpleSlug[] {
|
|
||||||
var folderName = path.dirname(slug ?? "") as SimpleSlug
|
|
||||||
const parentFolderNames = [folderName]
|
|
||||||
|
|
||||||
while (folderName !== ".") {
|
|
||||||
folderName = path.dirname(folderName ?? "") as SimpleSlug
|
|
||||||
parentFolderNames.push(folderName)
|
|
||||||
}
|
|
||||||
return parentFolderNames
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FolderPage: QuartzEmitterPlugin<Partial<FolderPageOptions>> = (userOpts) => {
|
|
||||||
const opts: FullPageLayout = {
|
|
||||||
...sharedPageComponents,
|
|
||||||
...defaultListPageLayout,
|
|
||||||
pageBody: FolderContent({ sort: userOpts?.sort }),
|
|
||||||
...userOpts,
|
|
||||||
}
|
|
||||||
|
|
||||||
const { head: Head, header, beforeBody, pageBody, afterBody, left, right, footer: Footer } = opts
|
|
||||||
const Header = HeaderConstructor()
|
|
||||||
const Body = BodyConstructor()
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: "FolderPage",
|
|
||||||
getQuartzComponents() {
|
|
||||||
return [
|
|
||||||
Head,
|
|
||||||
Header,
|
|
||||||
Body,
|
|
||||||
...header,
|
|
||||||
...beforeBody,
|
|
||||||
pageBody,
|
|
||||||
...afterBody,
|
|
||||||
...left,
|
|
||||||
...right,
|
|
||||||
Footer,
|
|
||||||
]
|
|
||||||
},
|
|
||||||
async *emit(ctx, content, resources) {
|
|
||||||
const allFiles = content.map((c) => c[1].data)
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
|
|
||||||
const folders: Set<SimpleSlug> = new Set(
|
|
||||||
allFiles.flatMap((data) => {
|
|
||||||
return data.slug
|
|
||||||
? _getFolders(data.slug).filter(
|
|
||||||
(folderName) => folderName !== "." && folderName !== "tags",
|
|
||||||
)
|
|
||||||
: []
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const folderInfo = computeFolderInfo(folders, content, cfg.locale)
|
|
||||||
yield* processFolderInfo(ctx, folderInfo, allFiles, opts, resources)
|
|
||||||
},
|
|
||||||
async *partialEmit(ctx, content, resources, changeEvents) {
|
|
||||||
const allFiles = content.map((c) => c[1].data)
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
|
|
||||||
// Find all folders that need to be updated based on changed files
|
|
||||||
const affectedFolders: Set<SimpleSlug> = new Set()
|
|
||||||
for (const changeEvent of changeEvents) {
|
|
||||||
if (!changeEvent.file) continue
|
|
||||||
const slug = changeEvent.file.data.slug!
|
|
||||||
const folders = _getFolders(slug).filter(
|
|
||||||
(folderName) => folderName !== "." && folderName !== "tags",
|
|
||||||
)
|
|
||||||
folders.forEach((folder) => affectedFolders.add(folder))
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are affected folders, rebuild their pages
|
|
||||||
if (affectedFolders.size > 0) {
|
|
||||||
const folderInfo = computeFolderInfo(affectedFolders, content, cfg.locale)
|
|
||||||
yield* processFolderInfo(ctx, folderInfo, allFiles, opts, resources)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,12 +1,8 @@
|
|||||||
export { ContentPage } from "./contentPage"
|
|
||||||
export { TagPage } from "./tagPage"
|
|
||||||
export { FolderPage } from "./folderPage"
|
|
||||||
export { ContentIndex as ContentIndex } from "./contentIndex"
|
export { ContentIndex as ContentIndex } from "./contentIndex"
|
||||||
export { AliasRedirects } from "./aliases"
|
export { AliasRedirects } from "./aliases"
|
||||||
export { Assets } from "./assets"
|
export { Assets } from "./assets"
|
||||||
export { Static } from "./static"
|
export { Static } from "./static"
|
||||||
export { Favicon } from "./favicon"
|
export { Favicon } from "./favicon"
|
||||||
export { ComponentResources } from "./componentResources"
|
export { ComponentResources } from "./componentResources"
|
||||||
export { NotFoundPage } from "./404"
|
|
||||||
export { CNAME } from "./cname"
|
export { CNAME } from "./cname"
|
||||||
export { CustomOgImages } from "./ogImage"
|
export { CustomOgImages } from "./ogImage"
|
||||||
|
|||||||
@ -1,170 +0,0 @@
|
|||||||
import { QuartzEmitterPlugin } from "../types"
|
|
||||||
import { QuartzComponentProps } from "../../components/types"
|
|
||||||
import HeaderConstructor from "../../components/Header"
|
|
||||||
import BodyConstructor from "../../components/Body"
|
|
||||||
import { pageResources, renderPage } from "../../components/renderPage"
|
|
||||||
import { ProcessedContent, QuartzPluginData, defaultProcessedContent } from "../vfile"
|
|
||||||
import { FullPageLayout } from "../../cfg"
|
|
||||||
import { FullSlug, getAllSegmentPrefixes, joinSegments, pathToRoot } from "../../util/path"
|
|
||||||
import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
|
|
||||||
import { TagContent } from "../../components"
|
|
||||||
import { write } from "./helpers"
|
|
||||||
import { i18n, TRANSLATIONS } from "../../i18n"
|
|
||||||
import { BuildCtx } from "../../util/ctx"
|
|
||||||
import { StaticResources } from "../../util/resources"
|
|
||||||
|
|
||||||
interface TagPageOptions extends FullPageLayout {
|
|
||||||
sort?: (f1: QuartzPluginData, f2: QuartzPluginData) => number
|
|
||||||
}
|
|
||||||
|
|
||||||
function computeTagInfo(
|
|
||||||
allFiles: QuartzPluginData[],
|
|
||||||
content: ProcessedContent[],
|
|
||||||
locale: keyof typeof TRANSLATIONS,
|
|
||||||
): [Set<string>, Record<string, ProcessedContent>] {
|
|
||||||
const tags: Set<string> = new Set(
|
|
||||||
allFiles.flatMap((data) => data.frontmatter?.tags ?? []).flatMap(getAllSegmentPrefixes),
|
|
||||||
)
|
|
||||||
|
|
||||||
// add base tag
|
|
||||||
tags.add("index")
|
|
||||||
|
|
||||||
const tagDescriptions: Record<string, ProcessedContent> = Object.fromEntries(
|
|
||||||
[...tags].map((tag) => {
|
|
||||||
const title =
|
|
||||||
tag === "index"
|
|
||||||
? i18n(locale).pages.tagContent.tagIndex
|
|
||||||
: `${i18n(locale).pages.tagContent.tag}: ${tag}`
|
|
||||||
return [
|
|
||||||
tag,
|
|
||||||
defaultProcessedContent({
|
|
||||||
slug: joinSegments("tags", tag) as FullSlug,
|
|
||||||
frontmatter: { title, tags: [] },
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update with actual content if available
|
|
||||||
for (const [tree, file] of content) {
|
|
||||||
const slug = file.data.slug!
|
|
||||||
if (slug.startsWith("tags/")) {
|
|
||||||
const tag = slug.slice("tags/".length)
|
|
||||||
if (tags.has(tag)) {
|
|
||||||
tagDescriptions[tag] = [tree, file]
|
|
||||||
if (file.data.frontmatter?.title === tag) {
|
|
||||||
file.data.frontmatter.title = `${i18n(locale).pages.tagContent.tag}: ${tag}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [tags, tagDescriptions]
|
|
||||||
}
|
|
||||||
|
|
||||||
async function processTagPage(
|
|
||||||
ctx: BuildCtx,
|
|
||||||
tag: string,
|
|
||||||
tagContent: ProcessedContent,
|
|
||||||
allFiles: QuartzPluginData[],
|
|
||||||
opts: FullPageLayout,
|
|
||||||
resources: StaticResources,
|
|
||||||
) {
|
|
||||||
const slug = joinSegments("tags", tag) as FullSlug
|
|
||||||
const [tree, file] = tagContent
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
const externalResources = pageResources(pathToRoot(slug), resources)
|
|
||||||
const componentData: QuartzComponentProps = {
|
|
||||||
ctx,
|
|
||||||
fileData: file.data,
|
|
||||||
externalResources,
|
|
||||||
cfg,
|
|
||||||
children: [],
|
|
||||||
tree,
|
|
||||||
allFiles,
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = renderPage(cfg, slug, componentData, opts, externalResources)
|
|
||||||
return write({
|
|
||||||
ctx,
|
|
||||||
content,
|
|
||||||
slug: file.data.slug!,
|
|
||||||
ext: ".html",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export const TagPage: QuartzEmitterPlugin<Partial<TagPageOptions>> = (userOpts) => {
|
|
||||||
const opts: FullPageLayout = {
|
|
||||||
...sharedPageComponents,
|
|
||||||
...defaultListPageLayout,
|
|
||||||
pageBody: TagContent({ sort: userOpts?.sort }),
|
|
||||||
...userOpts,
|
|
||||||
}
|
|
||||||
|
|
||||||
const { head: Head, header, beforeBody, pageBody, afterBody, left, right, footer: Footer } = opts
|
|
||||||
const Header = HeaderConstructor()
|
|
||||||
const Body = BodyConstructor()
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: "TagPage",
|
|
||||||
getQuartzComponents() {
|
|
||||||
return [
|
|
||||||
Head,
|
|
||||||
Header,
|
|
||||||
Body,
|
|
||||||
...header,
|
|
||||||
...beforeBody,
|
|
||||||
pageBody,
|
|
||||||
...afterBody,
|
|
||||||
...left,
|
|
||||||
...right,
|
|
||||||
Footer,
|
|
||||||
]
|
|
||||||
},
|
|
||||||
async *emit(ctx, content, resources) {
|
|
||||||
const allFiles = content.map((c) => c[1].data)
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
const [tags, tagDescriptions] = computeTagInfo(allFiles, content, cfg.locale)
|
|
||||||
|
|
||||||
for (const tag of tags) {
|
|
||||||
yield processTagPage(ctx, tag, tagDescriptions[tag], allFiles, opts, resources)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async *partialEmit(ctx, content, resources, changeEvents) {
|
|
||||||
const allFiles = content.map((c) => c[1].data)
|
|
||||||
const cfg = ctx.cfg.configuration
|
|
||||||
|
|
||||||
// Find all tags that need to be updated based on changed files
|
|
||||||
const affectedTags: Set<string> = new Set()
|
|
||||||
for (const changeEvent of changeEvents) {
|
|
||||||
if (!changeEvent.file) continue
|
|
||||||
const slug = changeEvent.file.data.slug!
|
|
||||||
|
|
||||||
// If it's a tag page itself that changed
|
|
||||||
if (slug.startsWith("tags/")) {
|
|
||||||
const tag = slug.slice("tags/".length)
|
|
||||||
affectedTags.add(tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a file with tags changed, we need to update those tag pages
|
|
||||||
const fileTags = changeEvent.file.data.frontmatter?.tags ?? []
|
|
||||||
fileTags.flatMap(getAllSegmentPrefixes).forEach((tag) => affectedTags.add(tag))
|
|
||||||
|
|
||||||
// Always update the index tag page if any file changes
|
|
||||||
affectedTags.add("index")
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are affected tags, rebuild their pages
|
|
||||||
if (affectedTags.size > 0) {
|
|
||||||
// We still need to compute all tags because tag pages show all tags
|
|
||||||
const [_tags, tagDescriptions] = computeTagInfo(allFiles, content, cfg.locale)
|
|
||||||
|
|
||||||
for (const tag of affectedTags) {
|
|
||||||
if (tagDescriptions[tag]) {
|
|
||||||
yield processTagPage(ctx, tag, tagDescriptions[tag], allFiles, opts, resources)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user