前言
最开始我用的是阿锋的朋友圈插件,这是我第一次见把友链整合到RSS订阅把它展现出来,那会儿很好奇,就使用了阿锋的晨风自定义插件。后面看到了hexo-circle-of-friends,网上找了半天没看到WordPress上面实现的方法。后面才看到了若志的这篇文章,索性就搞了起来。
实现步骤
首先要搭建FreshRSS,这个教程很多,我使用的是服务器搭建,纯宝塔操作,简单不复杂。
1、添加站点,注意:需要确认已经安装了 PHP 扩展 fileinfo(我的默认安装了)。接下来在宝塔面板创建新站点,设置好数据库与 PHP 版本。数据库我选择的是mysql,PHP版本是0。然后,删去网站根目录下默认添加创建的所有文件,确保文件夹全部清空。打开站点根目录,把 FreshRSS 源代码上传到网站根目录,域名访问开始安装。
2、安装完成后进入设置-账户-API 管理,填写api密码提交。
3、进入设置-认证,勾选允许 API 访问 (用于手机应用),提交。
4、添加你的友链feed地址,我试了一下,直接输入友链域名大部分的rss地址可以自动获取,少部分不知道rss地址的可以安装浏览器插件查看或者问博主本人。
5、不知道是不是我安装的有问题,点击添加的友链管理,会弹出502 Bad Gateway nginx。不过双击还是就进去了,可以进行删除修改等操作,凑合着用吧。
6、在自己站点根目录下创建一个php文件,用于放FreshRSS api调用函数,例如:rss.php。访问https://你的博客域名/rss.php,显示数据已保存到JSON文件中。
<?php
/**
* 获取最新订阅文章并生成JSON文件
*/
function getAllSubscribedArticlesAndSaveToJson($user, $password)
{
$apiUrl = 'https://你部署FreshRSS的域名/p/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的域名/p/'.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://你部署FreshRSS的域名/p/,没证书是http(最好带上证书,不然图标获取不到),还有后面的/p/. 新建页面,在正文里面输入简码:
7、我是用的是添加页面使用简码将其显示出来,在子主题的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');
8、可以自定义css样式让其精致的显示,这是我的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%;
}
9、在宝塔添加一个计划任务,定时访问执行第6步创建的php文件,以更新订阅数据。官网里说的那个自动刷新订阅源的方法,我按照官网设置了每隔30分钟刷新,不知道咋回事儿不管用,每次都要自己刷新后才更新订阅源。
结语
自己部署rss订阅源是一件非常有成就感的事儿,过程也是艰辛,尤其是我这种不会代码的,更是辛苦,一步一步地查看错误,幸好有GPT,帮我可以查找问题,解决问题,不至于求人。