📌 背景
我一直使用 Obsidian 编写 Markdown 文件,并配合脚本将内容自动发布到 Typecho 博客中,实现写作与发布的无缝整合。
整个流程包括:
- 在 Obsidian 中编写
.md
文件 - 使用脚本自动将
.md
转换为 HTML 或内容片段并通过接口发布到 Typecho - 发布后在博客首页中自动展示文章及封面图
一切都很顺利,直到我发现 首页有些文章封面不显示了,甚至页面布局错乱。
🕵️ 问题分析
经过排查,发现问题出在:
如果 Obsidian 的 Markdown 中插入了视频链接(如.mov
文件),自动生成的封面图提取逻辑会错误地把.mov
当成图片来显示。
而首页模板会这样写:
<img src="xxx.mov" />
👉 这在 HTML 中是非法的,浏览器无法渲染视频为图片,导致封面图加载失败。
🔧 根本原因
主题中负责提取封面图的函数如下(原始版本):
function getFirstImageFromContent($content) {
$output = preg_match_all('/<img.+src="([^"]+)"/i', $content, $matches);
if ($output && !empty($matches[1])) {
return $matches[1][0]; // 无论是什么格式都直接返回
}
return false;
}
⚠️ 它只是提取了第一个 <img src="...">
,但没有判断是不是图片格式。
✅ 修复方法
我将函数修改为以下更健壮的版本:
function getFirstImageFromContent($content) {
preg_match_all('/<img[^>]+src=["\']([^"\']+)["\']/i', $content, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $url) {
if (preg_match('/\.(jpg|jpeg|png|gif|webp)$/i', $url)) {
return $url;
}
}
}
return false;
}
改动说明:
- 提取所有
<img>
标签的src
- 遇到
.mov
、.mp4
等非图片格式的 URL 自动跳过 - 直到遇到第一个图片 URL 才返回
- 如果完全找不到图片,则返回
false
(可以在模板中使用默认图兜底)
✅ 修复效果
修复后首页恢复正常:
- 不再错误显示视频链接为图片
- 自动跳过视频,选取后面的
.jpg
或.png
- Markdown 中继续可以插入视频,不影响首页展示