前言

在用 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(',');?>" />

引用和感谢