feat: 404 page emitter
This commit is contained in:
		@@ -3,7 +3,7 @@ tags:
 | 
			
		||||
  - plugin/transformer
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
[org-roam](https://www.orgroam.com/) is a plain-text(`org`) personal knowledge management system for [emacs](https://en.wikipedia.org/wiki/Emacs). [ox-hugo](https://github.com/kaushalmodi/ox-hugo) is org exporter backend that exports `org-mode` files to [Hugo](https://gohugo.io/) compatible Markdown.
 | 
			
		||||
[org-roam](https://www.orgroam.com/) is a plain-text personal knowledge management system for [emacs](https://en.wikipedia.org/wiki/Emacs). [ox-hugo](https://github.com/kaushalmodi/ox-hugo) is org exporter backend that exports `org-mode` files to [Hugo](https://gohugo.io/) compatible Markdown.
 | 
			
		||||
 | 
			
		||||
Because the Markdown generated by ox-hugo is not pure Markdown but Hugo specific, we need to transform it to fit into Quartz. This is done by `Plugin.OxHugoFlavouredMarkdown`. Even though this [[making plugins|plugin]] was written with `ox-hugo` in mind, it should work for any Hugo specific Markdown.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,15 +4,14 @@ draft: true
 | 
			
		||||
 | 
			
		||||
## high priority backlog
 | 
			
		||||
 | 
			
		||||
- static dead link detection
 | 
			
		||||
- block links: https://help.obsidian.md/Linking+notes+and+files/Internal+links#Link+to+a+block+in+a+note
 | 
			
		||||
- note/header/block transcludes: https://help.obsidian.md/Linking+notes+and+files/Embedding+files
 | 
			
		||||
- static dead link detection
 | 
			
		||||
- docker support
 | 
			
		||||
 | 
			
		||||
## misc backlog
 | 
			
		||||
 | 
			
		||||
- breadcrumbs component
 | 
			
		||||
- filetree component
 | 
			
		||||
- cursor chat extension
 | 
			
		||||
- https://giscus.app/ extension
 | 
			
		||||
- sidenotes? https://github.com/capnfabs/paperesque
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,7 @@ const config: QuartzConfig = {
 | 
			
		||||
      }),
 | 
			
		||||
      Plugin.Assets(),
 | 
			
		||||
      Plugin.Static(),
 | 
			
		||||
      Plugin.NotFoundPage(),
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
import ArticleTitle from "./ArticleTitle"
 | 
			
		||||
import Content from "./pages/Content"
 | 
			
		||||
import TagContent from "./pages/TagContent"
 | 
			
		||||
import FolderContent from "./pages/FolderContent"
 | 
			
		||||
import NotFound from "./pages/404"
 | 
			
		||||
import ArticleTitle from "./ArticleTitle"
 | 
			
		||||
import Darkmode from "./Darkmode"
 | 
			
		||||
import Head from "./Head"
 | 
			
		||||
import PageTitle from "./PageTitle"
 | 
			
		||||
@@ -36,4 +37,5 @@ export {
 | 
			
		||||
  DesktopOnly,
 | 
			
		||||
  MobileOnly,
 | 
			
		||||
  RecentNotes,
 | 
			
		||||
  NotFound,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								quartz/components/pages/404.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								quartz/components/pages/404.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
import { QuartzComponentConstructor } from "../types"
 | 
			
		||||
 | 
			
		||||
function NotFound() {
 | 
			
		||||
  return (
 | 
			
		||||
    <article class="popover-hint">
 | 
			
		||||
      <h1>404</h1>
 | 
			
		||||
      <p>Either this page is private or doesn't exist.</p>
 | 
			
		||||
    </article>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default (() => NotFound) satisfies QuartzComponentConstructor
 | 
			
		||||
							
								
								
									
										56
									
								
								quartz/plugins/emitters/404.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								quartz/plugins/emitters/404.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
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 { FilePath, FullSlug } from "../../util/path"
 | 
			
		||||
import { sharedPageComponents } from "../../../quartz.layout"
 | 
			
		||||
import { NotFound } from "../../components"
 | 
			
		||||
import { defaultProcessedContent } from "../vfile"
 | 
			
		||||
 | 
			
		||||
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, emit): Promise<FilePath[]> {
 | 
			
		||||
      const cfg = ctx.cfg.configuration
 | 
			
		||||
      const slug = "404" as FullSlug
 | 
			
		||||
      const externalResources = pageResources(slug, resources)
 | 
			
		||||
      const [tree, vfile] = defaultProcessedContent({
 | 
			
		||||
        slug,
 | 
			
		||||
        text: "Not Found",
 | 
			
		||||
        description: "Not Found",
 | 
			
		||||
        frontmatter: { title: "Not Found", tags: [] },
 | 
			
		||||
      })
 | 
			
		||||
      const componentData: QuartzComponentProps = {
 | 
			
		||||
        fileData: vfile.data,
 | 
			
		||||
        externalResources,
 | 
			
		||||
        cfg,
 | 
			
		||||
        children: [],
 | 
			
		||||
        tree,
 | 
			
		||||
        allFiles: [],
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return [
 | 
			
		||||
        await emit({
 | 
			
		||||
          content: renderPage(slug, componentData, opts, externalResources),
 | 
			
		||||
          slug,
 | 
			
		||||
          ext: ".html",
 | 
			
		||||
        }),
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,3 +6,4 @@ export { AliasRedirects } from "./aliases"
 | 
			
		||||
export { Assets } from "./assets"
 | 
			
		||||
export { Static } from "./static"
 | 
			
		||||
export { ComponentResources } from "./componentResources"
 | 
			
		||||
export { NotFoundPage } from "./404"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user