WeUI —— Typecho 主题功能说明
一个基于腾讯 WeUI 的 Typecho 主题,样式对齐官方风格,内置站点级无刷新(PJAX)、
明暗配色、文章目录、相册、点赞打赏分享、评论富文本,以及一个自研的完整音乐播放器(含逐字歌词)。
- 主题名:WeUI(基础版)
- 依赖:Typecho、PHP(仅依赖主题内
libs/Meting.php一个音乐核心库) - 资源全部本地内置,不依赖任何外网 CDN(WeUI、highlight.js、Fancybox、qrcode 均在
assets/)
一、页面与模板
| 模板 | 说明 |
|---|---|
index.php | 文章列表(首页);同时作为分类/标签/作者/日期归档的兜底。 |
post.php | 文章详情页;若文章自定义字段 album=1 自动切换到相册布局。 |
page.php | 独立页面。 |
archive.php / category.php / search.php | 通用归档 / 分类归档 / 搜索结果页。 |
archives.php | 自定义页面模板「归档」:按年月分组的归档时间线(YYYY年N月 → 日期 + 标题)。 |
categories.php | 自定义页面模板「分类」:列出所有分类及各自文章数。 |
gallery.php | 自定义页面模板「相册」:列出相册文章。 |
gallery_album.php | 相册详情:正方形网格 + Fancybox 灯箱。 |
links.php | 自定义页面模板「友链」:正文按 名称\网址\图片\介绍 解析成友链网格。 |
about.php | 自定义页面模板「关于」:通用图文页 + 评论区。 |
相册文章会被在 SQL 层从普通列表/归档中排除(Widget\Archive::query 钩子),因此每页条数与总页数都不含相册。
二、视觉与配色
- 明暗双模式,颜色统一走 WeUI CSS 变量(
--weui-BG-*/--weui-FG-*/--weui-BRAND),自动适配。 三种配色来源(后台「默认配色」):
- 跟随系统:读取
prefers-color-scheme,系统切换时实时跟随; - 按时间自动:亮色区间由后台「亮色起始/结束小时」决定(默认 7–19 点,支持跨夜),每分钟检查一次;
- 亮色 / 暗色:手动锁定。
- 跟随系统:读取
- 前台切换按钮:侧边悬浮「外观设置」齿轮,选中的模式写入
localStorage(键wf_theme_mode),下次访问自动恢复。
后台关闭「显示明暗模式切换按钮」后,齿轮隐藏、也不再读本地选择。 - 防闪烁:
header.php在<head>内尽早解析配色并写到<html data-wf-theme>(同时上底色),<body>开头同步data-weui-theme给 WeUI,刷新时不闪另一种底色。 - 响应式:主断点
@media (min-width: 641px);页面容器最大宽 640px;支持prefers-reduced-motion降级动画。 侧边悬浮按钮(FAB)形态:
- 移动端:贴紧屏幕右缘的半圆片(宽 46px,右侧无边框、只保留左圆角);
- PC 端:离屏幕右缘的悬浮圆球(48×48),水平位置按「内容容器右缘 ↔ 屏幕右缘」的黄金分割比(0.382)偏右定位;
- 暗色下额外加一圈细描边,避免深色背景上轮廓不清。
三、无刷新(PJAX)
- 点击站内链接时用
fetch取回页面、替换.page容器、同步标题与 history,无整页刷新。 - 支持浏览器前进/后退(
popstate);带锚点的链接会滚到锚点,否则回到顶部。 - 不参与 PJAX:
target="_blank"、站外链接、附件下载(feed/扩展名过滤);可用data-no-pjax强制某链接走正常跳转。 - 换页后会重新初始化懒加载、灯箱、代码高亮、目录、加载更多等(
runInit())。 - 统计不重不漏:后台「统计代码」只在首次整页加载执行一次;每次无刷新换页由主题调用各平台标准接口补发一次浏览——
百度统计_hmt、GA4gtag、analytics.jsga、Matomo_paq,其它平台可自定义window.wfOnPjaxPageview(url)。 - 返回顶部、音乐播放器等固定在
.page之外,换页不重建 → 音乐不中断。
四、头部与导航
- 站点头:「跟随页面滚动」或「固定在顶部」(sticky),可后台切换。
- 站点标题 / 副标题(副标题可在首页显示/隐藏)。
- 导航:首页 + 所有独立页面,当前页高亮。
头部搜索:后台开启后,导航栏右侧出现放大镜按钮:
- 点击在头部下方展开 WeUI 官方搜索栏,再点收起(Esc 也可收起);
- 输入非空时出现「清空」按钮;提交走无刷新跳到
/search/<关键词>/(Typecho 原生搜索路由),无 JS 时用?s=; - 交互用文档级事件委托,PJAX 换页后可继续使用。
五、文章与元信息
- 相对时间:「刚刚 / N 分钟前 / N 小时前 / N 天前 / N 个月前」,超过一年直接给完整日期。
- 点击切换完整时间:列表卡片与正文的时间都可点,点一下切换成
2026-01-02 11:11:11。 阅读次数:文章页与相册页每访问一次计数,存放在 Typecho 原生自定义字段(
typecho_fields.views,不新增数据表)。- 按访客去重(默认):用 Cookie 记录已读 cid,同一访客打开同一篇只计一次(一年有效,最多记 200 篇);
- 每次访问都计数:不判断 Cookie。
- 元信息字段(列表与正文一致):
作者 · 时间 · 分类 · 阅读次数,每段前有小图标(内联 SVG,跟随 currentColor);
作者与分类为可点击链接(进对应归档),但颜色与其它字段一致(不用链接色、无下划线)。 - 页脚版权:
Copyright © 建站年份-当前年份 站名 All Rights Reserved.,只有站名是超链接;下方「由 Typecho 强力驱动」(官方 SVG,改currentColor自动适配明暗)。 - 页脚自定义内容:后台可填 HTML,显示在版权上方(备案号、友链等)。
六、正文增强
正文(.wf-post-content)与评论内容共用同一套排版与增强:
- 排版组件:标题、段落、有序/无序列表、引用
blockquote、行内code、kbd、mark、del、hr、表格、代码块、figure/figcaption、折叠details/summary、自适应iframe/video。 - 图片懒加载:真实地址写入
data-wf-src,src先用内联灰色占位 SVG;IntersectionObserver提前 200px 加载并淡入。 - Fancybox 灯箱:正文图片/视频自动包裹进 Fancybox(
data-fancybox="wf-content",视频按html5video);相册图片用wf-album。 - 代码高亮:
highlight.js 11.9(本地内置)自动识别语言高亮,每个代码块右上角自动出现「复制」按钮。 - 外链新窗口:正文/评论里站外链接自动加
target="_blank"+rel="noopener";站内链接交给 PJAX。 - 视频封面:无
poster的视频会在客户端抽帧当封面(含 Safari 兼容处理),失败则用原生首帧。
七、文章目录(TOC)
- 服务端扫描正文
h2/h3/h4,为无id的标题补上可读且唯一的 id(weuiTocSlug(),保留中日韩/字母数字)。 - 侧边悬浮「目录」按钮:标题数 ≥ 2 才显示;面板随正文重建,滚动时高亮当前章节;点击平滑滚动(移动端点击后自动收起)。
- 面板宽度自适应:宽度随目录文字长短伸缩,最小宽度 132px(与「网站配色」面板一致),
上限min(280px, 100vw − 72px),超出用省略号(不换行)。
八、相册
- 相册文章用自定义字段
album=1标记;post.php自动切到gallery_album.php。 - 正方形网格:移动端 3 列 / PC 4 列。
- 图片懒加载淡入 + Fancybox 灯箱;视频格子带居中播放键,无 poster 时抽帧或原生首帧当封面。
- 图片说明取
alt,视频取title/alt/data-caption。 - 相册页底部同样有点赞 / 打赏 / 分享行,并计入阅读次数。
九、评论系统
- 结构:所有评论平级输出在一个
<ol>,视觉层级由 CSS 缩进表达;回复链接由主题自输出(规避 Typecho 深层无回复按钮的问题)。 @某某回复:回复时在正文首段插入@某某(链到被回复评论锚点),点击可平滑滚动定位并高亮。- 富文本编辑器 + 表情:评论框升级为 contenteditable 富文本,提交前序列化为
[sticker:名字]/[emoji:编号]短代码;
表情面板含「贴纸 / 表情」两个 tab,光标位置记忆,点空白或 Esc 收起。 - 评论信息弹窗:昵称 / 邮箱 / 网站弹窗,本地记忆(
wf_comment_profile),邮箱变化实时更新头像。 - 无刷新提交:提交前同步富文本、空内容校验、游客信息弹窗、反垃圾令牌保留、只替换评论列表不换表单、待审核提示、成功定位并高亮新评论。
- 评论分页 / 加载更多:分页或「加载更多」按钮,支持滚动到底自动加载(提前 400px 预取)。
- 评论点赞:每条评论可点赞(存于所属文章的
comment_likesJSON 映射)。 - 头像加速:走后台配置的 Gravatar 镜像(见设置项),核心 Gravatar 也走同一 CDN。
- 快捷键:评论框
Ctrl/Cmd + Enter提交;Esc收起面板。 - 评论框位置:可后台选择「评论列表上方」或「下方」。
十、点赞 / 打赏 / 分享
文章页与相册页底部一行(正文之后、标签之前),居中排列:
- 点赞:文章点赞按钮,已赞再点即取消,用 Cookie 记忆已赞状态;多个访客并发计数安全。
- 打赏:微信 / 支付宝二维码弹窗;两个都填则同排显示,只配一个则居中,都留空则整块不显示;上方可配说明文字。
- 分享:分享面板 6 项 —— 微博 / QQ 空间 / Telegram / 微信扫码(qrcode 生成)/ 复制链接 / 生成海报
(纯前端 canvas 绘制标题 + 封面 + 摘要 + 二维码,可下载或长按保存)。
十一、音乐播放器
一个自研的完整 HTML5 播放器(不依赖 APlayer),核心取播放地址用主题内 libs/Meting.php(Meting 1.5.7)。
侧边音乐按钮点一下展开播放器面板;页面无刷新切歌不中断。
11.1 后端(歌单 → 代理端点)
- 平台:网易云 / QQ 音乐 / 酷狗 / 百度音乐(后台选)。
歌单 ID / 链接支持三种写法(一行一个):
- JSON:
{"server":"netease","type":"playlist","id":"xxx"} - 分享链接:自动按平台特征提取 ID(music.163.com、y.qq.com、kugou.com、百度音乐)
- 纯 ID:
playlist/song/album/artist
- JSON:
- Cookie:网易云 / QQ 必须带 Cookie 才能取到可播放地址;后台可填自己的 Cookie(含
MUSIC_U/qqmusic_key),留空用内置兜底 Cookie(失效时需自行更新)。 - 签名防盗刷:代理地址带
auth = md5(salt + server.type.id + salt)令牌。 代理端点
?weui_music=<type>&server=&id=&auth=(命中即返回,无需路由/插件):type 行为 playlist/song/album/artist返回歌曲列表 JSON(url/cover/lrc 均指向本站代理),缓存 2 小时 lyric(lrc自动映射)返回纯 LRC 文本,缓存 24 小时 pic302 跳真实封面地址,缓存 24 小时 url302 跳真实音频地址,缓存 20 分钟(含各平台 URL 修正) - 本地文件缓存(主题目录
cache/),不可写时静默降级直连。
11.2 播放器功能
- 播放 / 暂停 / 上一首 / 下一首,图标即时同步。
- 三种播放模式(循环切换,纯图标三态):列表循环 → 随机播放 → 单曲循环,选择被记住(
wf_music_mode)。 - 进度条:可拖动 seek;已播放部分用品牌色填充(未播放为灰)。
- 歌曲列表:每条含封面小图(懒加载) + 「专辑 · 作者」;当前播放项高亮。
- 圆形悬浮定位按钮:点击把当前播放项滚到列表中部并短暂高亮;打开面板时自动定位到当前条目;切歌时(面板开着)自动跟随。
- 接着上次播放:记住上次的歌曲 + 播放进度,下次进入自动恢复并 seek 到断点。
- 跨标签页互斥播放:同一时刻只允许一个标签页出声(
BroadcastChannel,不支持时退回localStorage)。 - 加载失败自动跳过:某曲加载失败会标记并 2 秒后自动跳下一首;全部失败则停止并提示;再点失败曲可重试。
- 自动播放(可选):打开页面自动播放(受浏览器策略限制,通常需先有一次交互)。
- 面板位于
.page之外,PJAX 换页不重建 → 播放不中断。
11.3 歌词(贴底单行,含全套动效)
- 贴底单行歌词:暗字底层 + 亮字覆盖层,逐字扫过高亮(卡拉 OK 效果)。
- 切行动效:整行
opacity + scale入场(与逐字并发);旧行停留 500ms 后淡出。 - 逐字入场(letterfx 三档):短句「上浮」、快长句「打字机」、慢长句「模糊抹过」。
- 超长行横向滚动:一行太长时,随逐字唱过整行向左滚动,把当前字保持在可视区约 32% 处(前面的字滚出、后面的字滚进)。
- 逐行分色:识别 LRC 的
男:/女:/合:前缀,分别用 蓝 / 红 / 品红 高亮。 - 歌词开关:面板上的「词」按钮,开关状态被记住;暂停即隐藏、播放才显示(歌词开关为开且正在播放时显示)。
- 歌词容器始终存在:后台「默认显示歌词」只作为前台开关初值,即便后台关掉、前台仍可自行打开。
十二、图片随明暗自动切换
给任意 <img> 写两个自定义属性即可,无需 JS,主题会按当前明暗主题自动换 src:
<img light-src="浅色版.png" dark-src="深色版.png" alt="说明">- 浅色主题显示
light-src,深色主题显示dark-src;缺其中一个时互相回退,不会出现空图。 - 用
MutationObserver监听,运行时插入的图片(含 PJAX 换页后新增、页尾手插的图)也会自动适配。
十三、后台设置项一览
后台 → 控制台 → 外观 → 设置外观:
头部与外观
| 设置项 | 说明 |
|---|---|
| 网站头部位置 | 跟随页面滚动 / 固定在页面顶部。 |
| 首页显示副标题 | 是否在首页头部显示站点副标题。 |
| 头部搜索 | 开启后导航栏右侧出现搜索按钮(可展开/收起搜索框)。 |
配色
| 设置项 | 说明 |
|---|---|
| 显示明暗模式切换按钮 | 关闭后前台不再显示「外观设置」齿轮,访客一律按「默认配色」。 |
| 默认配色 | 跟随系统 / 按时间自动 / 亮色 / 暗色。 |
| 亮色起始小时 / 结束小时 | 「按时间自动」的区间(0–23 整点,支持跨夜)。 |
头像
| 设置项 | 说明 |
|---|---|
| Gravatar 头像加速地址 | 留空用官方;可填镜像(如 https://cn.cravatar.com),主题自动补 /avatar/<hash>。 |
底部
| 设置项 | 说明 |
|---|---|
| 页脚自定义内容(支持 HTML) | 显示在版权信息上方。 |
| 统计代码 | 第三方统计脚本,只在首次加载执行一次;无刷新时由主题补发浏览。 |
| 建站年份 | 页脚版权 建站年份-当前年份;留空只显示当前年份。 |
列表 / 评论
| 设置项 | 说明 |
|---|---|
| 列表翻页方式 | 分页 / 按钮加载更多 / 瀑布流加载更多。 |
| 评论翻页方式 | 分页 / 按钮加载更多 / 瀑布流加载更多(需先在「设置 → 评论」开启评论分页)。 |
| 评论框位置 | 评论列表上方(文章下)/ 评论列表下方。 |
| 文章点赞 | 是否显示文章点赞。 |
| 文章分享 | 是否显示分享按钮。 |
| 评论点赞 | 是否在每条评论上显示点赞。 |
| 阅读计数方式 | 按访客去重 / 每次访问都计数。 |
打赏
| 设置项 | 说明 |
|---|---|
| 微信打赏二维码 | 图片地址;留空不显示微信打赏。 |
| 支付宝打赏二维码 | 两个都填则并排显示。 |
| 打赏说明文字 | 显示在二维码上方,可留空。 |
音乐播放器
| 设置项 | 说明 |
|---|---|
| 音乐播放器 | 开启后侧边出现音乐按钮。 |
| 音乐平台 | 网易云 / QQ 音乐 / 酷狗 / 百度音乐(需与歌单 ID 对应)。 |
| 歌单 ID / 链接 | 一行一个,支持 ID 或分享链接。 |
| 网易云 Cookie | 留空用内置兜底;失效时填自己的 Cookie。 |
| QQ 音乐 Cookie | 同上。 |
| 音乐接口密钥 | 给代理地址签名,防盗刷;留空用默认值。 |
| 自动播放 | 打开页面自动播放(可能被浏览器拦截)。 |
| 默认显示歌词 | 前台底部歌词条的初始状态(前台可开关并记住)。 |
| 默认播放模式 | 列表循环 / 随机播放 / 单曲循环。 |
文章编辑页自定义字段
- 相册(否 / 是):标记为相册文章。
- 缩略图(文本):留空自动取正文首图。
- 隐藏注册的计数字段
views/likes/comment_likes(防止编辑文章时计数被清零)。
十四、目录结构
theme/
├── assets/
│ ├── weui.css # WeUI 样式子集(官方 dist 逐条摘录)
│ ├── theme.js # 主题全部前端交互
│ ├── highlight.min.js # 代码高亮(本地内置)
│ ├── highlight.css # 高亮配色(跟随明暗)
│ ├── fancybox.umd.js / fancybox.css # 灯箱
│ ├── qrcode.min.js # 分享二维码
│ └── emoticons/ # 贴纸 / 表情图(含 manifest.json)
├── libs/
│ └── Meting.php # 音乐核心库(Meting 1.5.7)
├── tools/
│ ├── build-weui-subset.py # 提取 WeUI 子集
│ ├── fetch-emoticons.py # 生成表情清单
│ └── sync-live.py # 一键同步到服务器
├── index.php # 文章列表 / 通用归档
├── post.php # 文章详情(相册自动切换)
├── page.php # 独立页面
├── archive.php category.php search.php
├── archives.php # 页面模板:归档(时间线)
├── categories.php # 页面模板:分类
├── gallery.php # 页面模板:相册列表
├── gallery_album.php # 相册详情
├── links.php # 页面模板:友链
├── about.php # 页面模板:关于
├── header.php footer.php comments.php
├── functions.php # 主题函数与后台设置
├── style.css # 主题自有「胶水」样式
└── screenshot.png附:安装
- 把整个
theme目录放进 Typecho 的usr/themes/下(建议目录名改为WeUI)。 - 后台 → 控制台 → 外观,启用本主题。
- 主题名称/作者/版本由
index.php头部注释读取,不需要info.json。