Jacky Zhao
2024-07-10 247625c4f538a113617e553e1ed3c74d94545e62
feat(layout): add afterBody
12 files modified
76 ■■■■ changed files
docs/advanced/making plugins.md 4 ●●●● patch | view | raw | blame | history
docs/images/quartz layout.png patch | view | raw | blame | history
docs/layout.md 1 ●●●● patch | view | raw | blame | history
quartz.layout.ts 1 ●●●● patch | view | raw | blame | history
quartz/cfg.ts 3 ●●●● patch | view | raw | blame | history
quartz/components/Footer.tsx 1 ●●●● patch | view | raw | blame | history
quartz/components/renderPage.tsx 8 ●●●●● patch | view | raw | blame | history
quartz/plugins/emitters/contentPage.tsx 15 ●●●● patch | view | raw | blame | history
quartz/plugins/emitters/folderPage.tsx 15 ●●●● patch | view | raw | blame | history
quartz/plugins/emitters/tagPage.tsx 15 ●●●● patch | view | raw | blame | history
quartz/plugins/transformers/ofm.ts 1 ●●●● patch | view | raw | blame | history
quartz/styles/base.scss 12 ●●●● patch | view | raw | blame | history
docs/advanced/making plugins.md
@@ -260,11 +260,11 @@
    ...defaultContentPageLayout,
    pageBody: Content(),
  }
  const { head, header, beforeBody, pageBody, left, right, footer } = layout
  const { head, header, beforeBody, pageBody, afterBody, left, right, footer } = layout
  return {
    name: "ContentPage",
    getQuartzComponents() {
      return [head, ...header, ...beforeBody, pageBody, ...left, ...right, footer]
      return [head, ...header, ...beforeBody, pageBody, ...afterBody, ...left, ...right, footer]
    },
    async emit(ctx, content, resources, emit): Promise<FilePath[]> {
      const cfg = ctx.cfg.configuration
docs/images/quartz layout.png

docs/layout.md
@@ -12,6 +12,7 @@
  header: QuartzComponent[] // laid out horizontally
  beforeBody: QuartzComponent[] // laid out vertically
  pageBody: QuartzComponent // single component
  afterBody: QuartzComponent[] // laid out vertically
  left: QuartzComponent[] // vertical on desktop, horizontal on mobile
  right: QuartzComponent[] // vertical on desktop, horizontal on mobile
  footer: QuartzComponent // single component
quartz.layout.ts
@@ -5,6 +5,7 @@
export const sharedPageComponents: SharedLayout = {
  head: Component.Head(),
  header: [],
  afterBody: [],
  footer: Component.Footer({
    links: {
      GitHub: "https://github.com/jackyzha0/quartz",
quartz/cfg.ts
@@ -77,10 +77,11 @@
  header: QuartzComponent[]
  beforeBody: QuartzComponent[]
  pageBody: QuartzComponent
  afterBody: QuartzComponent[]
  left: QuartzComponent[]
  right: QuartzComponent[]
  footer: QuartzComponent
}
export type PageLayout = Pick<FullPageLayout, "beforeBody" | "left" | "right">
export type SharedLayout = Pick<FullPageLayout, "head" | "header" | "footer">
export type SharedLayout = Pick<FullPageLayout, "head" | "header" | "footer" | "afterBody">
quartz/components/Footer.tsx
@@ -13,7 +13,6 @@
    const links = opts?.links ?? []
    return (
      <footer class={`${displayClass ?? ""}`}>
        <hr />
        <p>
          {i18n(cfg.locale).components.footer.createdWith}{" "}
          <a href="https://quartz.jzhao.xyz/">Quartz v{version}</a> © {year}
quartz/components/renderPage.tsx
@@ -14,6 +14,7 @@
  header: QuartzComponent[]
  beforeBody: QuartzComponent[]
  pageBody: QuartzComponent
  afterBody: QuartzComponent[]
  left: QuartzComponent[]
  right: QuartzComponent[]
  footer: QuartzComponent
@@ -187,6 +188,7 @@
    header,
    beforeBody,
    pageBody: Content,
    afterBody,
    left,
    right,
    footer: Footer,
@@ -232,6 +234,12 @@
                </div>
              </div>
              <Content {...componentData} />
              <hr />
              <div class="page-footer">
                {afterBody.map((BodyComponent) => (
                  <BodyComponent {...componentData} />
                ))}
              </div>
            </div>
            {RightComponent}
          </Body>
quartz/plugins/emitters/contentPage.tsx
@@ -59,14 +59,25 @@
    ...userOpts,
  }
  const { head: Head, header, beforeBody, pageBody, left, right, footer: Footer } = opts
  const { head: Head, header, beforeBody, pageBody, afterBody, left, right, footer: Footer } = opts
  const Header = HeaderConstructor()
  const Body = BodyConstructor()
  return {
    name: "ContentPage",
    getQuartzComponents() {
      return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer]
      return [
        Head,
        Header,
        Body,
        ...header,
        ...beforeBody,
        pageBody,
        ...afterBody,
        ...left,
        ...right,
        Footer,
      ]
    },
    async getDependencyGraph(ctx, content, _resources) {
      const graph = new DepGraph<FilePath>()
quartz/plugins/emitters/folderPage.tsx
@@ -33,14 +33,25 @@
    ...userOpts,
  }
  const { head: Head, header, beforeBody, pageBody, left, right, footer: Footer } = opts
  const { head: Head, header, beforeBody, pageBody, afterBody, left, right, footer: Footer } = opts
  const Header = HeaderConstructor()
  const Body = BodyConstructor()
  return {
    name: "FolderPage",
    getQuartzComponents() {
      return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer]
      return [
        Head,
        Header,
        Body,
        ...header,
        ...beforeBody,
        pageBody,
        ...afterBody,
        ...left,
        ...right,
        Footer,
      ]
    },
    async getDependencyGraph(_ctx, content, _resources) {
      // Example graph:
quartz/plugins/emitters/tagPage.tsx
@@ -30,14 +30,25 @@
    ...userOpts,
  }
  const { head: Head, header, beforeBody, pageBody, left, right, footer: Footer } = opts
  const { head: Head, header, beforeBody, pageBody, afterBody, left, right, footer: Footer } = opts
  const Header = HeaderConstructor()
  const Body = BodyConstructor()
  return {
    name: "TagPage",
    getQuartzComponents() {
      return [Head, Header, Body, ...header, ...beforeBody, pageBody, ...left, ...right, Footer]
      return [
        Head,
        Header,
        Body,
        ...header,
        ...beforeBody,
        pageBody,
        ...afterBody,
        ...left,
        ...right,
        Footer,
      ]
    },
    async getDependencyGraph(ctx, content, _resources) {
      const graph = new DepGraph<FilePath>()
quartz/plugins/transformers/ofm.ts
@@ -2,7 +2,6 @@
import { Root, Html, BlockContent, DefinitionContent, Paragraph, Code } from "mdast"
import { Element, Literal, Root as HtmlRoot } from "hast"
import { ReplaceFunction, findAndReplace as mdastFindReplace } from "mdast-util-find-and-replace"
import { slug as slugAnchor } from "github-slugger"
import rehypeRaw from "rehype-raw"
import { SKIP, visit } from "unist-util-visit"
import path from "path"
quartz/styles/base.scss
@@ -201,11 +201,19 @@
    }
  }
  & .page-header {
  & .page-header,
  & .page-footer {
    width: $pageWidth;
    margin: $topSpacing auto 0 auto;
    margin-top: 1rem;
    @media all and (max-width: $fullPageWidth) {
      width: initial;
    }
  }
  & .page-header {
    margin: $topSpacing auto 0 auto;
    @media all and (max-width: $fullPageWidth) {
      margin-top: 2rem;
    }
  }