一个轻量级 WordPress 内容日历插件,用月历方式查看指定文章类型的发布分布。
有内容的日期会显示数量标记;桌面端鼠标悬浮可查看当天文章列表;移动端点击日期后,会在对应月份日历下方展开当天内容详情。插件支持多月窗口、Ajax 月份导航、分类 / 标签过滤,以及受 WordPress 权限控制的私密内容显示。
当前稳定版本:v1.0.0
Quicknotes 内容日历最初用于 quicknotes 笔记型文章,但数据源没有写死,可选择任意公开的 WordPress post_type。
它解决的是一个明确的问题:
把 WordPress 内容的发布日期按月可视化,快速查看“哪一天发布过什么内容”。
当前版本以 WordPress 的 post_date 作为日历日期,适合:
- Quicknotes / 工作笔记
- 博客文章归档
- 新闻发布记录
- 内容运营记录
- 其它需要按“发布日期”回顾的自定义文章类型
它不是活动预约或完整事件管理插件,当前不处理独立 event_date、重复事件、提醒、Google Calendar / ICS 等能力。
- 默认显示最近 7 个月,可设置为
1–24个月 - 当前月份作为窗口最新月份,向前回溯
- 当前日期高亮
- 顶部显示当前月份范围
- 支持“上一月 / 下一月”Ajax 导航
- 不允许导航到当前月之后的未来月份
按照当天文章数量显示:
- 1 条:
• - 2 条:
•• - 3 条:
••• - 4 条及以上:
3+
数量标记用于快速提示,详细内容在当天列表中查看。
桌面端:
鼠标悬浮日期
↓
按需加载当天内容
↓
显示 Tooltip 列表
也支持点击固定打开 Tooltip,点击页面空白处或按 ESC 关闭。
移动端:
点击有内容的日期
↓
在当前月份日历下方展开详情面板
↓
点击另一日期 → 切换内容
再次点击当前日期 / 点击空白处 / ESC → 关闭
移动端详情面板进入正常文档流,因此不会因日期位于周日 / 周六或月历最后一行而左右越界、覆盖下方内容。
同一日期成功加载后会缓存在当前页面 DOM 中,重复 Hover / 点击不会再次发起 Ajax 请求。
后台可以:
- 选择内容来源
post_type - 选择该文章类型支持的 taxonomy
- 勾选一个或多个 term
例如:
post_type = post
taxonomy = category
terms = WordPress、开发日志
日历只统计符合条件的文章。
后台可选择是否包含 private 内容。
安全规则:
- 未勾选:只查询
publish - 已勾选:只有当前用户具备对应文章类型的
read_private_posts权限时,才会查询private - 匿名访客不会因为开启设置而看到私密内容
- 与用户权限相关的 private 统计不写入共享 transient 缓存
v1.0.0 以“真实站点稳定使用”为目标,没有把插件扩展成大型日程系统,重点完成了以下几类优化。
交互模式只按照当前布局宽度判断:
宽度 > 767px → Desktop Tooltip / Hover 加载
宽度 ≤ 767px → Mobile Detail Panel / Click 加载
不再使用 ontouchstart / maxTouchPoints 判断桌面 Hover,从而避免支持触摸的 Windows / 二合一设备被错误排除,解决“第一次 Hover 不加载,点击一次后再次 Hover 才正常”的问题。
<= 767px时不使用格子内绝对定位 Tooltip- 详情显示在对应月份日历下方
- 不会左右越界或覆盖下方模块
- 标题显示完整日期和数量,例如
2025年8月17日 · 4条内容 - 长中文、英文、URL 和连续字符支持自动换行
- 当前选中日期保持高亮
- 点击另一日期直接切换
- 月份导航前主动清理详情状态
- 快速连续点击不同日期时,旧 Ajax 请求不会覆盖当前选择
公开月度统计使用 WordPress Transient 缓存,并结合 Cache Version 失效机制。
当内容发生以下变化时,会更新缓存版本:
- 新建 / 保存
- 修改发布日期
- 修改分类关系
- 移入 / 恢复回收站
- 删除
因此文章从一个月份改到另一个月份时,不需要逐个猜测并删除旧 transient,旧月份与新月份都会在下一次请求时重新生成正确统计。
包含 private 内容的统计不使用共享 transient,以避免不同用户权限之间产生模糊边界。
- 有内容的日期使用语义化按钮
- 支持 Tab / Enter / Space / ESC
- 使用
aria-expanded表达展开状态 - 页面空白处点击可关闭已打开详情
将插件目录上传到:
wp-content/plugins/quicknotes-content-calendar/
目录结构:
quicknotes-content-calendar/
├── quicknotes-content-calendar.php
├── README.md
├── includes/
│ ├── class-qncc-plugin.php
│ ├── class-qncc-query-service.php
│ ├── class-qncc-calendar-renderer.php
│ ├── class-qncc-ajax-controller.php
│ └── class-qncc-settings-page.php
└── assets/
├── css/
│ └── quicknotes-calendar.css
└── js/
└── quicknotes-calendar.js
然后进入:
WordPress 后台
→ 插件
→ 已安装插件
→ Quicknotes 内容日历
→ 启用
[quicknotes_calendar]
将短码放入普通页面、文章或支持 Shortcode 的页面构建器区域即可。
插件会读取后台设置,并生成对应的内容日历。
插件设置页主要包括:
- Post Type:日历数据来源
- 月份数量:显示最近多少个月,范围
1–24 - 包含 Private:仅对具备读取私密内容权限的用户生效
- Taxonomy:可选分类法
- Terms:可勾选一个或多个分类 / 标签
当更换 Post Type 后,如 taxonomy 选项需要刷新,保存设置后重新进入设置页即可。v1.0.0 暂不为低频后台操作增加额外的动态联动 Ajax。
当前版本使用:
post_date
因此文章显示在哪一天,由 WordPress 发布日期决定。
例如:
文章发布日期:2026-10-17
↓
日历:2026年10月17日显示内容标记
如果未来需要“文章发布日期”和“事件发生日期”分离,应作为新的数据模型设计,而不是直接修改当前 post_date 行为。
日历的月份统计与当天详情使用相同的核心筛选条件:
Post Type
Post Status
Year / Month / Day
Taxonomy
Terms
Current User Capability
这保证圆点统计与点击 / Hover 后的详情列表保持一致。
公开月度统计可使用 transient,以降低重复查询成本。
缓存键会考虑:
Post Type
Year
Month
Taxonomy
Terms
Cache Version
内容发生变化时不需要扫描并删除所有历史 transient,而是更新版本号:
旧缓存:version = 12
内容更新
新版本:version = 13
后续查询自动使用新版本缓存键,旧缓存不再命中,并由 WordPress 按生命周期清理。
当查询包含 private 内容时,不使用共享 transient。
这是有意的安全取舍:
权限相关数据宁可少缓存,也不共享模糊的权限结果。
Hover
→ 首次 Ajax 加载
→ Tooltip 显示列表
→ 当前 DOM 标记 loaded
→ 后续 Hover 即时显示
支持点击固定打开。
Tap 日期
→ 打开日历下方 Detail Panel
→ 首次 Ajax 加载
→ 复用同一份详情 HTML
移动端与桌面端共用后端详情接口,不维护两套数据查询逻辑。
用户快速点击多个日期时,每次移动端详情都会记录当前日期标识。较早发出的 Ajax 即使较晚返回,也不会覆盖后来选择的日期内容。
正式版本已按以下场景进行真实站点测试;以后修改代码时建议继续按此清单回归。
- 插件可正常激活
- 短码正常输出
- 多个月份正常显示
- 当前日期高亮正确
- 当天内容数量标记正确
- 上一月正常
- 下一月正常
- 不会导航到未来月份
- 连续点击导航不会产生重复请求错乱
- 从未点击过的日期第一次直接 Hover 能正常加载
- 加载完成后再次 Hover 即时显示
- 点击日期可固定打开
- 点击页面空白处关闭
- ESC 关闭
- 支持触摸能力的桌面设备不会禁用 Hover
- 点击日期在日历下方显示详情
- 周日 / 最左列不向左越界
- 周六 / 最右列不向右越界
- 月历最后一行不会覆盖下方内容
- 长中文 / 英文标题正常换行
- 连续快速点击不同日期显示正确内容
- 再次点击当前日期可关闭
- 切换月份后旧详情状态被清理
- 新建内容后统计更新
- 修改发布日期后新旧月份统计正确
- 删除 / 回收 / 恢复内容后统计正确
- Taxonomy / Terms 筛选正确
- Private 内容按当前用户权限显示
- 匿名用户无法看到 private 内容
为了保持 v1.0.0 小而稳定,当前版本不加入:
- Event CPT
- 自定义事件日期 / Date Resolver
- 多类型彩色圆点
- 周视图 / 年视图
- 拖拽排期
- Google Calendar / ICS
- 预约 / 提醒
- Elementor 专用 Widget
- 复杂后台动态联动
这些功能如果以后确实需要,应在现有稳定版本基础上重新评估,不直接堆进当前插件。
当前只认 post_date。
例如一篇“10 月 17 日展会”的文章如果 9 月 20 日发布,它会显示在 9 月 20 日,而不是 10 月 17 日。
这属于当前产品定义,不是 Bug。
插件本身不会把 private 月度统计写入共享 transient。
但如果“包含 private 的日历页面”被第三方整页缓存、CDN 或缓存插件错误地对匿名用户共享,仍应在站点缓存层正确配置登录态排除规则。
首次正式稳定版:
- 统一版本号、资源版本号和 Text Domain
- 完成 Ajax 参数校验和 Private 权限处理
- 整理公开数据 transient 缓存与 Cache Version 失效机制
- 支持 Taxonomy / Terms 过滤缓存
- 修复修改发布日期后的旧月份缓存问题
- 优化桌面 Tooltip 加载与重复请求
- 移动端改为日历下方详情面板
- 解决手机端左右越界与覆盖下方内容问题
- 增加快速切换日期的异步请求保护
- 修复支持触摸的桌面设备 Hover 不加载问题
- 增加基础键盘和 ARIA 支持
- 完成真实站点回归测试
项目在首次正式发布前依次经过:
v1.0.0-beta.1
→ 基础稳定性、权限、缓存与交互优化
v1.0.0-beta.2
→ 移动端详情面板优化
v1.0.0-beta.2.1
→ Desktop Hover 判断修复
v1.0.0
→ 首次正式稳定版
- 先保证真实使用稳定,再扩展功能。
- 日历只负责按发布日期展示内容,不承担完整事件系统职责。
- 优先使用 WordPress 原生能力:WP_Query、权限、Transient、Settings API、Ajax。
- Private 数据宁可少缓存,也不增加模糊的权限边界。
- 长期维护优先,不为了功能数量增加复杂度。
请根据仓库实际发布方式补充许可证文件。若作为公开开源项目发布,建议在 GitHub 首次正式发布时明确许可证。