2025-11-20

1. New Plugin:评论验证码

> 实现了验证码插件,防止恶意刷评攻击

参考项目:https://github.com/m00nfly/Typecho-Captcha?tab=readme-ov-file
插件路径:usr\plugins\Captcha
对原插件做出的修改如下:

  • 用户点击评论提交后弹出验证码弹窗,通过 AJAX 验证后再提交表单,创建 VerifyAction.php 用于前端验证接口
  • 将 Plugin.php 中相对路径改为绝对路径(dirname(__FILE__)),解决文件加载失败问题
  • 添加简单对话框提示(验证成功/失败),修复 shake 动画显示,统一按钮样式与主题一致,改进验证码可读性(字体、颜色、尺寸)
  • 将 Server酱推送从 filter() 方法移至 finishComment() 钩子,确保仅在评论成功插入数据库后发送推送通知

2025-11-21

1. New Plugin:仿GitHub风格贡献图

> 实现了仿GitHub风格贡献图插件,一个很帅的组件,用以作为博客操作记录

插件路径:usr\plugins\ContributionGraph
概述:实现了类似 GitHub 个人页面的贡献统计热力图功能,通过追踪博客文章发布、修改、页面发布/修改、评论等操作,自动记录每日贡献次数并以绿色方块热力图形式展示。在 Typecho 后台激活插件后,会自动创建 typecho_contributions 数据表用于存储贡献记录,并自动从现有数据库记录中初始化历史贡献数据。效果如下:

2025 年贡献统计

共 187 次贡献
1月
2月
3月
4月
5月
6月
7月
8月
9月
10月
11月
12月
周一
周三
周五

  • 组件插入方式:在文章或页面中使用短代码 [$ContributionGraph](删除其中的占位符$[ContributionGraph year="2025"] 插入贡献图表
  • 可配置项:插件支持在后台配置中自定义追踪的操作类型(文章发布、文章修改、页面发布/修改、评论)和默认显示年份。
  • 技术原理:通过 Typecho 钩子系统监听 Widget_Contents_Post_Edit::finishPublishWidget_Contents_Page_Edit::finishPublishWidget_Feedback::finishComment 等事件,自动记录操作日期和次数。热力图使用绝对定位布局,确保月份标签、周标签和方块一一对应,支持周日作为一周开始,并实现了可配置的说明区域(问号按钮悬停显示)。
  • Feature:支持显示任意年份的贡献数据,自动计算周数和月份标签位置,鼠标悬停显示具体日期和贡献次数,响应式设计适配移动端,完全模仿 GitHub 风格的绿色渐变色彩方案(4个等级:无贡献、1-3次、4-9次、10次以上)。

2. New Feature:折叠内容功能

> 为博客文章添加折叠内容功能,支持通过标签创建可展开/收起的折叠区域

组件插入方式:在 Markdown 文章中使用 [$fold title="提示字符"] 内容 [$/fold] (删除其中的占位符$格式创建折叠内容。效果如正如该折叠卡片所示。
Feature:

  • 支持换行格式:标签之间的内容可以包含多行
  • 美观的 UI 设计:箭头图标(>)可旋转,标题区域悬停高亮,内容区域平滑展开/收起动画
  • 响应式设计:适配主题的深色/浅色模式,使用主题 CSS 变量保持风格一致
  • 兼容 pjax:在页面通过 pjax 加载后自动重新初始化折叠功能

技术原理:

  • usr/themes/Daydream/functions.php:在 exContent() 函数中添加正则表达式解析标签
  • usr/themes/Daydream/assets/css/style.css:添加折叠容器的完整样式(包括箭头图标、边框、阴影、动画效果)
  • usr/themes/Daydream/footer.php:添加 JavaScript 实现点击展开/收起交互功能

3. Fix:站点LOGO资源文件问题

> 修改站点地址配置后,其他资源文件加载正常,但站点 LOGO仍然报 404 错误的BUG

问题原因:logoUrl 是主题配置项,值存储在数据库中。即使修改了站点地址,数据库中存储的旧路径(如 http://127.0.0.1/usr/themes/Daydream/assets/avatar.png)不会自动更新,导致路径缺少网站根目录部分
解决方案:

  • 修改 usr/themes/Daydream/header.php,添加路径检测和回退机制
  • 检测 logoUrl 是否为空或包含错误的路径(包含 /usr/themes/ 但不包含正确的站点 URL)
  • 如果路径错误,自动使用动态生成的路径 themeUrl('/assets/avatar.png')
  • 确保 logoUrl 始终使用正确的路径,不受数据库中旧值影响

修改位置:

  • usr/themes/Daydream/header.php 第15-25行:apple-touch-icon 的 logoUrl
  • usr/themes/Daydream/header.php 第63-75行:header 中的头像图片

4. New Func:GitHub仓库自动同步部署

> 实现了 GitHub 仓库与宝塔面板服务器的自动同步功能,实现本地开发后自动部署到生产环境

采用宝塔面板计划任务 + Git 同步脚本的方案,自动检查并同步代码。
技术实现:

  • 在服务器上安装 Git 并初始化仓库,配置远程仓库地址为 https://github.com/AWildFunny/Manueld.me.git
  • 创建同步脚本 git_sync.sh,实现强制同步功能(服务器代码与 GitHub 完全一致)
  • 在宝塔面板配置计划任务,定时执行同步脚本

同步脚本功能:

  • 强制同步:使用 git reset --hard origin/main 确保服务器代码与 GitHub 完全一致,自动丢弃本地修改
  • 配置文件保护:自动备份和恢复 config.inc.php(包含数据库密码等敏感信息),防止被覆盖
  • 日志文件保护:保护 sync.log 文件不被删除或覆盖,确保同步日志完整记录
  • 权限设置:同步后自动设置正确的文件权限(chown -R www:wwwchmod -R 755
  • 详细日志:记录每个步骤的执行情况,便于排查问题

修改文件:

  • .gitignore:添加 Typecho 敏感文件和目录到忽略列表

    • config.inc.php(数据库配置)
    • usr/uploads/(用户上传文件)
    • usr/tmp/usr/cache/(临时文件)
  • 服务器同步脚本:/www/wwwroot/www.manueld.me/git_sync.sh(新建)

使用说明:

  • 本地开发完成后,提交并推送到 GitHub:git push origin main
  • 服务器会自动同步
  • 同步日志保存在 /www/wwwroot/www.manueld.me/sync.log
  • 配置文件 config.inc.php 会被自动保护,不会被覆盖
今天真是充实(闲人)的一天...

2025-11-22

1. Fix:评论时 User-Agent 解析错误

> 修复评论显示时某些 User-Agent 无法匹配版本号导致的 PHP 8.0+ 警告错误

问题原因:当某些评论者的 User-Agent 字符串无法匹配到浏览器版本号时,preg_match() 返回的数组不包含索引 [1],原代码使用 is_null($regmatch[1]) 检查,但在 PHP 8.0+ 中访问不存在的数组键会先触发警告。
解决方案:将 usr/themes/Daydream/include/UserAgent/get_browser_name.php 第27行的检查方式从 is_null($regmatch[1]) 改为 isset($regmatch[1]) && !empty($regmatch[1]),在访问数组键之前先检查其是否存在,避免 PHP 8.0+ 的严格检查警告。
修改位置:usr/themes/Daydream/include/UserAgent/get_browser_name.php 第27行,get_browser_version() 函数中的版本号提取逻辑。
影响范围:修复后可以安全处理所有类型的 User-Agent 字符串,即使无法匹配版本号也不会报错,评论功能正常工作。

2025-11-25

1. Fix:服务器端验证码图片加载错误

> 修复服务器环境下验证码图片无法加载的问题

问题原因:服务器 PHP 8.1+ 环境下,securimage.php 第 791 行产生大量 Implicit conversion from float to int loses precision 的 Deprecated 警告。当服务器开启 display_errors 时,这些警告被输出到响应中,污染了图片的二进制数据,导致浏览器无法解析图片(响应体为空或包含警告文本)。
解决方案:

  • usr/plugins/Captcha/Action.php 开始时抑制错误输出:设置 ini_set('display_errors', '0')error_reporting() 过滤 Deprecated 警告
  • 清理输出缓冲区:在开始时和调用 $img->show() 之前使用 ob_end_clean() 清理所有输出缓冲区,确保图片输出前没有其他内容
  • 修复跨站检查逻辑:添加对 parse_url() 返回的 path 键的安全检查,处理站点地址为根域名(无路径)的情况

修改位置:

  • usr/plugins/Captcha/Action.php 第 7-14 行:添加错误抑制和输出缓冲区清理
  • usr/plugins/Captcha/Action.php 第 16-43 行:优化跨站检查逻辑,安全获取路径并规范化比较
  • usr/plugins/Captcha/Action.php 第 109-112 行:在图片输出前再次清理输出缓冲区

影响范围:修复后验证码图片可以在服务器环境下正常显示,不再受 PHP Deprecated 警告影响,跨站检查逻辑更加健壮,支持根域名配置。

测试了好多轮,发现仅依赖console进行调试不可取,必须查找服务器log进行PHP错误的调试

2025-11-26

1. New Feature:顶部导航栏水平布局、滚动固定

> 实现了Header和Navbar的水平布局,并添加滚动时的动态切换效果

将原本竖直排布的Header和Navbar改为水平布局(Header在左,Navbar在右),并实现滚动时Navbar固定在顶部,左侧显示小头像的功能。

主要功能

  • Header和Navbar水平布局:使用Flexbox实现,Header(头像+标题+描述)在左侧,Navbar在右侧
  • 滚动固定效果:当页面滚动、Header不可见时,Navbar自动固定在顶部,左侧显示小头像(32px),点击跳转到"关于"页面
  • 导航链接高亮:当前页面对应的导航链接自动高亮显示(底部边框+主色+加粗)
  • Pjax兼容:支持pjax无刷新切换页面,导航链接高亮状态自动更新

修改文件

  • usr/themes/Daydream/header.php:HTML结构调整、JavaScript逻辑
  • usr/themes/Daydream/assets/css/style.css:布局样式、高亮样式、响应式样式

2. New Feature:自定义首页模板、修改主页路径

> 实现了自定义首页功能,支持独立编辑首页内容,并统一首页访问路径

  • 自定义首页模板:创建 usr/themes/Daydream/page/home.php,支持显示 alert公告、推荐阅读("首页推荐"分类)、最新文章(5篇)
  • 路径统一:访问 /home.html 时自动 301 重定向到根路径 /,统一 URL 并提升 SEO
  • 页面优化:移除"文章"页面(/blog/)的 alert 公告显示

配置方法

  1. 创建"首页推荐"分类(用于推荐文章到首页)
  2. 创建独立页面,slug 设置为 home,标题为"首页"
  3. 在"设置" → "阅读"中,选择"使用 [首页] 页面作为首页",并设置文章列表页路径为 /blog/

技术实现

  • usr/themes/Daydream/page/home.php:首页模板(新建),包含重定向逻辑和内容展示
  • usr/themes/Daydream/header.php:导航栏逻辑优化,支持页面首页识别和高亮
  • usr/themes/Daydream/index.php:移除 alert 显示
  • usr/themes/Daydream/assets/css/style.css:添加首页模板样式(推荐阅读、最新文章区域)
  • usr/themes/Daydream/page/:自定义页面模板目录(新建)
  • usr/themes/Daydream/page/home.php:首页模板(新建)

2025-11-27

1. New Feature:文章列表页分类筛选组件

> 实现了文章列表页的分类筛选、标签筛选和搜索功能,提供完整的筛选体验

在文章列表页(/blog/)添加了完整的筛选组件,支持分类筛选、多选标签筛选、搜索功能,并集成Pjax无刷新更新和URL分享功能。
分类图标配置

  • 在Typecho后台编辑分类,在"描述"字段中填入图标代码(emoji或图标类名)
  • 支持emoji图标:📚 💻 ✍️ 📖 ✈️ 🍜 等
  • 如果描述为空,默认使用 📁 图标

技术实现:

  • usr/themes/Daydream/functions.php:添加辅助函数

    • isArchivePage():判断是否为archive页面
    • getCategoriesWithIcons():获取所有分类及图标
    • getCategoryPostCount():获取分类文章数量
    • getTagsByFilter():根据筛选条件获取标签云数据
    • getFilterUrl():生成筛选URL
  • usr/themes/Daydream/index.php:添加筛选组件HTML和文章筛选逻辑

    • 读取URL参数(cat, tags, search)
    • 显示筛选组件(分类侧边栏、搜索框、标签云、结果统计)
    • 实现文章筛选逻辑(在显示时过滤)
  • usr/themes/Daydream/assets/css/style.css:添加筛选组件样式

    • 左侧分类侧边栏样式(带图标、数量、激活状态)
    • 搜索框样式(右侧放大镜图标、高度42px)
    • 标签云样式(气泡样式、大小分级、激活状态)
    • 结果统计样式(右下角定位、清除按钮)
    • 响应式样式(移动端适配)
  • usr/themes/Daydream/assets/js/category-filter.js:实现筛选交互(新建)

    • 分类点击切换
    • 标签多选/取消
    • 搜索输入处理(防抖)
    • Pjax集成
    • URL更新和分享
    • 分页链接更新
  • usr/themes/Daydream/header.php:引入category-filter.js文件

使用说明:

  1. 配置分类图标:在Typecho后台编辑分类,在"描述"字段中填入图标代码
  2. 访问文章列表页:筛选组件会自动显示在 /blog/ 页面
  3. 使用筛选:点击分类、标签或输入搜索关键词即可筛选
  4. 分享筛选结果:筛选后浏览器地址栏的URL包含筛选参数,可直接复制分享

2025-11-30

1. Fix:文章筛选分页问题

> 修复文章筛选的问题

使用 query 钩子(在 functions.php 加载后执行),手动执行查询并推送结果到 Archive 对象,在 query 钩子中重新设置 countSql,确保分页计算包含筛选条件。当没有筛选条件时,也手动执行默认查询,确保"全部"选项正常工作。筛选逻辑优化:分类和标签筛选使用 IN 查询(避免 JOIN 冲突),搜索筛选直接应用 LIKE 条件

修改文件:

  • usr/themes/Daydream/functions.php:实现 query 钩子,添加筛选逻辑和分页计算
  • usr/themes/Daydream/footer.php:清理调试代码

2. New Feature:分类隐藏功能

> 实现了分类隐藏功能,支持在后台设置分类是否在前端显示

在Typecho后台分类编辑页面添加了"隐藏分类"复选框,勾选后该分类不会在前端的分类筛选组件中显示。

使用方法

  1. 在Typecho后台进入"分类" → "编辑分类"
  2. 在"分类描述"字段下方会出现"隐藏分类"复选框
  3. 勾选后保存,该分类将不会在前端分类列表中显示

3. Fix:标签气泡大小优化

> 将所有标签气泡大小减半,使界面更加紧凑

将标签气泡的字体大小和内边距全部减半,使界面更加紧凑美观。

4. New Feature:标签折叠功能

> 实现了标签折叠功能,当标签数量超过阈值时自动折叠显示

当标签数量超过屏幕大小对应的阈值时,自动隐藏超出部分的标签,并在最后显示"点击显示全部标签"链接,点击后展开所有标签。

功能特点:

  • 响应式阈值:根据屏幕宽度自动调整显示阈值

    • 移动端(< 576px):显示8个标签
    • 平板(576px - 992px):显示15个标签
    • 桌面(> 992px):显示25个标签
  • 自动折叠:超过阈值的标签自动隐藏
  • 一键展开:点击"点击显示全部标签"后显示所有标签
  • Pjax兼容:支持Pjax无刷新切换页面后重新初始化