feat: 404 page emitter
This commit is contained in:
		
							parent
							
								
									2d52eba413
								
							
						
					
					
						commit
						8d6029b7b8
					
				
					 7 changed files with 75 additions and 4 deletions
				
			
		| 
						 | 
					@ -3,7 +3,7 @@ tags:
 | 
				
			||||||
  - plugin/transformer
 | 
					  - 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.
 | 
					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
 | 
					## 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
 | 
					- 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
 | 
					- note/header/block transcludes: https://help.obsidian.md/Linking+notes+and+files/Embedding+files
 | 
				
			||||||
- static dead link detection
 | 
					 | 
				
			||||||
- docker support
 | 
					- docker support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## misc backlog
 | 
					## misc backlog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- breadcrumbs component
 | 
					- breadcrumbs component
 | 
				
			||||||
- filetree component
 | 
					 | 
				
			||||||
- cursor chat extension
 | 
					- cursor chat extension
 | 
				
			||||||
- https://giscus.app/ extension
 | 
					- https://giscus.app/ extension
 | 
				
			||||||
- sidenotes? https://github.com/capnfabs/paperesque
 | 
					- sidenotes? https://github.com/capnfabs/paperesque
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,6 +69,7 @@ const config: QuartzConfig = {
 | 
				
			||||||
      }),
 | 
					      }),
 | 
				
			||||||
      Plugin.Assets(),
 | 
					      Plugin.Assets(),
 | 
				
			||||||
      Plugin.Static(),
 | 
					      Plugin.Static(),
 | 
				
			||||||
 | 
					      Plugin.NotFoundPage(),
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
import ArticleTitle from "./ArticleTitle"
 | 
					 | 
				
			||||||
import Content from "./pages/Content"
 | 
					import Content from "./pages/Content"
 | 
				
			||||||
import TagContent from "./pages/TagContent"
 | 
					import TagContent from "./pages/TagContent"
 | 
				
			||||||
import FolderContent from "./pages/FolderContent"
 | 
					import FolderContent from "./pages/FolderContent"
 | 
				
			||||||
 | 
					import NotFound from "./pages/404"
 | 
				
			||||||
 | 
					import ArticleTitle from "./ArticleTitle"
 | 
				
			||||||
import Darkmode from "./Darkmode"
 | 
					import Darkmode from "./Darkmode"
 | 
				
			||||||
import Head from "./Head"
 | 
					import Head from "./Head"
 | 
				
			||||||
import PageTitle from "./PageTitle"
 | 
					import PageTitle from "./PageTitle"
 | 
				
			||||||
| 
						 | 
					@ -36,4 +37,5 @@ export {
 | 
				
			||||||
  DesktopOnly,
 | 
					  DesktopOnly,
 | 
				
			||||||
  MobileOnly,
 | 
					  MobileOnly,
 | 
				
			||||||
  RecentNotes,
 | 
					  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 { Assets } from "./assets"
 | 
				
			||||||
export { Static } from "./static"
 | 
					export { Static } from "./static"
 | 
				
			||||||
export { ComponentResources } from "./componentResources"
 | 
					export { ComponentResources } from "./componentResources"
 | 
				
			||||||
 | 
					export { NotFoundPage } from "./404"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue