handsome 主题自带“引用其他文章”和“手动指定摘要内容”功能,但二者其实并不适配。笔者个人觉得“手动指定摘要内容”功能更应当交由插件实现(挂 excerpt 钩子),但这超过了本文讨论范围,不具体展开。直接在文章中插入“引用其他文章”的代码,会解读出文章本身的内容并截取作为引用块的摘要,感觉有些不协调。

  笔者出于强迫症,考虑从代码层面一次性根本解决这个问题。定位至“引用其他文章”功能实现的核心步骤 Content::quoteOtherPostCallback()(libs/Content.php),代码就不贴了,可以见到此处是没有被引用文章的上下文的,为了获取文章的信息还要执行 SQL 进行查询。这里作者显然查了头图数组typecho 文章摘要,但是竟并没有查自定义摘要数组。

  这里帖一个小方法(来自 Typecho 源代码),如何性感地按照 cid 查询自定义数组:

  首先肯定是要查一次数组表的,也就是 prefix_fields 表,这里的 prefix_ 是安装时设置的数据表前缀。第一个问题就是怎么获取这个前缀,但实际上 Typecho 包装的数据库驱动可以使用 table.xxx 代替 prefix_xxx,那么就不再还要自动获取这个前缀,即:

  $db->fetchAll($db->select()->from('table.fields')->where('cid = ?', $cid));

  这样一句话将要返回 $cid 文章的所有数组,但是这还不够,对其进行一下加工:

   $fields = array();

    $rows = $db->fetchAll($db->select()->from('table.fields')->where('cid = ?', $cid));
    foreach ($rows as $row) {
        $fields[$row['name']] = $row[$row['type'] . '_value'];
    }

  这样处理以后得到的 $fields(显而易见**typecho 文章摘要**,是一个 Typecho_Config 对象)对应的成员就保存着对应自定义数组的值。例如 $fields->xxx。

  回到自动指定摘要,该数组对应的内部名称为 customSummary,这时我们就用 $fields->customSummary 来访问它。

   if (trim($fields->customSummary) != "") {

        $targetSummary = $fields->customSummary;
    } else {
        $targetSummary = Content::excerpt(Markdown::convert($result['text']), 60);

  那么修改后的完整代码就是这样:

<p><pre> /**

 * 一篇文章中引用另一篇文章正则替换回调函数
 * @param $matches
 * @return bool|string
 */
public static function quoteOtherPostCallback($matches){
    $options = mget();
    // 不解析类似  双重括号的代码
    if ( $matches[1] == '[' && $matches[6] == ']' ) {
        return substr($matches[0], 1, -1);
    }
    //对$matches[3]的url如果被解析器解析成链接,这些需要反解析回来
    $matches[3] = preg_replace("/<a href=.*?>(.*?)/",'$1',$matches[3]);
    $attr = htmlspecialchars_decode($matches[3]);//还原转义前的参数列表
    $attrs = self::shortcode_parse_atts($attr);//获取短代码的参数
    //这里需要对id做一个判断,避免空值出现错误
    $cid = @$attrs["cid"];
    $url = @$attrs['url'];
    $cover = @$attrs['cover'];//封面
    $targetTitle = "";//标题
    $targetUrl = "";//链接
    $targetSummary ="";//简介文字
    $targetImgSrc = "";//封面图片地址
    if (!empty($cid)){
        $db = Typecho_Db::get();
        $prefix = $db->getPrefix();
        $posts = $db->fetchAll($db
            ->select()->from($prefix.'contents')
            ->orWhere('cid = ?',$cid)
            ->where('type = ? AND status = ? AND password IS NULL', 'post', 'publish'));
        //这里需要对id正确性进行一个判断,避免查找文章失败
        if (count($posts) == 0){
            $targetTitle = "文章不存在,或文章是加密、私密文章";
        }else{
            $result = Typecho_Widget::widget('Widget_Abstract_Contents')->push($posts[0]);
            $fields = array();
            $rows = $db->fetchAll($db->select()->from('table.fields')->where('cid = ?', $cid));
            foreach ($rows as $row) {
                $fields[$row['name']] = $row[$row['type'] . '_value'];
            }
            $fields = new Typecho_Config($fields);
            if ($cover == "") {
                $targetImgSrc = Content:: whenSwitchHeaderImgSrc(0, 2, null, $result['text'], @$fields->thumb, 1);
            } else {
                $targetImgSrc = $cover;
            }
            if (trim($fields->customSummary) != "") {
                $targetSummary = $fields->customSummary;
            } else {
                $targetSummary = Content::excerpt(Markdown::convert($result['text']), 60);
            }
            $targetTitle = $result['title'];
            $targetUrl = $result['permalink'];
        }
    }else if (empty($cid) && $url !=""){
        $targetUrl = $url;
        $targetSummary = @$attrs['intro'];
        $targetTitle = @$attrs['title'];
        $targetImgSrc = $cover;
    }else{
        $targetTitle = "文章不存在,请检查文章CID";
    }
    $imageHtml = "";
    $noImageCss = "";
    if (trim($targetImgSrc) != ""){
        $imageHtml = '

';

    }else{
        $noImageCss = 'style="margin-left: 10px;"';
    }
    return 
Last modification:January 1st, 2021 at 01:04 am
如果觉得我的文章对你有用,请随意赞赏