fix: 404 page styling for nested pages (closes #458)

This commit is contained in:
Jacky Zhao 2023-09-12 21:29:57 -07:00
parent 71d81bde1d
commit 60a3c54339
7 changed files with 31 additions and 13 deletions

View file

@ -1,4 +1,4 @@
import { joinSegments, pathToRoot } from "../util/path" import { FullSlug, _stripSlashes, joinSegments, pathToRoot } from "../util/path"
import { JSResourceToScriptElement } from "../util/resources" import { JSResourceToScriptElement } from "../util/resources"
import { QuartzComponentConstructor, QuartzComponentProps } from "./types" import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
@ -7,7 +7,11 @@ export default (() => {
const title = fileData.frontmatter?.title ?? "Untitled" const title = fileData.frontmatter?.title ?? "Untitled"
const description = fileData.description?.trim() ?? "No description provided" const description = fileData.description?.trim() ?? "No description provided"
const { css, js } = externalResources const { css, js } = externalResources
const baseDir = pathToRoot(fileData.slug!)
const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`)
const path = url.pathname as FullSlug
const baseDir = fileData.slug === "404" ? path : pathToRoot(fileData.slug!)
const iconPath = joinSegments(baseDir, "static/icon.png") const iconPath = joinSegments(baseDir, "static/icon.png")
const ogImagePath = `https://${cfg.baseUrl}/static/og-image.png` const ogImagePath = `https://${cfg.baseUrl}/static/og-image.png`

View file

@ -3,7 +3,7 @@ import { QuartzComponent, QuartzComponentProps } from "./types"
import HeaderConstructor from "./Header" import HeaderConstructor from "./Header"
import BodyConstructor from "./Body" import BodyConstructor from "./Body"
import { JSResourceToScriptElement, StaticResources } from "../util/resources" import { JSResourceToScriptElement, StaticResources } from "../util/resources"
import { FullSlug, joinSegments, pathToRoot } from "../util/path" import { FullSlug, RelativeURL, joinSegments } from "../util/path"
interface RenderComponents { interface RenderComponents {
head: QuartzComponent head: QuartzComponent
@ -15,9 +15,10 @@ interface RenderComponents {
footer: QuartzComponent footer: QuartzComponent
} }
export function pageResources(slug: FullSlug, staticResources: StaticResources): StaticResources { export function pageResources(
const baseDir = pathToRoot(slug) baseDir: FullSlug | RelativeURL,
staticResources: StaticResources,
): StaticResources {
const contentIndexPath = joinSegments(baseDir, "static/contentIndex.json") const contentIndexPath = joinSegments(baseDir, "static/contentIndex.json")
const contentIndexScript = `const fetchData = fetch(\`${contentIndexPath}\`).then(data => data.json())` const contentIndexScript = `const fetchData = fetch(\`${contentIndexPath}\`).then(data => data.json())`

View file

@ -28,7 +28,10 @@ export const NotFoundPage: QuartzEmitterPlugin = () => {
async emit(ctx, _content, resources, emit): Promise<FilePath[]> { async emit(ctx, _content, resources, emit): Promise<FilePath[]> {
const cfg = ctx.cfg.configuration const cfg = ctx.cfg.configuration
const slug = "404" as FullSlug const slug = "404" as FullSlug
const externalResources = pageResources(slug, resources)
const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`)
const path = url.pathname as FullSlug
const externalResources = pageResources(path, resources)
const [tree, vfile] = defaultProcessedContent({ const [tree, vfile] = defaultProcessedContent({
slug, slug,
text: "Not Found", text: "Not Found",

View file

@ -4,7 +4,7 @@ import HeaderConstructor from "../../components/Header"
import BodyConstructor from "../../components/Body" import BodyConstructor from "../../components/Body"
import { pageResources, renderPage } from "../../components/renderPage" import { pageResources, renderPage } from "../../components/renderPage"
import { FullPageLayout } from "../../cfg" import { FullPageLayout } from "../../cfg"
import { FilePath } from "../../util/path" import { FilePath, pathToRoot } from "../../util/path"
import { defaultContentPageLayout, sharedPageComponents } from "../../../quartz.layout" import { defaultContentPageLayout, sharedPageComponents } from "../../../quartz.layout"
import { Content } from "../../components" import { Content } from "../../components"
@ -31,7 +31,7 @@ export const ContentPage: QuartzEmitterPlugin<Partial<FullPageLayout>> = (userOp
const allFiles = content.map((c) => c[1].data) const allFiles = content.map((c) => c[1].data)
for (const [tree, file] of content) { for (const [tree, file] of content) {
const slug = file.data.slug! const slug = file.data.slug!
const externalResources = pageResources(slug, resources) const externalResources = pageResources(pathToRoot(slug), resources)
const componentData: QuartzComponentProps = { const componentData: QuartzComponentProps = {
fileData: file.data, fileData: file.data,
externalResources, externalResources,

View file

@ -12,6 +12,7 @@ import {
SimpleSlug, SimpleSlug,
_stripSlashes, _stripSlashes,
joinSegments, joinSegments,
pathToRoot,
simplifySlug, simplifySlug,
} from "../../util/path" } from "../../util/path"
import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout" import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
@ -69,7 +70,7 @@ export const FolderPage: QuartzEmitterPlugin<FullPageLayout> = (userOpts) => {
for (const folder of folders) { for (const folder of folders) {
const slug = joinSegments(folder, "index") as FullSlug const slug = joinSegments(folder, "index") as FullSlug
const externalResources = pageResources(slug, resources) const externalResources = pageResources(pathToRoot(slug), resources)
const [tree, file] = folderDescriptions[folder] const [tree, file] = folderDescriptions[folder]
const componentData: QuartzComponentProps = { const componentData: QuartzComponentProps = {
fileData: file.data, fileData: file.data,

View file

@ -5,7 +5,13 @@ import BodyConstructor from "../../components/Body"
import { pageResources, renderPage } from "../../components/renderPage" import { pageResources, renderPage } from "../../components/renderPage"
import { ProcessedContent, defaultProcessedContent } from "../vfile" import { ProcessedContent, defaultProcessedContent } from "../vfile"
import { FullPageLayout } from "../../cfg" import { FullPageLayout } from "../../cfg"
import { FilePath, FullSlug, getAllSegmentPrefixes, joinSegments } from "../../util/path" import {
FilePath,
FullSlug,
getAllSegmentPrefixes,
joinSegments,
pathToRoot,
} from "../../util/path"
import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout" import { defaultListPageLayout, sharedPageComponents } from "../../../quartz.layout"
import { TagContent } from "../../components" import { TagContent } from "../../components"
@ -62,7 +68,7 @@ export const TagPage: QuartzEmitterPlugin<FullPageLayout> = (userOpts) => {
for (const tag of tags) { for (const tag of tags) {
const slug = joinSegments("tags", tag) as FullSlug const slug = joinSegments("tags", tag) as FullSlug
const externalResources = pageResources(slug, resources) const externalResources = pageResources(pathToRoot(slug), resources)
const [tree, file] = tagDescriptions[tag] const [tree, file] = tagDescriptions[tag]
const componentData: QuartzComponentProps = { const componentData: QuartzComponentProps = {
fileData: file.data, fileData: file.data,

View file

@ -123,7 +123,10 @@ export function slugTag(tag: string) {
} }
export function joinSegments(...args: string[]): string { export function joinSegments(...args: string[]): string {
return args.filter((segment) => segment !== "").join("/") return args
.filter((segment) => segment !== "")
.join("/")
.replace(/\/\/+/g, "/")
} }
export function getAllSegmentPrefixes(tags: string): string[] { export function getAllSegmentPrefixes(tags: string): string[] {