quartz-research-note/quartz/components/renderPage.tsx

81 lines
2.8 KiB
TypeScript
Raw Normal View History

2023-07-01 07:03:01 +00:00
import { render } from "preact-render-to-string";
import { QuartzComponent, QuartzComponentProps } from "./types";
import HeaderConstructor from "./Header"
import BodyConstructor from "./Body"
import { JSResourceToScriptElement, StaticResources } from "../resources";
import { resolveToRoot } from "../path";
interface RenderComponents {
head: QuartzComponent
header: QuartzComponent[],
beforeBody: QuartzComponent[],
pageBody: QuartzComponent,
left: QuartzComponent[],
right: QuartzComponent[],
footer: QuartzComponent,
}
export function pageResources(slug: string, staticResources: StaticResources): StaticResources {
const baseDir = resolveToRoot(slug)
2023-07-02 20:08:29 +00:00
const contentIndexPath = baseDir + "/static/contentIndex.json"
const contentIndexScript = `const fetchData = fetch(\`${contentIndexPath}\`).then(data => data.json())`
2023-07-01 07:03:01 +00:00
return {
css: [baseDir + "/index.css", ...staticResources.css],
js: [
{ src: baseDir + "/prescript.js", loadTime: "beforeDOMReady", contentType: "external" },
2023-07-02 20:08:29 +00:00
{ loadTime: "afterDOMReady", contentType: "inline", spaPreserve: true, script: contentIndexScript },
2023-07-01 07:03:01 +00:00
...staticResources.js,
{ src: baseDir + "/postscript.js", loadTime: "afterDOMReady", moduleType: 'module', contentType: "external" }
]
}
}
export function renderPage(slug: string, componentData: QuartzComponentProps, components: RenderComponents, pageResources: StaticResources): string {
const { head: Head, header, beforeBody, pageBody: Content, left, right, footer: Footer } = components
const Header = HeaderConstructor()
const Body = BodyConstructor()
2023-07-02 20:08:29 +00:00
const LeftComponent =
<div class="left">
<div class="left-inner">
{left.map(BodyComponent => <BodyComponent {...componentData} />)}
</div>
</div>
const RightComponent =
<div class="right">
<div class="right-inner">
{right.map(BodyComponent => <BodyComponent {...componentData} />)}
</div>
</div>
2023-07-01 07:03:01 +00:00
const doc = <html>
<Head {...componentData} />
<body data-slug={slug}>
<div id="quartz-root" class="page">
2023-07-02 20:08:29 +00:00
<div class="page-header">
<Header {...componentData} >
{header.map(HeaderComponent => <HeaderComponent {...componentData} />)}
</Header>
<div class="popover-hint">
{beforeBody.map(BodyComponent => <BodyComponent {...componentData} />)}
</div>
2023-07-01 07:03:01 +00:00
</div>
<Body {...componentData}>
2023-07-02 20:08:29 +00:00
{LeftComponent}
<div class="center">
2023-07-01 07:03:01 +00:00
<Content {...componentData} />
2023-07-02 20:08:29 +00:00
<Footer {...componentData} />
2023-07-01 07:03:01 +00:00
</div>
2023-07-02 20:08:29 +00:00
{RightComponent}
2023-07-01 07:03:01 +00:00
</Body>
</div>
</body>
{pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(res => JSResourceToScriptElement(res))}
</html>
return "<!DOCTYPE html>\n" + render(doc)
}