阅读视图

发现新文章,点击刷新页面。

在折腾中寻找完美

不知不觉这个主题在我手中用了快两年了,由于水平有限,问题也多多,在边用边折腾中,某些问题也是在慢慢完善和改进。

利用RSS订阅功能添加博友圈,实时展示博友最新文章!

博友圈展示博友文章的好处

个人博客没有评论是没有灵魂的,而博客互访才是博客的运营之道。老张在《如何有效的博客互访、互评!》等众多文章里都提到博客互访的重要性。在没有接触RSS订阅工具之前,老张都是在浏览器的收藏夹里收藏了一两百个博客,每天都要打开一次,但是这近两百个博客中其实只有十来个博客更新内容,所以这样操作浪费了大量的时间。后来有了RSS工具,可以对常访的博客进行订阅,当博客有文章更新时,就会得到通知。但是这样操作也有一个弊端,你的博客每天都会打开好几次,但是RSS订阅工具却不是常打开。这个时候我们可以利用RSS订阅功能添加博友圈,在自己的博客上实时看到博友们更新的内容而可以及时的进行访问评论。

利用RSS订阅功能添加博友圈,实时展示博友最新文章的好处是不言而喻的,首先对于博主来说,不必频繁的打开RSS工具而可以第一时间知道博友的文章更新而进行访问评论,于博友来说,也可以说是得到了到别人博客上的展示,极大了增加了博客的用户体验、极大了增强博友之间的互动、极大增强了博友们博客的曝光度。

我的“博友圈”的入选标准

博友圈不是友情链接,我的博友圈是都是我常访问的一些博客,目前收集了近一百五十个博客。能和老张博客互评达到四五次的,博客原创文章能及时更新的我都会收集到我的博友圈。这样,你的最新文章也就可以展示到我的博客的博友圈里。

如何添加博友圈

搭建rss订阅服务-FreshRSS

关于RSS订阅工具,老张博客在以前折腾过很多,RSS订阅工具的文章也写了有十来篇,其实《RSS订阅工具miniflux、tiny tiny rss、freshrss使用体会》对常用的几个RSS订阅工具进行了全面的比较,有兴趣的可以看看。FreshRSS的项目地址是https://github.com/FreshRSS/FreshRSS/我按照官方的方法Doocker部署一直没有成功,用宝塔的Docker面板部署也没有成功,后来按小宋的《搭建一个自己的rss订阅服务-FreshRSS》方法得要成功,不知什么原因。

docker run -d --restart unless-stopped --log-opt max-size=10m \
-p 8880:80 \
-e TZ=Europe/Paris \
-e 'CRON_MIN=1,31' \
-v /www/dockerdata/freshrss/data:/var/www/FreshRSS/data \
-v /www/dockerdata/freshrss/extensions:/var/www/FreshRSS/extensions \
--name freshrss \
freshrss/freshrss

直接SSH到服务器,运行以上代码,常访问我的博客或是常折腾Docker的小伙伴都可以看懂上面的代码意思,这里就不再多表了。

完成后打开你的IP+端口,就可以安装FreshRss了,成功之后,一定要执行以下两步

1.安装完成后进入设置-账户-API 管理,填写api密码提交。

2.进入设置-认证,勾选允许 API 访问 (用于手机应用),提交。

实现博友圈实时展示最新文章

这里我参考了小段的《跟风利用FreshRSS实现朋友圈》文章,但是遇到了几个坑,给大家提醒下。

3.在自己站点根目录下创建一个php文件,命名为rss.php,将以下代码复制进去。此文件用于放FreshRSS api调用函数,例如:rss.php。访问https://你的博客域名/rss.php,显示数据已保存到JSON文件中。

<?php
/**
 * 获取最新订阅文章并生成JSON文件
 */
function getAllSubscribedArticlesAndSaveToJson($user, $password)
{
    $apiUrl = 'https://你部署FreshRSS的域名/api/greader.php';
    $loginUrl = $apiUrl . '/accounts/ClientLogin?Email=' . urlencode($user) . '&Passwd=' . urlencode($password);
    $loginResponse = curlRequest($loginUrl);
    if (strpos($loginResponse, 'Auth=') !== false) {
        $authToken = substr($loginResponse, strpos($loginResponse, 'Auth=') + 5);
        $articlesUrl = $apiUrl . '/reader/api/0/stream/contents/reading-list?&n=1000';
        $articlesResponse = curlRequest($articlesUrl, $authToken);
        $articles = json_decode($articlesResponse, true);
        if (isset($articles['items'])) {
            usort($articles['items'], function ($a, $b) {
                return $b['published'] - $a['published'];
            });
            $subscriptionsUrl = $apiUrl . '/reader/api/0/subscription/list?output=json';
            $subscriptionsResponse = curlRequest($subscriptionsUrl, $authToken);
            $subscriptions = json_decode($subscriptionsResponse, true);
            if (isset($subscriptions['subscriptions'])) {
                $subscriptionMap = array();
                foreach ($subscriptions['subscriptions'] as $subscription) {
                    $subscriptionMap[$subscription['id']] = $subscription;
                }
                $formattedArticles = array();
                foreach ($articles['items'] as $article) {
                    $desc_length = mb_strlen(strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8')), 'UTF-8');
                    if ($desc_length > 20) {
                        $short_desc = mb_substr(strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8')), 0, 99, 'UTF-8') . '...';
                    } else {
                        $short_desc = strip_tags(html_entity_decode($article['summary']['content'], ENT_QUOTES, 'UTF-8'));
                    }
                    
                    $formattedArticle = array(
                        'site_name' => $article['origin']['title'],
                        'title' => $article['title'],
                        'link' => $article['alternate'][0]['href'],
                        'time' => date('Y-m-d H:i', $article['published']),
                        'description' => $short_desc,
                    );

                    $subscriptionId = $article['origin']['streamId'];
                    if (isset($subscriptionMap[$subscriptionId])) {
                        $subscription = $subscriptionMap[$subscriptionId];
                        $iconUrl = $subscription['iconUrl'];
                        $filename = 'https://你部署FreshRSS的域名'.substr($iconUrl, strrpos($iconUrl, '/') + 1);
                        $formattedArticle['icon'] = $filename;
                    }

                    $formattedArticles[] = $formattedArticle;
                }

                saveToJsonFile($formattedArticles);
                return $formattedArticles;
            } else {
                echo 'Error retrieving articles.';
            }
        } else {
            echo 'Error retrieving articles.';
        }
    } else {
        echo 'Login failed.';
    }
    return null;
}
function curlRequest($url, $authToken = null)
{
    $ch = curl_init($url);
    if ($authToken) {
        $headers = array(
            'Authorization: GoogleLogin auth=' . $authToken,
        );
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}
/**
 * 将数据保存到JSON文件中
 */
function saveToJsonFile($data)
{
    $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    file_put_contents('output.json', $json);
    echo '数据已保存到JSON文件中';
}

// 调用函数并提供用户名和密码
getAllSubscribedArticlesAndSaveToJson('这里是FreshRSS的用户名', '这里是第3步设置的api密码');

注意修改代码的几处设置。设置好处,直接用浏览器访问https://你的博客域名/rss.php,就会显示“数据已保存到JSON文件中”,表示成功了。

注意一个小坑:两处"你部署FreshRSS的域名",一定要是你的FreshRss设置-账户-API管理里的地址,如果是IP地址,可以修改Freshrss的配置文件改成域名。这个时候有部分地址是有“/p/”这个目录年,一定要看清了。

这个时候注意一个大坑,最开始我的PHP版本是8.0的,访问https://你的博客域名/rss.php死活报错,折腾好长时间也不成功,最后换服务器PHP版本是7.4成功了,不知道是什么原因造成的,但是结果我们却知道了,就是PHP8.0不成功。解决方法是把RSS.php文件放在其他网站上,在第4步代码中“./output.json”修改为“https://放rss.php文件的网站/output.json”

4.主题的funtions.php里添加以下代码:

// 在 functions.php 中添加 shortcode 函数
function display_articles_shortcode() {
    // 获取JSON数据
    $jsonData = file_get_contents('./output.json');
    // 将JSON数据解析为PHP数组
    $articles = json_decode($jsonData, true);
    // 对文章按时间排序(最新的排在前面)
    usort($articles, function ($a, $b) {
        return strtotime($b['time']) - strtotime($a['time']);
    });
    // 设置每页显示的文章数量
    $itemsPerPage = 30;

    // 生成文章列表
    ob_start(); // 开始缓存输出
    foreach (array_slice($articles, 0, $itemsPerPage) as $article) {
    ?>
        <div class="article">
            <h3>
                <img src="<?php echo htmlspecialchars($article['icon']); ?>" alt="Icon" class="icon">
                <a href="<?php echo htmlspecialchars($article['link']); ?>" target="_blank"><?php echo htmlspecialchars($article['title']); ?></a>
            </h3>
            <p>作者:<?php echo htmlspecialchars($article['site_name']); ?></p>
            <p><?php echo htmlspecialchars($article['description']); ?></p>
            <time><?php echo htmlspecialchars($article['time']); ?></time>
        </div>
    <?php
    }
    return ob_get_clean(); // 返回缓存的输出并清除缓存
}

// 注册简码
add_shortcode('display_articles', 'display_articles_shortcode');

5.自定义css样式

/* Article container */
.article {
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 15px;
    margin-bottom: 20px;
}

/* Article title */
.article h3 {
    margin-top: 0;
}

/* Article icon */
.icon {
    width: 50px;
    height: 50px;
    margin-right: 10px;
    border-radius: 50%;
}

/* Article metadata */
.article p, .article time {
    margin: 5px 0;
}

/* Article time */
.article time {
    font-style: italic;
}

/* Hover effect on article */
.article:hover {
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    transition: box-shadow 0.3s ease;
}
/* Article icon */
.icon {
    width: 1.5em; /* 使用 em 单位可以根据标题字体大小调整图标大小 */
    height: auto; /* 自动调整高度以保持宽高比 */
    margin-right: 10px;
    vertical-align: middle; /* 垂直居中对齐 */
    border-radius: 50%;
}

以上代码可以直接写在主题的CSS文章里,也可以在主题的自定义样式里添加。

6.新建页面,在代码文本模式下输入[display_artices]

7.在宝塔面板下创建一个计划合作,每1小时或2小时访问一次https://你的博客域名/rss.php,这样达成生成最新的output.json文件以便博友圈调取展示。

至此,已全部完成,样式可以自行修改CSS文件!

 

 

 

 

如何有效的博客互访、互评!

老张在《如何经营好个人独立博客》就阐述过自己的观点,个人独立博客不是孤立博客,当你的博客文章展示在大家面前的时候,更想的就是想和博友们交流交流自己所写的观点,这个时候那就必须要用到的是“评论”!那怎么样做好与其他博客的互访、互评呢!

有效订阅他人博客

想要有效的进行博客互访,博客圈不可少。老张在建立博客之初,为了能更好的进行博客互访,在浏览器的收藏夹里收藏了近有200个博客地址。每天都会把这200个博客打开一次,看看哪个博客文章有更新,更新了就会及时的进行评论。这个方法真的是太耗时了,主要大部分博客不能及时更新。那我们就需要“订阅功能”。后来才知道有RSS订阅这回事。

简单地说,就是通过RSS订阅工具订阅博客,当博客文章有更新时在工具里会有显示,这个时候你再去进行访问、评论,更有效。对于RSS工具这块,老张在几年前折腾的比较多,那个时候主打是自己部署,在《RSS订阅工具miniflux、tiny tiny rss、freshrss使用体会》和《RSS订阅工具推荐-蚁阅,暨RSS订阅源分享!》有过详细的介绍。

博客做久了,老张将《将博客减法进行到底!》,有些服务就不再自己部署。目前订阅工具用的是蚁阅和innoreader,innoreader免费用户只能有150个订阅源,对个博客互访来说,这150个订阅源也是足够了。老张会对这150个订阅源不定期进行整理,失效的、超过半年不更新的会进行清理。同时会不断增加新的订阅源。

小胡同学的《如何订阅一个博客?》介绍的更为具体,可以移步过去学习学习。

为他人留下“网址”

评论系统的文本输入框是基本的包含昵称、邮箱、网址、评论内容。但是,有一部分博主却在后台把“网址”给屏蔽掉了。你既想让别人评论,却又不想让别人留下网址,不留下网址,你怎么进行“回访”呢!不管出于什么原因,把网址输入框屏蔽这个做法是不可取的。说真的,遇到这样的博客,我是直接关掉走人。

做好评论邮件通知

评论邮件通知这个功能还是很有必要做的,实现这个功能需要相应的插件来完成,不过现在很多主题的功能比较强大,就自带有评论邮件通知的设置。评论邮件通知,是做好博客互访、更评的一个有效的途径。当别人评论了你的文章,你进行了回复评论,对方就会收到邮件通知后,就会有选择性的再进行回复,以达到有效的互动。

走心的评论

说真的,有一部分人(这部分人也包含我^^)进行博客评论时就是过个场,有时评论内容和博客内容都扯不上边,唉!评论别人的博客,不要求长篇大论,至少与文章内容对得上题。

用心的回评

我的原则是,只要有评论,那我是必回复。所以当你看到我的一些文章的评论数达到五六十时,其实这个数字里面有一半是我对博友的回评。你走心的评论那我就用心的回评。

独立不孤立,个人博客就需要做好与其他博客的“互动”,把博客互访、互评做好,才是个人博客的精华。

 

 

❌