Skip to content

制作自定义主题(供 AI 参考) ​

本文说明 WonderPen 桌面版自定义主题的文件结构、配置字段与 CSS 编写方式,供 AI 根据用户需求生成可导入的 .wptheme 文件,也适用于手工制作主题。应用内的主题操作见主题。

制作主题时,先确定明暗风格、主要配色、背景图片和正文阅读样式,再生成配置与 CSS,打包后在 WonderPen 中检查实际效果。主题 CSS 主要控制应用界面;导出文档的样式需要通过自定义 CSS另行设置。

主题包结构 ​

.wptheme 是扩展名经过修改的 ZIP 压缩包,推荐采用以下扁平结构:

text
我的主题.wptheme
├── config.json
├── style.css
└── background.jpg
  • config.json:必需,定义主题身份、名称、基础主题和默认设置。
  • style.css:可选,定义自定义样式。
  • background.jpg:可选,主题使用的背景图片,文件名与格式可以不同。

这些文件直接放在压缩包根目录,不要再套一层文件夹,也不要把图片放进子目录;当前导入逻辑不会为包内文件创建子目录。config.json 与 style.css 使用 UTF-8 编码。只打包实际使用的文件,不包含本机设置、临时文件、旧图片或 __MACOSX 等系统生成的目录。不需要 HTML、JavaScript 或构建工具。

配置文件 ​

config.json 使用标准 JSON,不支持注释或末尾多余的逗号。下面的配置可以与后文的基础 CSS 示例一起使用:

json
{
  "id": "lake-light-6b6f66d3-604c-4c22-8537-22ba2a2723fa",
  "title": {
    "zh": "湖光",
    "en": "Lake Light"
  },
  "theme_mode": "light",
  "base_style": "light",
  "bg_color": "#eef4f1",
  "bd_color": "rgba(38, 59, 53, 0.12)",
  "settings": {
    "font_family": [],
    "editor_font_family": [],
    "editor_font_size": 18,
    "editor_font_color": "auto",
    "editor_width": 720,
    "editor_line_height": 1.8,
    "editor_paragraph_spacing": 0,
    "editor_page_padding_h": 48,
    "editor_page_padding_v": 30,
    "editor_background_opacity": 1,
    "editor_line_bg_show": false
  }
}

生成新主题时,应为 id 生成新的唯一值,不要直接复制示例 ID。

核心字段 ​

字段类型是否必选说明
id字符串是主题唯一标识
title字符串或对象是非空主题名称;多语言对象可包含 en、zh、zh_tw
theme_mode字符串否,建议明确填写"light" 或 "dark",应与实际样式保持一致;实际明暗判断见下文
base_style字符串否要继承的内置主题标识;省略或空字符串表示不继承
background_image字符串否包内背景图片文件名,例如 "background.jpg";使用主题背景图时填写
background_image_blur数字否背景模糊半径,单位 px;当前设置界面范围为 0~50
background_overlay_bg字符串否背景叠加层,通常使用带透明度的 CSS 颜色
settings对象否主题默认使用的界面字体与编辑器设置
bg_color字符串否,建议填写主题列表预览使用的背景颜色
bd_color字符串否,建议填写主题列表预览使用的边框颜色

title 可以直接写成 "湖光";使用多语言对象时,建议至少提供非空的 en 作为回退名称,并按需添加 zh、zh_tw。表中的“必选”指制作可正常显示、编辑和分发的主题包所需的字段;导入器并不会完整校验所有字段,不能把导入成功当作配置完全有效。

bg_color 和 bd_color 不负责设置实际界面配色,都应填写具体颜色值,不能填写完整边框或依赖主题内变量的 var(...)。直接生成主题包时,建议像示例一样提供这两个值,让主题列表显示相应配色;导入时不会自动从 CSS 计算它们。应用在主题编辑器中保存主题时会尝试根据 CSS 更新预览,但结果不等于浏览器最终计算出的颜色。

不要在分发配置中写入运行时生成的 bg_image,也不要把 CSS 重复放进 JSON;样式统一保存到 style.css。

主题 ID 与更新 ​

WonderPen 使用 id 识别主题,不依赖主题名称或 .wptheme 文件名。

  • 创建独立的新主题:生成新 ID。
  • 发布同一主题的更新:保留原 ID。
  • 希望两个变体同时存在:为它们使用不同 ID。

导入相同 ID 的主题时,WonderPen 会提示是否覆盖。确认后,新包替换原主题目录;这是整体替换,不是逐项合并,原目录中的本机主题设置也不会保留。应用不会比较版本号,也不会为相同 ID 自动保留多个版本。

ID 推荐只使用小写英文字母、数字和连字符,例如 UUID,或名称前缀加 UUID,以兼容目录名与应用生成的 CSS 类名。不要添加应用内部使用的 custom-- 前缀,也不要使用空白、路径分隔符、.、.. 或内置主题名称作为 ID。

继承基础主题 ​

base_style 指定要继承的内置主题。例如,"base_style": "light" 表示以明亮主题为基础。

WonderPen 会先加载该基础主题的样式,再追加 style.css。按照 CSS 层叠规则,自定义样式可以覆盖基础样式;通常只需覆盖需要修改的变量,无须复制整个内置主题。

base_style 继承的是基础主题的 CSS,不会让自定义主题拥有该内置主题的全部应用状态。例如,使用高对比度基础主题可以继承其配色与 CSS,但部分组件还根据应用的高对比度状态决定是否显示边框或特殊样式,这些效果不一定随之启用。应检查实际界面,按需用已确认的选择器补充样式,不要通过修改主题 ID 来模拟这些状态。

当前可用的内置主题如下。base_style 填写第一列的标识,不填写显示名称:

标识内置主题名描述
light明亮浅色主题,浅灰界面与白色纸面,搭配深色文字和蓝色主色。
dark夜间暗色主题,深灰黑色背景,搭配浅色文字和蓝色主色。
gray深灰暗色主题,背景比夜间更亮,以灰色为主,搭配青色主色。
dracula暗紫暗色主题,深蓝紫色背景,搭配浅色文字和紫色主色。
green浅绿浅色主题,柔和的灰绿色界面与淡绿纸面。
green2淡绿浅色主题,淡绿色界面与白色纸面,搭配绿色主色。
cyan轻蓝浅色主题,淡蓝色界面与接近白色的纸面,搭配青蓝色主色。
yellow浅黄浅色主题,暖黄色背景与纸面,搭配深棕色文字。
pink桃红浅色主题,淡粉色背景与纸面,搭配桃红色主色。
peach_fuzz柔和桃浅色主题,柔和的桃色界面与浅桃色纸面,搭配棕色文字。
light_red淡红浅色主题,接近白色的淡红背景与白色纸面,搭配橙色主色。
silver银灰浅色主题,以白色、浅灰和黑色构成简洁的中性配色。
mocha_mousse摩卡慕斯暗色主题,咖啡棕色背景与纸面,搭配暖白色文字。
mocha_light摩卡·浅色浅色主题,米色界面与暖白纸面,搭配深棕色文字。
high_contrast_light亮色高对比度浅色主题,白底黑字,边框清晰。
high_contrast_dark暗色高对比度暗色主题,黑底白字,边框清晰。
high_contrast_dark_green暗绿高对比度暗色主题,黑色背景搭配亮绿色文字与边框。
high_contrast_dark_yellow暗黄高对比度暗色主题,近黑色背景搭配亮黄色文字与边框。

不需要继承时,可以省略 base_style,或设为 ""。推荐省略;不要使用 "none",也不要填写自定义主题 ID。

不继承基础主题时,需要自行提供足够完整的主题变量,覆盖文字、背景、输入框、菜单、选中态等界面元素。通常建议从接近目标风格的基础主题开始。

theme_mode 不会自动生成配色。实际明暗判断使用 CSS 变量 --wp-dark:

css
.theme-custom {
  --wp-dark: light;
}

暗色主题使用 --wp-dark: dark。应使它与 theme_mode 及整体配色一致。

编辑器默认设置 ​

字体、字号、行高、纸面透明度等优先放在 settings 中。应用会根据这些设置生成运行时样式,直接在 CSS 中覆盖对应值容易与用户操作互相干扰。省略的设置项先使用应用默认值,再叠加本机调整和持续保持一致的设置;不会继承基础主题的本机编辑器设置。

下表是当前跟随主题应用的设置字段。不要把应用的其他设置任意加入 settings,例如 editor_letter_spacing、editor_text_align 不在此范围内;把这些字段放在配置顶层也不会使其生效。

字段值与单位
font_family界面字体名称数组
editor_font_family正文字体名称数组,主要字体在前,备选字体在后
editor_font_size字号,数字,px
editor_font_color"auto" 或 CSS 颜色
editor_width编辑器宽度,数字,px
editor_line_height行高,数字,按 em 使用
editor_paragraph_spacing段落间距,数字,按 em 使用
editor_page_padding_h水平页边距,数字,px
editor_page_padding_v垂直页边距,数字,px
editor_background_opacity纸面不透明度,0~1
editor_line_bg_show是否显示横线背景,布尔值
editor_line_bg_use_custom_color是否使用自定义横线颜色,布尔值
editor_line_bg_color横线颜色
editor_background_type"auto"、"color" 或 "image"
editor_background_color自定义背景颜色
editor_background_image运行时使用的背景图片 URL

数字不要附带单位,例如字号写 18,不要写 "18px"。没有指定字体时使用 [],不要填入 null 或无意义的空白项。字体名称不会使字体随主题安装。

editor_background_opacity 控制纸面背景:0 为完全透明,1 为完全不透明,不影响正文文字的不透明度。

建议在当前主题编辑器的输入范围内取值:字号 10~100 px,行高 0.5~4,段落间距 0~4,水平与垂直页边距 0~200 px;编辑器宽度从 400 px 起,上限与屏幕宽度有关。这些是界面提供的范围,不代表导入时会自动校验或修正超出范围的值。

主题自带图片应通过顶层 background_image 指定,由应用生成实际 URL;不要把包内文件名直接填入 settings.editor_background_image。

背景设置有额外的应用逻辑。 在没有本机背景覆盖和持续保持一致规则时,存在顶层 background_image 会把背景类型设为 image;没有该字段时会恢复为 auto,并清空背景图片 URL。因此,不能只写 settings.editor_background_type: "color" 和 editor_background_color 来制作纯色主题。纯色主题应通过 --wp-base-bg、--wp-paper-bg 和面板背景变量配色;背景图片主题使用顶层 background_image。

CSS 作用域与编写规则 ​

应用自定义主题时,WonderPen 会在 body 上添加 .theme-custom。公共主题变量应定义在这里,具体界面调整优先使用具有明确含义的 data-* 属性:

css
.theme-custom {
  --wp-primary-color: #397d75;
}

.theme-custom [data-role='editor-nav-bar'] {
  background: rgba(230, 240, 233, 0.8);
}

编写时遵循以下规则:

  • 优先覆盖已有主题变量,再按需调整具体元素。
  • 保留 .theme-custom 作用域;局部变量放在对应区域内,全局配色放在 .theme-custom 上,使菜单等浮层也能继承。
  • 优先使用已确认存在的 [data-role="..."] 和其他状态属性。
  • 避免依赖自动生成的类名、复杂 DOM 层级或未经确认的选择器。
  • 使用普通 CSS;主题 CSS 不经过 Sass 编译,不支持 Sass 变量或 mixin。
  • 默认使用展开的选择器,便于检查与维护。
  • 仅在确有需要时局部使用 !important。
  • 背景透明使用 rgba() 等颜色值,不要给整个面板设置 opacity,否则文字与按钮也会一起变淡。

CSS 可以包含渐变、伪类、伪元素、阴影、滤镜和动画。动画使用独特名称,并考虑通过 prefers-reduced-motion 关闭或减少动态效果。

data-* 属性和主题变量也可能随版本调整。需要更多选择器时,通过应用的开发者工具检查目标元素,不要自行猜测属性名称;最终以目标版本中的实际效果为准。

可覆盖的 CSS 变量 ​

下面列出常用变量。明亮与夜间主题的完整变量及默认值见内置主题样式。

用途常用变量
明暗模式--wp-dark
主色与主色上的文字--wp-primary-color、--wp-on-primary-color
主要、次要文字--wp-text-color、--wp-text-color-2
链接--wp-link-color、--wp-link-hover-color
文字高亮--wp-text-highlight-color、--wp-text-highlight-bg、--wp-text-highlight-border
基础背景及文字--wp-base-bg、--wp-on-base-bg、--wp-on-base-bg2
纸面背景--wp-paper-bg、--wp-paper-bg-alpha
输入框--wp-input-bg、--wp-input-bg-disabled
选中状态--wp-selected-bg、--wp-on-selected-bg
失焦选中状态--wp-selected-bg-blur、--wp-on-selected-bg-blur
次级选中与悬停--wp-selected-bg2、--wp-on-selected-bg2、--wp-hover-bg
普通边框颜色--wp-border-color、--wp-border-color-2、--wp-border-color-3
框架分隔线--wp-frame-border-color(完整边框定义,不是单独的颜色)
左面板--wp-left-panel-bg、--wp-left-panel-border、--wp-left-panel-backdrop-filter
中间面板--wp-main-panel-bg、--wp-main-panel-border、--wp-main-panel-backdrop-filter
右面板--wp-right-panel-bg、--wp-right-panel-border、--wp-right-panel-backdrop-filter
标题栏与状态栏--wp-title-bar-bg、--wp-status-bar-bg
备注--wp-memo-bg
弹出层--wp-popup-bg、--wp-popup-border、--wp-popup-backdrop-filter
页面叠加层与滤镜--wp-page-wrapper-bg、--wp-page-wrapper-backdrop-filter
阴影--wp-shadow、--wp-shadow-sm、--wp-shadow-lg、--wp-shadow-float
光标与焦点轮廓--wp-caret-color、--wp-focus-outline-color
滚动条--wp-scrollbar-thumb、--wp-scrollbar-thumb-hover、--wp-scrollbar-track

变量的值必须符合用途。例如,边框颜色与完整边框定义不同:

css
.theme-custom {
  --wp-border-color: rgba(38, 59, 53, 0.12);
  --wp-left-panel-border: 1px solid rgba(38, 59, 53, 0.12);
  --wp-left-panel-backdrop-filter: blur(8px);
}

--wp-paper-bg 会参与纸面颜色与透明度计算,应填写颜色,不能填写渐变或 url(...)。需要渐变时,可使用接受背景值的面板变量,或对已确认的目标元素设置 background。

改变背景色时,应同时检查对应文字颜色。例如,修改 --wp-selected-bg 后也要检查 --wp-on-selected-bg。

参考页中的 .theme-light、.theme-dark 是内置主题选择器。将其中的变量用于自定义主题时,应放入 .theme-custom。

Island 布局与边框 ​

主窗口的 island 布局用留白分隔带圆角的面板。面板之间的框架分隔线与每个 island 自身的外轮廓是两类边框,不能一起隐藏。 制作主题时应沿用内置主题的布局,只调整所需的配色:

  • --wp-frame-border-color 控制主窗口顶部工具栏下方、左右面板与中间工作区之间的框架分隔线。内置明亮主题使用 1px solid transparent;改成实色会在原有留白中额外画线。虽然名称以 color 结尾,它接受的是完整边框定义。
  • --wp-left-panel-border、--wp-main-panel-border、--wp-right-panel-border 控制面板与编辑区的外轮廓,也被导航栏、堆叠面板等组件用于必要的内部边界。应保留可见边框,按主题调整颜色;不要为了去掉框架分隔线而把它们统一设为 none 或透明。
  • --wp-border-color 等普通边框颜色还供其他组件使用,不应全局设为透明来消除某一处线条。

例如,下面保留浅青灰色的 island 外轮廓,同时让框架分隔线保持透明:

css
.theme-custom {
  --wp-frame-border-color: 1px solid transparent;
  --wp-border-color: #c7d5cc;
  --wp-left-panel-border: 1px solid var(--wp-border-color);
  --wp-main-panel-border: 1px solid var(--wp-border-color);
  --wp-right-panel-border: 1px solid var(--wp-border-color);
}

出现多余线条时,先与相近的内置主题对照,在开发者工具中确认是哪一层元素、哪个变量绘制了线条,再修正对应变量。不要给 main-page-frame、frame-body-left、frame-body-main、frame-body-right、editor-base 或导航栏等区域批量添加 border: none、border-color: transparent;这会覆盖组件本身的边框规则,并可能破坏专注模式、极简模式或浮出面板中本来需要显示的边界。

间距、圆角以及不同模式下的边框显隐由应用布局处理。没有明确的布局修改需求时,保留这些规则,不用主题 CSS 重新实现 island 布局。

底部状态栏背景 ​

普通 island 布局中,左、中、右栏底部的状态栏应融入窗口底色,不随上方的面板或导航栏铺上独立色块。要保持内置明亮主题的效果,需要同时检查以下三处:

  • 状态栏变量:--wp-status-bar-bg 由左右栏底部工具条和编辑器状态栏使用,应设为 transparent。
  • 直接样式覆盖:不要把 [data-role="editor-status-bar"] 与导航栏、标签栏一起设置实色 background。直接声明背景会绕过状态栏变量;应移除这类覆盖,让组件继续使用内置规则。左右栏对应区域为 [data-role="left-panel-bottom-bar"] 和 [data-role="right-panel-bottom-bar"],也应检查是否有类似覆盖。
  • 父容器底色:中间容器包含编辑区及底部状态栏,背景由 --wp-main-panel-bg 控制。即使状态栏自身透明,父容器的实色背景仍会透出来;需要统一窗口底色时,该变量也应设为 transparent。正文纸面颜色通过 --wp-paper-bg 设置,不要为此给整个中间容器铺色。

下面的变量配置应与移除状态栏直接背景覆盖一起使用:

css
.theme-custom {
  --wp-status-bar-bg: transparent;
  --wp-main-panel-bg: transparent;
}

这里的透明是让下层背景透出,不是固定的某个颜色。若仍有色块,应检查状态栏及其祖先元素的计算背景;不要使用整个元素的 opacity 淡化色块,也不要通过移除 island 边框来处理背景问题。没有特别的状态栏设计需求时,保留应用对专注模式、极简模式及浮动窗口的状态栏规则。

常用界面选择器 ​

选择器对应区域
[data-role="page-wrapper"]页面包装层
[data-role="main-page-frame"]主窗口框架
[data-role="frame-body-left"]左侧面板区域
[data-role="frame-body-main"]中间工作区域
[data-role="frame-body-right"]右侧面板区域
[data-role="left-panel-sidebar"]左侧纵向工具栏
[data-role="right-panel-sidebar"]右侧纵向工具栏
[data-role="editor-base"]编辑器分栏容器
[data-role="editor-prosemirror"]主正文编辑器区域,可用于限定共享编辑器的作用范围
[data-role="editor-nav-bar"]编辑器顶部导航栏
[data-role="editor-status-bar"]编辑器状态栏
[data-role="editor"]共享正文编辑器外层
[data-role="editor-paper"]正文纸面
[data-role="editor-paper-content"]正文编辑内容的挂载容器
[data-role="editor-tabs"]编辑器标签区域
[data-role="editor-tab-item"]单个编辑器标签
[data-role="tree-panel"]文档目录面板
[data-role="memo-editor"]备注编辑器

共享编辑器可能出现在多个场景。只调整主正文纸面时,可以使用 .theme-custom [data-role="editor-prosemirror"] [data-role="editor-paper"]。editor-paper-content 是挂载容器,不是编辑器的最外层;修改纸面背景、宽度或正文排版时,优先使用配置字段和主题变量。

这些属性不保证在每个窗口、每种视图中都存在。例如,主窗口框架选择器不匹配浮动窗口,纵向工具栏在横向工具栏布局中不会出现。状态栏还可能通过 portal 渲染到编辑区外,不能假定它总是 editor-base 的后代。

状态属性可以与区域选择器组合:

css
/* 当前活动标签 */
.theme-custom [data-role='editor-tab-item'][data-active='1'] {
  color: var(--wp-primary-color);
}

/* 分栏时,激活编辑器的导航栏 */
.theme-custom [data-role='editor-base'][data-active-status='1'] [data-role='editor-nav-bar'] {
  background: rgba(210, 230, 219, 0.85);
}

/* 主窗口使用图片背景时 */
.theme-custom [data-role='main-page-frame'][data-background-type='image'] {
  --wp-memo-bg: transparent;
}

data-active-status="1" 表示分栏且激活,"0" 表示分栏但未激活;未分栏时该属性可能不存在。

选择器匹配不代表规则一定胜出。应用对激活分栏、连续视图等状态有专门样式;效果不符时,检查目标元素的计算样式和选择器优先级,再增加必要的区域或状态限定。

主窗口框架还提供 data-composition="1" 和 data-minimal-mode="1",分别表示专注模式与极简模式。与 data-role 在同一元素上的状态属性应直接相连,不要在两者之间加空格。

注意两种背景状态属性的所在层级:主窗口的 main-page-frame 使用 data-background-type;主窗口与浮动窗口的 page-wrapper 使用 data-editor-background-type。要在两类窗口中匹配图片背景,可以使用 [data-role="page-wrapper"][data-editor-background-type="image"],不要混用属性名称。

只调整某类窗口时,可以限定:

css
body.theme-custom[data-win-name='main'] [data-role='page-wrapper'] {
  /* 主窗口 */
}

body.theme-custom[data-win-name='float'] [data-role='page-wrapper'] {
  /* 浮动窗口 */
}

基础 CSS 示例 ​

下面的 style.css 与前面的 JSON 配合使用,继承明亮主题并调整为柔和的绿色配色:

css
.theme-custom {
  --wp-dark: light;

  --wp-primary-color: #397d75;
  --wp-on-primary-color: #ffffff;

  --wp-text-color: #263b35;
  --wp-text-color-2: #687d75;

  --wp-base-bg: #eef4f1;
  --wp-on-base-bg: #263b35;
  --wp-on-base-bg2: #687d75;
  --wp-paper-bg: #fbfdfb;

  --wp-selected-bg: #397d75;
  --wp-on-selected-bg: #ffffff;
  --wp-hover-bg: rgba(57, 125, 117, 0.12);

  --wp-frame-border-color: 1px solid transparent;
  --wp-border-color: rgba(38, 59, 53, 0.12);

  --wp-left-panel-bg: #dcebe3;
  --wp-main-panel-bg: transparent;
  --wp-right-panel-bg: #e6f0e9;
  --wp-status-bar-bg: transparent;

  --wp-left-panel-border: 1px solid var(--wp-border-color);
  --wp-main-panel-border: 1px solid var(--wp-border-color);
  --wp-right-panel-border: 1px solid var(--wp-border-color);

  --wp-memo-bg: #f3f7ee;
  --wp-caret-color: #397d75;
}

.theme-custom [data-role='editor-nav-bar'] {
  background: rgba(230, 240, 233, 0.8);
}

背景图片、模糊与透明效果 ​

使用背景图片时,在 ZIP 根目录加入图片,并将以下字段合并到配置顶层。建议使用简单文件名,例如 background.png 或 background.jpg,名称和大小写与配置完全一致;避免 #、? 等具有 URL 含义的字符。应用背景图保存逻辑使用的格式包括 PNG、JPG/JPEG、GIF、BMP、WebP。

json
{
  "background_image": "background.jpg",
  "background_image_blur": 8,
  "background_overlay_bg": "rgba(255, 255, 255, 0.35)"
}

同时按需要调整 settings.editor_background_opacity,例如设为 0.2。以上只是需要添加的字段,不是完整的 config.json。

这些设置分别控制:

  • 背景图片:提供底层图像。
  • 模糊:柔化图片细节。
  • 叠加层:压低背景对比度,或整体提亮、压暗。
  • 纸面不透明度:控制正文背后的纸面遮挡程度。
  • 面板背景:由 CSS 变量控制,可使用半透明颜色。

图片默认居中,以 cover 铺满窗口,宽高比不同时会裁掉部分边缘。降低纸面不透明度不会自动让左右面板透明;如果沿用前面的 CSS 示例,需要另行把面板背景改成半透明颜色,图片才能透出来。

不要直接使用 url("./background.jpg") 引用包内背景图。主题 CSS 被注入页面的 <style> 元素,相对 URL 不会自动以主题目录为基准解析,也不要使用制作机器上的绝对路径。

主题样式的拼接顺序是:基础主题样式 → style.css → 根据背景配置生成的规则。正数模糊半径会生成 --wp-page-wrapper-backdrop-filter,非空叠加层会生成 --wp-page-wrapper-bg;相同优先级下,这些规则会覆盖 style.css 中对应变量的值。

打包、导入与检查 ​

将 config.json、style.css 和实际使用的图片压缩成 ZIP,再将扩展名改为 .wptheme。也可以直接用 ZIP 工具生成该扩展名的文件。

例如,将配置和 CSS 放在 my-theme/ 目录,在它的父目录运行以下 Python 代码:

python
import json
from pathlib import Path
from zipfile import ZipFile, ZIP_DEFLATED

source = Path("my-theme")
config = json.loads((source / "config.json").read_text(encoding="utf-8"))
files = ["config.json"]
if (source / "style.css").is_file():
    files.append("style.css")
background = config.get("background_image")
if background:
    # 图片必须位于包根目录,不能是路径或 URL。
    assert isinstance(background, str)
    assert "/" not in background and "\\" not in background
    assert background not in (".", "..")
    files.append(background)

for name in files:
    assert (source / name).is_file(), f"Missing file: {name}"

with ZipFile("my-theme.wptheme", "w", ZIP_DEFLATED) as archive:
    for name in files:
        archive.write(source / name, arcname=name)

在 WonderPen 的【设置】→【外观】→【自定义主题】中点击【导入】,导入后点击主题应用。可用权限以应用内标识及版本对比为准。

检查时至少覆盖以下场景:

  • 正文、备注、目录、输入框及菜单文字清晰可读。
  • 选中、悬停、失焦和禁用状态能够区分。
  • 单编辑器、分栏、标签页和浮动窗口显示正常。
  • Island 外轮廓清晰保留,面板之间的留白没有多余框架分隔线;导航栏等组件的必要边界未被一并隐藏。
  • 左、中、右栏底部状态栏融入窗口底色,没有直接背景覆盖或父容器底色造成的意外色块。
  • 调整窗口大小后,背景和面板没有异常遮挡。
  • 专注模式与极简模式下仍能正常使用。
  • 切换到其他主题后,自定义样式不再影响界面。

如果效果与预期不同,还应检查:

  • 【高级】中是否启用了其他自定义 CSS;它们在主题 CSS 后加载,相同优先级下可能覆盖主题样式。
  • 当前主题是否保存过本机样式调整;需要时可通过主题右键菜单的【重置为默认值】清除。
  • 是否启用了应用到其他主题中的【持续保持一致】;需要完整验证主题默认设置时,应先停止保持一致。

主题编辑器保存的是可分发的设计;使用主题时在样式面板中的额外调整不会自动写入导出主题。需要一起分发的设置,应保存到主题设计中。

给 AI 的交付检查表 ​

  • ZIP 根目录包含合法的 config.json,主题名称非空。
  • JSON 与 CSS 使用 UTF-8;只使用文档列出的字段和正确的值类型,不能把“导入成功”当作完整配置校验。
  • 新主题使用新 ID;同一主题更新保留原 ID。
  • base_style 使用有效内置主题标识,或省略。
  • theme_mode、--wp-dark 与实际配色一致。
  • CSS 使用 .theme-custom 作用域,具体元素优先使用已确认的 data-* 选择器。
  • 区分框架分隔线与 island 外轮廓,按边框说明检查,避免批量隐藏面板或组件边框。
  • 按状态栏背景说明同时检查状态栏变量、直接背景覆盖与父容器底色,不能只把状态栏变量设为透明就认为检查完成。
  • 图片引用不依赖制作机器的本地绝对路径,包内包含配置引用的图片。
  • 不包含 local_settings.json、其他 local* 文件或无关资源。
  • 交付 .wptheme 文件,并简要说明主题风格、使用的字体及导入方式。
  • 如未在 WonderPen 中验证,应明确说明尚未完成应用内验证。