2024-02-17 17:45:01 +00:00
import path from "path"
2023-06-16 19:41:59 -07:00
import { QuartzEmitterPlugin } from "../types"
2023-06-07 22:27:32 -07:00
import { QuartzComponentProps } from "../../components/types"
2023-07-01 00:03:01 -07:00
import HeaderConstructor from "../../components/Header"
2023-06-11 23:46:38 -07:00
import BodyConstructor from "../../components/Body"
2023-07-01 00:03:01 -07:00
import { pageResources , renderPage } from "../../components/renderPage"
import { FullPageLayout } from "../../cfg"
2025-03-16 14:17:31 -07:00
import { pathToRoot } from "../../util/path"
2023-07-25 23:37:24 -07:00
import { defaultContentPageLayout , sharedPageComponents } from "../../../quartz.layout"
import { Content } from "../../components"
2023-09-22 09:43:34 -07:00
import chalk from "chalk"
2024-01-18 18:56:14 +00:00
import { write } from "./helpers"
2025-03-16 14:17:31 -07:00
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 ,
}
2024-02-17 17:45:01 +00:00
2025-03-16 14:17:31 -07:00
const content = renderPage ( cfg , slug , componentData , opts , externalResources )
return write ( {
ctx ,
content ,
slug ,
ext : ".html" ,
2024-02-17 17:45:01 +00:00
} )
}
2023-07-25 23:37:24 -07:00
export const ContentPage : QuartzEmitterPlugin < Partial < FullPageLayout > > = ( userOpts ) = > {
const opts : FullPageLayout = {
. . . sharedPageComponents ,
. . . defaultContentPageLayout ,
pageBody : Content ( ) ,
. . . userOpts ,
2023-06-03 15:07:19 -04:00
}
2024-07-09 19:09:31 -07:00
const { head : Head , header , beforeBody , pageBody , afterBody , left , right , footer : Footer } = opts
2023-06-11 23:46:38 -07:00
const Header = HeaderConstructor ( )
const Body = BodyConstructor ( )
2023-06-11 23:26:43 -07:00
return {
name : "ContentPage" ,
getQuartzComponents() {
2024-07-09 19:09:31 -07:00
return [
Head ,
Header ,
Body ,
. . . header ,
. . . beforeBody ,
pageBody ,
. . . afterBody ,
. . . left ,
. . . right ,
Footer ,
]
2023-06-11 23:26:43 -07:00
} ,
2025-03-13 10:27:46 -07:00
async * emit ( ctx , content , resources ) {
2023-07-22 17:27:41 -07:00
const allFiles = content . map ( ( c ) = > c [ 1 ] . data )
2023-09-22 09:43:34 -07:00
let containsIndex = false
2025-03-16 14:17:31 -07:00
2023-06-11 23:26:43 -07:00
for ( const [ tree , file ] of content ) {
2023-08-19 15:52:25 -07:00
const slug = file . data . slug !
2023-09-22 09:43:34 -07:00
if ( slug === "index" ) {
containsIndex = true
}
2025-03-16 14:17:31 -07:00
// 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 )
2023-06-11 23:26:43 -07:00
}
2023-09-22 09:43:34 -07:00
2025-03-16 14:17:31 -07:00
if ( ! containsIndex ) {
2023-09-22 09:43:34 -07:00
console . log (
chalk . yellow (
2025-03-06 09:41:26 -08:00
` \ 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. ` ,
2023-09-22 09:43:34 -07:00
) ,
)
}
2023-07-22 17:27:41 -07:00
} ,
2025-03-16 14:17:31 -07:00
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 )
}
} ,
2023-05-31 17:01:23 -04:00
}
}