WordPress 有「頁面範本」——編輯器裡的下拉選單可為每頁選擇版面(例如 Default、Full Width、Landing Page)。EmDash 以 select 欄位支援相同模式。
運作方式
- 在
pages集合新增 slug 為template的select欄位 - 為每個選項建立版面元件
- 在頁面路由將欄位值對應到版面
不需要額外系統——沿用 EmDash 的 select 欄位與 Astro 的元件模型。
新增欄位
在管理後台為 pages 集合新增 slug 為 template 的 select 欄位與版面選項(例如「Default」「Full Width」)。或寫入 seed 資料:
{
"slug": "template",
"label": "Template",
"type": "select",
"validation": {
"options": ["Default", "Full Width"]
},
"defaultValue": "Default"
}
建立版面元件
每種版面在基礎版面中包住內容並使用不同樣式:
---
import type { ContentEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "./Base.astro";
interface Props {
page: ContentEntry<any>;
}
const { page } = Astro.props;
---
<Base title={page.data.title}>
<article class="page-default">
<h1>{page.data.title}</h1>
<PortableText value={page.data.content} />
</article>
</Base>
<style>
.page-default {
max-width: var(--content-width);
margin: 0 auto;
padding: 2rem 1rem;
}
</style>
---
import type { ContentEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "./Base.astro";
interface Props {
page: ContentEntry<any>;
}
const { page } = Astro.props;
---
<Base title={page.data.title}>
<article class="page-wide">
<h1>{page.data.title}</h1>
<PortableText value={page.data.content} />
</article>
</Base>
<style>
.page-wide {
max-width: var(--wide-width);
margin: 0 auto;
padding: 2rem 1rem;
}
</style>
接上路由
在頁面路由匯入各版面並對應範本值:
---
import { getEmDashEntry } from "emdash";
import PageDefault from "../../layouts/PageDefault.astro";
import PageFullWidth from "../../layouts/PageFullWidth.astro";
const { slug } = Astro.params;
if (!slug) {
return Astro.redirect("/404");
}
const { entry: page } = await getEmDashEntry("pages", slug);
if (!page) {
return Astro.redirect("/404");
}
const layouts = {
"Default": PageDefault,
"Full Width": PageFullWidth,
};
const Layout = layouts[page.data.template as keyof typeof layouts] ?? PageDefault;
---
<Layout page={page} />
路由保持精簡。每個版面元件自有標記與樣式。新增版面:建立元件、在 select 加選項、在對應表加一行。
新增更多版面
WordPress 主題常見選項:
- Default — 窄內容欄,適合閱讀
- Full Width — 較寬內容區,無側欄
- Landing Page — 無頁首/頁尾,適合 hero 區塊
- Sidebar — 含側欄小工具區的內容
每一種只是在 src/layouts/ 多一個 Astro 元件,並在路由的版面對應表多一筆。