Typecho 文档:给博客 Feed 添加指定文章评论 Feed

2023-09-09

适用程序:Typecho
程序版本:1.2.1
文档作者:Lopwon
作者博客:Lopwon.com
发布页面:Lopwon.com/3557.html

注意:此文档源于作者在博客改造中的一些经验总结,转载还请署名。

敬告:此文档操作涉及程序核心文件的修改,作者不对你在使用中产生的任何问题造成的不良后果,承担责任。

文档说明

本文档源自网友 #目的地-Destination 提出的需求:在博客 Feed 订阅源页面中,输出指定文章(如:说说)下的评论 Feed 内容,让小伙伴在订阅博客 Feed 时,也能看到博主的(说说)动态信息。

工作原理:Typecho 有博客 Feed 显示博客最新 10 篇文章,另外,还有文章 Feed 展示文章内容和该文章下的评论信息,而部分博客的(说说)功能,刚好是使用文章下的评论作为心情动态的提交发布。本文档即是把指定文章下的评论信息,整合到博客 Feed 页面中。


使用方法

A 涉及文件

var/Widget/Archive.php

B 改造文件

作用:给博客 Feed 添加指定文章评论 Feed

打开文件 var/Widget/Archive.php 搜索找到第 1477 行,将 else {...} 里的代码全部替换为以下代码(留意注释,以及按需修改):

    /**
     * 文章
     */
            
    $this->feed->setTitle($this->options->title . ($this->archiveTitle ? ' - ' . $this->archiveTitle : null));

    $postArr = [];

    while ($this->next()) {
        $suffix = self::pluginHandle()->trigger($plugged)->feedItem($this->feedType, $this);        
        if (!$plugged) {
            $suffix = null;
        }

        $feedUrl = '';
        if (Feed::RSS2 == $this->feedType) {
            $feedUrl = $this->feedUrl;
        } elseif (Feed::RSS1 == $this->feedType) {
            $feedUrl = $this->feedRssUrl;
        } elseif (Feed::ATOM1 == $this->feedType) {
            $feedUrl = $this->feedAtomUrl;
        }

        $postArr[] = [
            'title'           => $this->title,
            'content'         => $this->options->feedFullText ? $this->content
                : (false !== strpos($this->text, '<!--more-->') ? $this->excerpt .
                    "<p class=\"more\"><a href=\"{$this->permalink}\" title=\"{$this->title}\">[...]</a></p>"
                    : $this->content),
            'date'            => $this->created,
            'link'            => $this->permalink,
            'author'          => $this->author,
            'excerpt'         => $this->___description(),
            'comments'        => $this->commentsNum,
            'commentsFeedUrl' => $feedUrl,
            'suffix'          => $suffix
        ];

    }

    $postItemArr = [];

    foreach ($postArr as $postItem) {
        $postItemArr[] = $postItem;
    }

    /**
    * 评论
    */

    $comments = Recent::alloc('pageSize=5&parentId=2'); // pageSize=5 为输出评论的数量;parentId=2 为指定文章的 cid

    $commentArr = [];

    while ($comments->next()) {
        $suffix = self::pluginHandle()->trigger($plugged)->commentFeedItem($this->feedType, $comments);
        if (!$plugged) {
            $suffix = null;
        }

        $commentArr[] = [
            'title'   => strlen(strip_tags($comments->content)) > 0 ? strip_tags($comments->content) : '图片说说,点击查看', // 如果评论(说说)中只有图片或表情图标,没有文字时,输出自定义提示内容
            'content' => $comments->content,
            'date'    => $comments->created,
            'link'    => $comments->permalink,
            'author'  => (object)[
                'screenName' => $comments->author,
                'url'        => $comments->url,
                'mail'       => $comments->mail
            ],
            'excerpt' => strlen(strip_tags($comments->content)) > 0 ? strip_tags($comments->content) : '图片说说,点击查看',
            'suffix'  => $suffix
        ];
    }

    $commentItemArr = [];

    foreach ($commentArr as $commentItem) {
        if ($commentItem['author']->screenName == $comments->author) { // 只输出博主的评论,或把 $comments->author 改为 '博主登录名'
            $commentItemArr[] = $commentItem;
        }
    }

    /**
    * 合并排序
    */

    $moodArr = array_merge($postItemArr, $commentItemArr);

    usort($moodArr, function($a, $b) {
        return $b['date'] - $a['date'];
    });

    foreach ($moodArr as $mood) {
        $this->feed->addItem($mood);
    }

注意:请将以上代码中,有注释行的参数修改为自己需要的,作用是:将指定页面、指定数量的评论输出到博客 Feed 中,该数量不受博客 Feed 默认的 10 篇影响,也就是博客 Feed 输出的数量将变更为(10 + 评论数量),如果需要修改博客 Feed 默认的 10 篇数量,请修改第 276 行的 pageSize=10 数量。

至此,访问博客 Feed 地址后,就能看到输出的指定文章下的评论信息了,并且,文章和评论(说说)按照发布时间混合排序。

感谢观赏

支持作者:Buy Me a 冰棒

Store

15 条评论

  1. 目的地-Destination 52

    哈哈哈,好久没来了。老哥也不更新插件了吗?今天发现个问题,别人回复主评论的评论,也会被放到Feed中。这个应该怎么处理下呢。正常来说,应该只放主评论的

    1. Lopwon Lopwon 博主
      @ 目的地-Destination

      把评论加入数组时做判断,只要博主的评论,文档已更新。

      1. 目的地-Destination 52
        @ Lopwon

        感谢老哥。我昨天也想到一种方法,这里多拼一个where条件`$comments = Recent::alloc('pageSize=10&parentId=6&isZhu=true');`,然后在Recent里也多加了一个。这样也可以。不过要比你的多改一个地方了。哈哈

  2. 目的地-Destination 52

    老哥,有个新问题,需要优化下了。有的博客无法刷新我的feed,用rss校验工具,https://validator.w3.org/feed/check.cgi?url=https%3A%2F%2Fblog.chrison.cn%2Ffeed%2F 发现,如果评论中,只有图片或者表情,那么这段代码的title就会缺失。是不是要判断把这种过滤掉,或者给个默认标题?

    1. Lopwon Lopwon 博主
      @ 目的地-Destination

      我改过一次代码,你可能使用的是旧代码,评论标题原来是输出作者名称,改过后是输出评论内容。

      1. 目的地-Destination 52
        @ Lopwon

        对了,我试了“'excerpt' => strip_tags($comments->content),” 这一行也要改成和title一样,要不然会提示description为空。改了就完全没问题了

        1. Lopwon Lopwon 博主
  3. 目的地-Destination 52

    老哥,有个疑问。```$result .= $content . $moods . '``` ,这段代码,是把两个循环数据拼在一起了,有个发布时间的问题,moods永远是排在后面的,实际程序获取feed的时候,好像是从上到下获取的?新发布的说说,并不能显示出来

    1. Lopwon Lopwon 博主
      @ 目的地-Destination

      $moods 不属于 $content 的循环内,也就是 $content 默认输出最新 10 篇文章,也就是 10 个 item 而 $moods 是独立的 item 紧跟着 $content 最后一个 item 我在测试中是正常显示的。

      1. 目的地-Destination 52
        @ Lopwon

        我的意思是,如果feed直接读全部数据,那必然就是10条文章,10条说说,但是说说永远排在文章10条的后面,因为不是时间排序的。使用Lopwon Feed插件,一般就读前3条,或者其他博客只读取最新一条,说说是获取不到的。我试过了,把$content 和$moods调换位置,说说才能拿到,但是文章就排在后面了。是这个意思

        1. Lopwon Lopwon 博主
          @ 目的地-Destination

          方法一:拼贴输出,也就是当前的效果,文章输出 5 条,说说输出 5 条,搜索文件 var/Widget/Archive.php 第 289 行,修改 $parameter->pageSize = 10; 的文章数量为 5。

          方法二:混合输出,也就是 10 条信息中,文章和说说按照时间顺序先后输出。修改文件 var/Widget/Archive.php 第 1518 行,给数组 $this->feed->addItem 做判断,这个方法可能更适合,有空我研究下。

          1. 目的地-Destination 52
            @ Lopwon

            是的,混合判断好一些。无奈我只能说想法,无法下手。[笑哭]

            1. Lopwon Lopwon 博主
              @ 目的地-Destination

              文档已更新,注意,要改造的文件已变更。

              1. 目的地-Destination 52
                @ Lopwon

                搞定嘞,感谢老哥。 这篇教程,我可以转载到我博客么,会标注来源的!

                1. Lopwon Lopwon 博主

准备下山 准备下山
Snapic Plus v5
使用 Lopwon POP 实现