给 Typecho 文章设置 meta data 让链接预览时具有标题、简介以及缩略图

warning: 这篇文章距离上次修改已过862天,其中的内容可能已经有所变动。

前言

在用 Slack、Mattermost、钉钉、飞书、Telegram 的时候,聊天中发出 Typecho 博客文章的链接之后,我看到并没有漂亮的链接预览信息。事实上我发现国内很多网站都没有做这个优化,这点上显然国外的网站支持得更好。

还有一点,微信的编辑区是完全不支持 link preview 的,想要这个功能?张xiǎo🐲:想得美

正文

meta 标签的信息是描述 HTML 文档的元数据。这些元数据不会显示在客户端,但是会被浏览器解析,meta 标签内的元素通常用于指定网页的描述,关键词,文件的最后修改时间,作者及其他元数据。它可以被浏览器使用(如何显示内容或重新加载页面),被搜索引擎(关键词)使用,或其他 Web 服务调用。<meta> 标签一般位于 HTML 文档的 <head> 区域内。

Open Graph Protocol(开放图谱协议),简称 OG 协议。它是 Facebook 在 2010 年 F8 开发者大会公布的一种网页元信息(Meta Information)标记协议,属于 Meta Tag(Meta 标签)的范畴,是一种为社交分享而生的 Meta 标签。就是来标注页面的类型和描述页面的内容。我的博客文章链接发到 Slack 聊天区不能生成漂亮的预览就是因为没有支持 og 协议。

更多介绍可以阅读本文底部 引用 部分的 html metaFacebook The Open Graph protocol

下面开始详细说明。
昨晚发现 GitHub 仓库的链接在 Slack、Mattermost 等软件打开了 preview link 的功能之后,在聊天框能生成漂亮的链接预览。不得不说,GitHub 的做得很精致,信息也很全。

github的效果

于是我试了下我的 Typecho 文章链接,尴尬了哈哈(上面那个是处理前,下面链接是处理后的效果)。

对比

我回想起来以前使用钉钉的时候也是 -_-

于是就着手修改,我想实现的目标有

  1. 显示本站的标题
  2. 显示文章的 title
  3. 显示文章的 description
  4. 显示文章的第一张图片,如果那篇文章没有配图,则使用站点 logo

在经过了一番努力之后,实现了!效果如下

处理后


下面来讲一下实现的过程和代码。

要想实现上面目标的第四点,需要在 functions.php 写一个获取文章首图的 method,返回的是图片的 direct link,在 header.php 中引入这个函数,传入文章的 cid (就是文章表的主键)。

考虑到文章中引用的图片不一定来自本站,所以我就直接返回图片的直链,因为看到有些博客的图片全都放在他博客的那台服务器上,所以有些人使用的是相对链接,看起来类似 /usr/uploads/.../xxxx.jpg

function getPostFirstImg($cid) {
    $db = Typecho_Db:: get();
    $rs = $db -> fetchRow($db -> select('table.contents.text')
        -> from('table.contents')
        -> where('table.contents.cid=?', $cid)
        -> order('table.contents.cid', Typecho_Db:: SORT_ASC)
        -> limit(1));
    $imgUrl = [];
    $num = preg_match_all("/http(.*?)(.jpg|.png)/", $rs['text'], $imgUrl);
    if ($num == 0) {
        // 这是我博客的站点 logo 图片 direct link
        return 'https://img.gejiba.com/images/078696031158bfa46081354582567662.png';
    } else {
        return $imgUrl[0][0];
    }
}

然后在 header.php 适当位置添加如下代码

<meta property="og:site_name" content="<?php $this->options->title() ?>" />
<meta property="og:type" content="article" />
<meta property="og:url" content="<?php $this->permalink() ?>" />
<meta property="og:title" content="<?php $this->title() ?>" />
<meta property="og:description" content="<?php $this->description(); ?>" />
<meta property="og:image" content="<?php echo getPostFirstImg($this->cid); ?>" />
<meta property="og:category" content="<?php $this->category(',', false); ?>" />
<meta property="article:author" content="<?php $this->author(); ?>" />
<meta property="article:publisher" content="<?php $this->options->siteUrl(); ?>" />
<meta property="article:published_time" content="<?php $this->date('c'); ?>" />
<meta property="article:published_first" content="<?php $this->options->title() ?>, <?php $this->permalink() ?>" />
<meta property="article:tag" content="<?php $this->keywords(',');?>" />

引用和感谢

最后修改于:2023年08月06日 10:03

已有 6 条评论

  1. ATP ATP

    感谢分享,以前用 Hugo 的貌似自带 og 生成,换 Typecho 后就一直都忘了...看到你的文章终于想起得折腾下了,不过文章图片因为域名证书问题挂了~?

    1. 谢谢提醒,刚才重新搞了几张截图把文章图片补上了,你可以再预览一遍文章?。这提醒我再也不要用别人 开源用爱发电 的图床。现在只用自己的图床了,对自己负责。

  2. 写得不错,有一个网站可以检测OG协议预览的https://www.opengraph.xyz/,可惜我typecho博客的主题是handsome不能直接用你写的方法。

    1. 非常感谢你贴出的网址,这个检测服务不错。大名鼎鼎的 handsome,没用过?️。不可以改一下兼容 handsome 么

      1. 我的技术还差点火候,还不足以我自己改主题,已经呼叫handsome主题作者改了,说不定未来某个版本就会支持了。你这篇文章算是全网第一篇支持OG协议的typecho的教程,膜拜大佬。不过为啥你的提醒邮件会放到垃圾箱里面,差点没发现?

        1. 被识别成了垃圾邮件,这个说来挺复杂的…… 你可以标记一下 这不是垃圾邮件?

添加新评论