# 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> { 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
``` 不要给一个公共 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; 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 ? : 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. 未知或不兼容板块不能在生产构建中静默消失。 按“统一协议、独立渲染、有限配置、严格校验”实现,既能保留每个网站的设计自由度,也能让后续内容维护和新站迁移真正复用同一套系统。