feat: unify layout slot architecture - make header/footer configurable positions, footer as array, add defaultPosition fallback, add tests, update docs

This commit is contained in:
saberzero1
2026-07-27 17:32:40 +02:00
parent e37b4888f3
commit a121fd2e96
20 changed files with 1180 additions and 57 deletions
+3 -3
View File
@@ -412,13 +412,13 @@ export const MyFrame: PageFrame = {
grid-template-areas: "center";
}
`,
render({ componentData, pageBody: Content, footer: Footer }: PageFrameProps): unknown {
render({ componentData, pageBody: Content, footer: Footers }: PageFrameProps): unknown {
const renderSlot = (C: (props: typeof componentData) => unknown): ComponentChildren =>
C(componentData) as ComponentChildren
return (
<div class="center">
{(Content as any)(componentData)}
{(Footer as any)(componentData)}
{Footers.map((Footer) => (Footer as any)(componentData))}
</div>
)
},
@@ -428,7 +428,7 @@ export const MyFrame: PageFrame = {
Key requirements:
- `name`: A unique string identifier. This is what page types and YAML config reference.
- `render()`: Receives all layout slots (header, sidebars, content, footer) and returns JSX for the inner page structure.
- `render()`: Receives all layout slots (header, sidebars, content, footer) and returns JSX for the inner page structure. Note that `footer` is a `QuartzComponent[]` (an array) — frames should iterate over it with `.map()` to render all footer components.
- `css` (optional): Frame-specific CSS. Scope it with `.page[data-frame="my-frame"]` selectors to avoid conflicts.
**2. Re-export the frame:**
+36
View File
@@ -28,6 +28,42 @@ npx quartz plugin install --latest
See the [[upgrade|CLI reference for upgrade]] for more details on available flags.
### Layout System Changes
The `footer` layout slot is now an array of components, consistent with other layout slots like `header`, `left`, and `right`. Additionally, `header` and `footer` are now configurable layout positions — plugins can declare `layout: { position: header }` or `layout: { position: footer }` in their YAML config.
**If you override layouts in `quartz.ts`**, update any `footer` assignments to use arrays:
```ts title="quartz.ts"
// Before
export const layout = await loadQuartzLayout({
defaults: { footer: MyFooterComponent },
})
// After
export const layout = await loadQuartzLayout({
defaults: { footer: [MyFooterComponent] },
})
```
**If you have a custom page frame**, update the `render` function to iterate the footer array:
```tsx
// Before
render({ footer: Footer, ...rest }: PageFrameProps) {
return <Footer {...componentData} />
}
// After
render({ footer, ...rest }: PageFrameProps) {
return footer.map((F) => <F {...componentData} />)
}
```
Both changes are caught by TypeScript at compile time — running `npx quartz build` will show the error.
No changes are needed for `quartz.config.yaml` — the YAML format is unchanged.
### Cleaning Up Unused Plugins
If you've removed plugins from your configuration during an upgrade, you can clean up the leftover files:
+10 -2
View File
@@ -20,7 +20,7 @@ export interface FullPageLayout {
afterBody: QuartzComponent[] // laid out vertically
left: QuartzComponent[] // vertical on desktop and tablet, horizontal on mobile
right: QuartzComponent[] // vertical on desktop, horizontal on tablet and mobile
footer: QuartzComponent // single component
footer: QuartzComponent[] // laid out vertically
}
```
@@ -36,7 +36,7 @@ These correspond to following parts of the page:
> There are two additional layout fields that are _not_ shown in the above diagram.
>
> 1. `head` is a single component that renders the `<head>` [tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head) in the HTML. This doesn't appear visually on the page and is only is responsible for metadata about the document like the tab title, scripts, and styles.
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. This enables you to replicate the old Quartz 3 header bar where the title, search bar, and dark mode toggle. By default, Quartz doesn't place any components in the `header`.
> 2. `header` is a set of components that are laid out horizontally and appears _before_ the `beforeBody` section. You can place components in the header by setting `layout.position: header` in your plugin configuration. This enables layouts similar to Quartz 3's header bar with title, search bar, and dark mode toggle.
Layout components are configured in the `layout` section of `quartz.config.yaml`. Plugins declare their position and priority, and the layout system arranges them automatically:
@@ -77,12 +77,20 @@ plugins:
layout:
position: beforeBody
priority: 30
- source: github:quartz-community/darkmode
enabled: true
layout:
position: header
priority: 10
- source: github:quartz-community/footer
enabled: true
options:
links:
GitHub: https://github.com/jackyzha0/quartz
Discord Community: https://discord.gg/cRFFHYye7t
layout:
position: footer
priority: 50
layout:
groups: