Z-Blog 主题取缩略图,我找了半天没这个属性

· zblog · 阅读 5
摘要

想在列表页给每篇文章配张缩略图,我下意识去翻 $article->Thumb。翻不到。Z-Blog 的 Post 对象里没有这个东西,也没有 WordPress 那套「特色图像」,得自己想办法。这点我第一次用的时候挺不适应。 先看 Meta

想在列表页给每篇文章配张缩略图,我下意识去翻 $article->Thumb。翻不到。Z-Blog 的 Post 对象里没有这个东西,也没有 WordPress 那套「特色图像」,得自己想办法。这点我第一次用的时候挺不适应。

先看 Metas 里有没有,再决定要不要抓正文

比较常见的做法是在文章编辑页加个自定义字段,键名一般叫 thumbnail,存在 $article->Metas->thumbnail。读出来不长:

// zb_users/theme/你的主题/include.php
function theme_thumb($article, $default = ''){
    if (isset($article->Metas->thumbnail) && $article->Metas->thumbnail) {
        return $article->Metas->thumbnail;
    }
    if (preg_match('/<img[^>]+src="([^"]+)"/i', $article->Content, $m)) {
        return $m[1];
    }
    return $default;
}

那层 isset 别省。字段没填的时候 Metas 是个空对象,直接取值拿到 null,模板里就输出一段空的 src,浏览器转头去请求当前页地址。页面上看着没事,Network 面板里一片 404。我第一次就是这么过去的。

正文抓首图只能当兜底

正则抓 $article->Content 里第一张图,看着简单,实际问题不少。外链图可能防盗链,懒加载的图 src 是个占位符、真地址在 data-src。所以匹配的时候把两个属性都带上:

if (preg_match('/<img[^>]+(?:data-src|src)="([^"]+)"/i', $article->Content, $m)) {
    return $m[1];
}

还有个更尴尬的:文章第一张图可能是表情包或者截图边角,抓出来放进列表卡片特别难看。所以我的习惯还是优先读 Metas,没填才退回正文图,最后给一张默认图。三级兜底,别嫌麻烦。

性能这块我实测过,两千篇的列表里跑一遍 preg_match,肉眼没看出区别。Content 本来就已经在内存里了,不是瓶颈。

模板里怎么调

函数写在主题的 include.php 里,模板里直接调,花括号内是可以跑 PHP 的:

{theme_thumb($article, $zbp->host . 'zb_users/theme/你的主题/style/noimg.png')}

顺手把 alt 补上,用 {$article.Title}。我见过不少主题这里直接空着,图片多了对 SEO 一点好处没有。至于缩略图要不要裁剪成统一尺寸——Z-Blog 没有内置的缩略图生成,想统一比例只能 CSS 配合 object-fit: cover,这个我试过,比在 PHP 里算尺寸省事得多。