Files
cms-website/SiteForge_主题与板块设计方案_V1.0.md
T
浅念 d60123ba41 docs: SiteForge 规划文档基线 + 纵向切片设计规格 V1
- V3.0 总体方案、主题与板块设计、实施计划
- cms 现状差距分析 V2.0(V1.0 已标注作废)与复用评估 V1.0
- 纵向切片设计规格(路线 C:全新架构 + 白名单资产移植)
- .gitignore 先行(storage/artifacts/env 永不入库)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-20 16:10:34 +08:00

901 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SiteForge 主题与板块设计方案
> 版本:V1.0
> 日期:2026-10-20
> 目标:支持每个网站拥有独立设计,同时让内容可以在后台结构化编辑并生成纯静态页面。
---
## 1. 设计结论
主题和板块必须解耦:
- **主题(Theme)**负责页面结构、视觉风格、HTML、CSS、动画和响应式实现。
- **板块(Block)**负责内容字段及其顺序,例如标题、图片、按钮、产品参数、FAQ。
- **模板(Template)**规定一类页面默认由哪些区域组成,以及允许使用哪些板块。
- **页面(Page)**保存所选模板和实际板块数据。
推荐模式是:
```text
统一板块数据协议 + 每个主题自己的板块渲染器
```
例如后台都保存 `hero` 数据,但汽车站可以显示全屏视频,工业站可以显示左文右图。两者共享内容语义,不共享强制布局。
V1 不做任意坐标、任意嵌套的低代码编辑器,只提供:
- 选择板块。
- 表单编辑字段。
- 调整板块顺序。
- 启用或隐藏板块。
- 选择少量经过主题声明的样式变体。
- PC/移动端静态预览。
这样既能快速维护,又不会让自由配置破坏设计、响应式和 SEO。
---
## 2. 四层结构
```mermaid
flowchart TB
CONTENT[内容:产品/文章/页面/媒体]
BLOCK[板块实例:type + data + settings]
TEMPLATE[页面模板:区域与板块约束]
THEME[主题:组件、样式、交互]
HTML[静态 HTML/CSS/JS]
CONTENT --> BLOCK
BLOCK --> TEMPLATE
TEMPLATE --> THEME
THEME --> HTML
```
### 2.1 内容层
保存可复用的业务数据,例如产品名称、参数、文章正文和媒体资源。内容不应该写死在主题代码里。
### 2.2 板块层
保存某个页面中的展示内容和顺序。板块数据尽量不包含颜色、像素、CSS 类名等主题实现细节。
### 2.3 模板层
定义首页、产品详情、新闻详情、普通页面等页面类型及允许的区域。模板可以自动插入由业务数据驱动的系统区域。
### 2.4 主题层
每个主题提供自己的 Astro 页面、组件、样式和板块渲染器,最终生成静态文件。
---
## 3. 板块分类
### 3.1 全局板块
全站复用,单独管理:
- Header
- Footer
- 顶部通知条
- 全局询价 CTA
- 联系方式
- 社交媒体链接
- Cookie/隐私提示
修改全局板块后,会重建所有引用它的页面;V1 可以直接触发该站全量构建。
### 3.2 页面内容板块
由管理员在页面中新增、排序和编辑:
- Hero
- Rich Text
- Image + Text
- Image Gallery
- Video
- Feature List
- Statistics
- Logo/Brand List
- Product Grid
- Article List
- Specification Table
- Download List
- FAQ
- Testimonials
- CTA
- Contact Information
- Map Embed
### 3.3 模板系统板块
由模板根据当前内容自动生成,通常不允许页面编辑者删除:
- 面包屑
- 产品主信息
- 产品参数
- 文章标题、日期和正文
- 分类列表与分页
- 相关推荐
- SEO Head
管理员可以在允许范围内控制显示、顺序或样式变体,但不直接维护其核心业务数据。
### 3.4 站点专属板块
某些页面效果只属于一个站点,可以由主题声明自定义板块,例如:
```text
vehicle-360-view
charging-calculator
factory-process-timeline
dealer-map
```
站点专属板块仍需提供数据 schema 和后台表单定义,不能只在代码中写死内容。
### 3.5 Legacy HTML 板块
用于暂时无法结构化的历史内容:
- 只接受清洗后的 HTML。
- 删除脚本、事件属性和危险 URL。
- 使用隔离样式容器。
- 后台醒目标记为“待结构化”。
- 不能作为新页面的默认编辑方式。
---
## 4. 板块数据协议
### 4.1 板块实例
```ts
export interface BlockInstance<TData = Record<string, unknown>> {
id: string;
type: string;
schemaVersion: number;
variant?: string;
data: TData;
settings?: {
anchorId?: string;
themeMode?: 'default' | 'light' | 'dark';
spacing?: 'none' | 'small' | 'medium' | 'large';
};
visibility: {
enabled: boolean;
locales?: string[];
};
}
```
### 4.2 页面内容示例
```json
{
"contentId": "page_home",
"templateKey": "home",
"blocks": [
{
"id": "block_hero_01",
"type": "hero",
"schemaVersion": 1,
"variant": "image-right",
"data": {
"eyebrow": "New Energy Vehicles",
"title": "Build Your Next Journey",
"description": "A short introduction.",
"mediaId": "asset_1001",
"primaryAction": {
"label": "View Products",
"href": "/products/"
}
},
"settings": {
"spacing": "large",
"themeMode": "dark"
},
"visibility": {
"enabled": true
}
}
]
}
```
### 4.3 内容和样式边界
建议保存在板块数据中的字段:
- 标题、描述和按钮文案。
- 媒体资源引用。
- 内部/外部链接。
- 产品、文章、分类等内容引用。
- 允许的语义变体,例如 `featured`、`compact`。
不建议保存:
- 任意 CSS。
- Tailwind/CSS 类名。
- 像素坐标。
- 随意输入的颜色值。
- 主题组件文件路径。
- 可执行 JavaScript。
颜色、字体和间距默认由主题控制。如果确实需要运营配置,只允许主题 manifest 中声明的有限选项。
---
## 5. 板块定义与表单生成
每个板块类型包含两份声明:
1. `schema`:数据校验规则。
2. `uiSchema`:后台如何展示编辑表单。
### 5.1 Hero Schema 示例
```json
{
"$id": "siteforge://blocks/hero/v1",
"type": "object",
"required": ["title"],
"properties": {
"eyebrow": { "type": "string", "maxLength": 80 },
"title": { "type": "string", "minLength": 1, "maxLength": 160 },
"description": { "type": "string", "maxLength": 500 },
"mediaId": { "type": "string" },
"primaryAction": {
"type": "object",
"properties": {
"label": { "type": "string", "maxLength": 40 },
"href": { "type": "string" }
},
"required": ["label", "href"]
}
},
"additionalProperties": false
}
```
### 5.2 UI Schema 示例
```json
{
"title": { "widget": "text", "label": "主标题" },
"description": { "widget": "textarea", "label": "说明" },
"mediaId": { "widget": "media-picker", "label": "主视觉" },
"primaryAction.href": { "widget": "link-picker", "label": "按钮链接" }
}
```
管理后台根据这些声明生成表单,不需要为每个主题重复开发一套内容编辑页面。
推荐使用 JSON Schema 作为跨前后端协议,并使用 Ajv 校验。主题内可以生成对应 TypeScript 类型,避免重复维护接口。
---
## 6. 主题协议
### 6.1 主题清单
```json
{
"id": "automotive-premium",
"name": "Automotive Premium",
"version": "1.0.0",
"engine": "astro",
"siteConfigSchema": "./schemas/site-config.schema.json",
"templates": {
"home": {
"entry": "src/templates/HomePage.astro",
"allowedBlocks": ["hero", "feature-list", "product-grid", "cta"],
"requiredBlocks": ["hero"],
"maxPerType": { "hero": 1 }
},
"product": {
"entry": "src/templates/ProductDetail.astro",
"allowedBlocks": ["gallery", "specification-table", "download-list", "faq", "cta"]
},
"page": {
"entry": "src/templates/GenericPage.astro",
"allowedBlocks": ["hero", "rich-text", "image-text", "gallery", "faq", "cta"]
}
},
"blocks": {
"hero": {
"renderer": "src/blocks/HeroBlock.astro",
"schema": "siteforge://blocks/hero/v1",
"variants": ["fullscreen", "image-right", "minimal"]
},
"product-grid": {
"renderer": "src/blocks/ProductGridBlock.astro",
"schema": "siteforge://blocks/product-grid/v1",
"variants": ["cards", "editorial"]
}
}
}
```
### 6.2 主题目录
```text
themes/automotive-premium/
theme.json
schemas/
site-config.schema.json
src/
templates/
HomePage.astro
ProductDetail.astro
ArticleDetail.astro
GenericPage.astro
blocks/
HeroBlock.astro
RichTextBlock.astro
ProductGridBlock.astro
FaqBlock.astro
components/
Header.astro
Footer.astro
Breadcrumb.astro
layouts/
BaseLayout.astro
styles/
tokens.css
global.css
lib/
block-renderers.ts
public/
```
### 6.3 不使用主题继承
V1 不建议建立复杂的父主题/子主题覆盖机制。公共能力通过普通包复用:
```text
packages/theme-runtime
packages/seo-components
packages/block-contracts
packages/media-components
```
每个主题仍然明确拥有自己的模板和 CSS。这样升级公共包时更可控,也避免多层覆盖难以追踪。
### 6.4 四层组件化复用架构
为了提高新主题和新网站的开发速度,组件按复用程度分为四层:
```mermaid
flowchart TB
C1[第一层:数据契约与工具]
C2[第二层:无样式基础组件]
C3[第三层:业务逻辑与 Headless 组件]
C4[第四层:主题展示组件]
PAGE[页面模板]
C1 --> C2
C1 --> C3
C2 --> C4
C3 --> C4
C4 --> PAGE
```
#### 第一层:数据契约与工具,完全复用
- Block、Page、Media、Menu、SEO 类型。
- JSON Schema 和数据验证。
- 内部链接解析。
- 图片地址、`srcset` 和尺寸计算。
- URL、Canonical、Hreflang 和结构化数据生成。
- HTML 净化、日期格式化和多语言工具。
这一层不包含任何主题样式。
#### 第二层:无样式基础组件,高度复用
- Container
- Grid
- Stack
- Media
- Picture
- Link
- Button 基础行为
- Dialog
- Accordion
- Tabs
- Carousel 控制逻辑
- Pagination
组件提供语义、可访问性和交互状态,不固定颜色、字体和视觉效果。主题通过 CSS、自定义属性和组合方式决定最终外观。
#### 第三层:业务逻辑与 Headless 组件,高度复用
- 产品列表查询与分页。
- 文章列表查询。
- 产品参数分组。
- 菜单树解析。
- 面包屑生成。
- FAQ 展开状态。
- 表单校验和提交状态。
- 搜索数据适配。
- 相关推荐规则。
这类组件输出数据或状态,不直接决定最终 DOM 结构。例如 `createProductGridModel()` 负责得到产品卡片数据,汽车主题和工业主题分别决定如何渲染卡片。
#### 第四层:主题展示组件,按主题独立
- Header、Footer、Mega Menu。
- Hero 的具体布局。
- Product Card 的视觉结构。
- 首页各板块的组合方式。
- 动画、颜色、字体和响应式细节。
这一层允许完全不同,避免为了复用而把所有网站做成同一种风格。
### 6.5 公共组件包结构
```text
packages/
content-contracts/ # Page、Block、Product、Post 等类型
block-contracts/ # 板块 schema、版本和迁移
theme-runtime/ # 主题加载、模板解析、渲染上下文
ui-primitives/ # 无样式基础组件
headless-components/ # 菜单、分页、Tabs、Accordion 等逻辑
content-resolvers/ # 产品/文章/分类引用解析
media-components/ # Picture、Video、资源地址与 srcset
seo-components/ # Meta、Canonical、Hreflang、JSON-LD
form-runtime/ # 表单 schema、校验和提交适配
design-tokens/ # 公共 token 协议,不存具体品牌值
```
主题只引用公共包的正式入口,不能跨主题引用另一个主题内部文件。
```text
允许:theme-a → packages/ui-primitives
禁止:theme-a → themes/theme-b/src/components/ProductCard.astro
```
如果多个主题确实重复使用一个展示组件,应先将其中的通用行为和结构抽到公共包,再由各主题提供外观;不要直接复制后形成多个无法同步的版本。
### 6.6 设计令牌
公共组件只使用语义化 token,不使用某个网站的品牌颜色:
```css
:root {
--sf-color-primary: #1f4b7a;
--sf-color-accent: #e8792e;
--sf-color-text: #1b1f24;
--sf-color-surface: #ffffff;
--sf-radius-control: 0.5rem;
--sf-space-section: clamp(4rem, 8vw, 8rem);
--sf-container-width: 75rem;
}
```
每个主题覆盖这些 token,也可以增加自己的 token。公共包不得依赖只有某个主题才存在的 token。
### 6.7 组合优于大量 Variant
公共组件保持小而稳定,通过组合形成页面板块:
```astro
<Section>
<Container>
<SplitLayout>
<HeroContent data={block.data} />
<ThemeHeroMedia media={media} />
</SplitLayout>
</Container>
</Section>
```
不要给一个公共 Hero 增加几十个布尔属性来适应所有网站,例如 `rounded`、`centered`、`overlay`、`video`、`reverse`、`compact` 的任意组合。稳定的数据协议可以复用,最终板块应由主题组合基础组件实现。
### 6.8 组件复用矩阵
| 能力 | 公共包复用 | 主题独立 |
|---|---:|---:|
| 数据类型与 Schema | 是 | 否 |
| SEO Head | 是 | 可提供少量站点配置 |
| Picture/srcset | 是 | 可控制画面比例和样式 |
| 菜单树和展开逻辑 | 是 | Header 结构和动画独立 |
| 产品查询与分页 | 是 | 产品卡片独立 |
| FAQ 数据与交互状态 | 是 | 排版和图标独立 |
| 表单校验与提交 | 是 | 字段布局和视觉独立 |
| Hero 内容协议 | 是 | Hero 渲染完全独立 |
| 页面模板 | 否 | 是 |
| 品牌色、字体、间距 | 仅协议 | 是 |
### 6.9 组件版本与兼容
- 公共包遵循语义化版本。
- 破坏性变更必须提供迁移说明或兼容适配层。
- 主题 manifest 记录公共运行时的兼容范围。
- 每个公共组件提供最小、完整、异常三个测试 fixture。
- 公共组件升级后,自动构建所有示范主题并执行截图回归。
- 发布 release 锁定公共包和主题版本,回滚时不能自动升级依赖。
### 6.10 组件预览与文档
建立独立的组件预览页,展示:
- 基础组件的状态和可访问性。
- 每种板块的最小/完整数据。
- 同一板块在不同主题中的效果。
- 桌面、平板和手机断点。
- 空数据、超长标题、图片缺失等异常状态。
预览页可以采用 Storybook 或项目内 Astro 组件目录。V1 的重点是可查看和自动截图,不强制依赖某个文档工具。
---
## 7. 模板约束
模板除了渲染页面,还负责约束后台可配置范围。
```ts
export interface TemplateDefinition {
key: string;
contentTypes: string[];
allowedBlocks: string[];
requiredBlocks?: string[];
maxPerType?: Record<string, number>;
lockedRegions?: string[];
}
```
示例:
- 首页必须有一个 Hero,最多一个。
- 产品详情固定显示产品标题、价格/询价入口和核心参数。
- FAQ、下载、CTA 可以由管理员添加、删除和排序。
- SEO Head、Header、Footer 是锁定区域,不出现在自由排序列表里。
后台新增板块时,只显示当前主题、当前模板支持的类型和变体。
---
## 8. 数据库存储
推荐将板块实例按修订版本独立存储,而不是直接写入已发布页面。
```sql
CREATE TABLE page_blocks (
id UUID PRIMARY KEY,
site_id UUID NOT NULL REFERENCES sites(id),
revision_id UUID NOT NULL REFERENCES content_revisions(id),
block_type TEXT NOT NULL,
schema_version INTEGER NOT NULL,
variant TEXT,
position INTEGER NOT NULL,
data JSONB NOT NULL DEFAULT '{}'::jsonb,
settings JSONB NOT NULL DEFAULT '{}'::jsonb,
visibility JSONB NOT NULL DEFAULT '{"enabled":true}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_page_blocks_revision_position
ON page_blocks(revision_id, position);
```
全局板块可以使用:
```text
global_fragments
global_fragment_revisions
global_fragment_usages
```
发布时锁定内容修订和全局板块修订,确保历史 release 可以准确回滚。
---
## 9. 后台编辑体验
### 9.1 页面编辑器布局
```text
┌────────────────────────────────────────────────────────────┐
│ 页面标题 / URL / 模板 / 保存 / 预览 / 发布 │
├──────────────────────┬─────────────────────────────────────┤
│ 板块列表 │ 当前板块表单 │
│ │ │
│ 1. Hero │ 标题 [________________] │
│ 2. Product Grid │ 描述 [________________] │
│ 3. FAQ │ 图片 [选择媒体] │
│ 4. CTA │ 样式变体 [image-right ▼] │
│ │ │
│ [+ 添加板块] │ │
└──────────────────────┴─────────────────────────────────────┘
```
首版功能:
- 点击新增板块。
- 拖动调整纵向顺序。
- 复制、隐藏和删除板块。
- 编辑结构化字段。
- 从媒体库、产品、文章和内部路由中选择引用。
- 保存草稿。
- 创建静态预览。
- 显示字段和模板校验错误。
### 9.2 不在 V1 实现
- 画布上任意拖动位置。
- 任意列宽和像素级布局。
- 无限层级嵌套板块。
- 管理员输入 CSS/JavaScript。
- 在一个主题中自由调用另一个主题的组件。
---
## 10. Astro 渲染实现
### 10.1 渲染器注册
```ts
import HeroBlock from '../blocks/HeroBlock.astro';
import RichTextBlock from '../blocks/RichTextBlock.astro';
import ProductGridBlock from '../blocks/ProductGridBlock.astro';
export const blockRenderers = {
hero: HeroBlock,
'rich-text': RichTextBlock,
'product-grid': ProductGridBlock,
} as const;
```
### 10.2 页面循环
```astro
---
import { blockRenderers } from '../lib/block-renderers';
const { page } = Astro.props;
const blocks = page.blocks.filter((block) => block.visibility.enabled);
---
{blocks.map((block) => {
const Renderer = blockRenderers[block.type];
return Renderer
? <Renderer block={block} page={page} />
: null;
})}
```
实际构建前必须已经验证所有板块类型。生产构建发现未知板块时应失败,不能静默生成空白区域;后台预览可以显示“当前主题不支持该板块”的占位提示。
### 10.3 数据解析顺序
```text
读取发布快照
→ 获取页面与内容引用
→ 获取模板定义
→ 验证允许的板块和数量
→ 按 schema 校验每个板块
→ 解析媒体与内部链接
→ 选择主题渲染器
→ 生成 HTML
→ 执行 SEO/链接/资源验收
```
### 10.4 客户端 JavaScript
Astro 默认输出静态 HTML。只有轮播、菜单、筛选等确需交互的组件才使用客户端 hydration,并选择合适的加载策略。普通文本、产品参数和 FAQ 不应无条件加载完整前端框架。
---
## 11. 主题切换策略
### 11.1 可以直接切换的条件
- 新主题支持当前页面模板。
- 新主题支持页面使用的全部板块类型。
- 每个板块的 schema 版本兼容。
- 主题所需站点配置完整。
### 11.2 切换前检查
系统先生成兼容报告:
```text
支持的模板
缺失的板块渲染器
不支持的 variant
缺失的站点配置
需要迁移的数据版本
```
存在不支持板块时,不允许直接用于生产构建。可以:
- 为新主题增加渲染器。
- 将板块转换为兼容类型。
- 由管理员明确删除或替换。
### 11.3 主题切换不是主要目标
平台需要支持主题版本升级和兼容检查,但不必把“任何网站一键换任意主题”作为 V1 目标。不同网站设计差异很大,强行互换会让板块协议变得臃肿。
---
## 12. 板块版本与数据迁移
板块必须携带 `schemaVersion`。
```ts
type BlockMigration = {
blockType: string;
fromVersion: number;
toVersion: number;
migrate: (oldData: unknown) => unknown;
};
```
例如 Hero V2 将 `buttonText` 和 `buttonUrl` 合并为 `primaryAction`:
```text
v1 data
→ 运行纯函数迁移
→ v2 data
→ schema 校验
→ 生成新的内容修订
```
禁止直接批量覆盖已发布修订。迁移失败的板块进入人工处理列表,旧版本数据继续保留。
---
## 13. API 建议
```text
GET /api/v1/themes
GET /api/v1/themes/:themeId/manifest
GET /api/v1/sites/:siteId/theme
PUT /api/v1/sites/:siteId/theme
GET /api/v1/sites/:siteId/pages/:pageId/blocks
POST /api/v1/sites/:siteId/pages/:pageId/blocks
PATCH /api/v1/sites/:siteId/pages/:pageId/blocks/:blockId
DELETE /api/v1/sites/:siteId/pages/:pageId/blocks/:blockId
POST /api/v1/sites/:siteId/pages/:pageId/blocks/reorder
POST /api/v1/sites/:siteId/pages/:pageId/validate
POST /api/v1/sites/:siteId/pages/:pageId/preview
GET /api/v1/sites/:siteId/fragments
POST /api/v1/sites/:siteId/fragments
PATCH /api/v1/sites/:siteId/fragments/:fragmentId
```
后端负责验证模板、板块类型、schema、variant、媒体和内部链接;不能只在管理后台进行校验。
---
## 14. 测试策略
### 14.1 契约测试
- 每个主题 manifest 格式正确。
- 模板引用的板块都有渲染器。
- 板块数据能通过对应 schema。
- 主题声明的 variant 都能渲染。
- 必需板块和最大数量约束有效。
### 14.2 渲染测试
- 每个模板至少有一份标准 fixture。
- 每个板块测试最少字段、完整字段和异常字段。
- 生成 HTML 不包含预览域名、危险脚本和无效资源。
- 核心内容在输出 HTML 中真实存在,而非仅客户端加载。
### 14.3 视觉测试
- 为首页、产品详情、文章详情和普通页面生成桌面/移动截图。
- 主题版本变化时对比关键页面。
- 视觉差异由超级管理员确认后才能用于生产发布。
### 14.4 性能与可访问性
- 图片包含宽高并使用合适尺寸。
- 交互组件按需加载。
- 标题层级、链接、按钮和表单具有正确语义。
- 颜色对比、键盘操作和焦点状态在主题验收中检查。
---
## 15. V1 实现顺序
### Sprint 1:契约和最小渲染
- 建立 `block-contracts`。
- 建立 `ui-primitives`、`theme-runtime` 和 `content-resolvers` 的最小公共包。
- 定义 Hero、Rich Text、Image Text、Gallery、CTA、FAQ 六个基础板块。
- 建立主题 manifest 和模板协议。
- 使用固定 JSON 生成一个静态首页。
### Sprint 2:数据库和后台编辑
- 建立 `page_blocks` 和内容修订。
- 根据 schema 生成表单。
- 支持新增、编辑、删除、排序和隐藏。
- 支持媒体和内部链接选择。
### Sprint 3:主题与预览
- 完成第一套主题的首页、普通页面、产品详情和文章详情。
- 建立预览构建。
- 增加模板与板块兼容检查。
### Sprint 4:第二主题验证
- 使用相同基础板块数据开发视觉完全不同的第二主题。
- 验证哪些字段真正通用,哪些需要站点专属板块。
- 将两个主题中重复的非视觉逻辑提取到公共组件包。
- 固化主题 SDK、测试 fixture 和开发文档。
### Sprint 5:生产质量
- 板块版本迁移。
- 全局板块。
- 视觉回归、可访问性和性能检查。
- 与发布门禁和不可变 release 集成。
---
## 16. 首版基础板块清单
建议首版只实现以下 12 个,真实试点需要后再增加:
| 板块 | 核心字段 |
|---|---|
| Hero | eyebrow、title、description、media、actions |
| Rich Text | content |
| Image Text | title、content、media、mediaPosition、action |
| Gallery | title、items |
| Feature List | title、items、icon/media |
| Statistics | title、items(value/label) |
| Product Grid | title、productRefs/query、limit、action |
| Article List | title、category/query、limit、action |
| Specification Table | title、groups/rows 或 product field binding |
| Download List | title、assetRefs |
| FAQ | title、items(question/answer) |
| CTA | title、description、media、actions |
Header、Footer、Breadcrumb、产品主信息和文章主内容作为全局/模板系统组件单独实现,不计入可自由添加板块。
---
## 17. 开发验收标准
主题与板块模块达到以下条件即可视为 V1 完成:
1. 超级管理员能为页面选择模板。
2. 能新增、编辑、排序、隐藏和删除模板允许的板块。
3. 后台字段由 schema 驱动,并在前后端双重验证。
4. 相同板块数据能被两套主题渲染成明显不同的设计。
5. 主题不支持某板块时,生产构建会被阻止并给出明确错误。
6. 产品详情和文章详情能混合系统板块与可配置板块。
7. 全局 Header/Footer 修改后能够重新构建站点。
8. 所有发布版本锁定主题版本和板块修订,可准确回滚。
9. 页面输出为静态 HTML,核心内容无需 JavaScript 即可读取。
10. 主题和板块变更进入现有 URL、SEO、内容和视觉发布门禁。
11. 两套主题复用相同的数据契约、媒体、SEO 和 Headless 逻辑,但最终页面视觉明显不同。
---
## 18. 最终建议
首版主题系统的重点不是“让管理员设计网页”,而是让开发者能够快速制作不同主题,让管理员安全地维护结构化内容。
必须守住三个边界:
1. 内容数据中不写 CSS 和组件路径。
2. 主题不能自己决定历史 URL 和 SEO。
3. 未知或不兼容板块不能在生产构建中静默消失。
按“统一协议、独立渲染、有限配置、严格校验”实现,既能保留每个网站的设计自由度,也能让后续内容维护和新站迁移真正复用同一套系统。