Runtime
Slides 架構
簡報 Press 的結構方式:Press marker、folder-per-slide、template registry、core objects,以及穩定的 object identity。
OpenPress 的簡報架構刻意把「deck 順序」、「每張 slide 的 source」、「可複製 template」與「theme CSS」分開。這讓 slide style 可以被移植成 package,也讓 Agent 可以針對單張投影片工作,而不用修改一個巨大的簡報檔。
Press 只描述順序
press/<slug>/press.tsx 是 deck 的索引。它用 <Slide id="..." /> 註冊播放順序,不應承載每一頁的實際 layout。
import { Press, Slide } from "@open-press/core";
export default function SlidePress() {
return (
<Press slug="slide" title="Deck Title" type="slides" page="slide-16-9">
<Slide id="cover" />
<Slide id="agenda" />
</Press>
);
}
每張 slide 是獨立 source
每一張投影片位於 press/<slug>/slides/<id>/slide.tsx。這個檔案是實際畫面 source,通常由 Slide、Frame、Text、Line、MediaObject 等 core objects 組成。
Folder-per-slide 的好處仍然成立:
- Agent 可以只改一張 slide,不需要理解整份 deck。
- Git diff 與版本回溯較清楚。
- Workbench 的新增、刪除、跳過 slide 可以對應到明確的 source folder。
Template registry 是移植邊界
press/<slug>/slide-style/manifest.json 註冊可用 template。新增 slide 時,CLI 或 Workbench 會從 slide-style/templates/<template>/ 複製檔案到新的 slides/<id>/。
這個邊界很重要:style package 可以帶著 templates 與 theme 走,而 deck 本身只保存已生成的 slide source。
Object identity 由 primitives 表達
可編輯物件不應藏在大型 compound wrapper 的 props 裡。Template 應直接使用 core objects:
Frame使用frameKey作為 identity。Text、Line、MediaObject在 template 中應提供穩定label。- 固定座標使用
box,16:9 slide 的基準是 1920 x 1080。 - 彈性排列使用
Frame layout。 - 字體、顏色、間距與特殊效果放在 theme CSS。
引擎會根據這些 primitives 產生完整 locator,供 Workbench 的 inline editing、comments、thumbnail 與 preview 使用。作者與 Agent 的責任是提供穩定、可讀、可移植的局部 ID 與清楚的 source 結構。
更多細節請參考 Core Object API。