博友圈展示博友文章的好处
个人博客没有评论是没有灵魂的,而博客互访才是博客的运营之道。老张在《如何有效的博客互访、互评!》等众多文章里都提到博客互访的重要性。在没有接触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文件!