偶然间看到别的博客通过rss订阅建立了一个友链博友圈,主要通过rss做实时展示一些友链博主更新的博文。不得不说这种展现形式很新颖。即增加了友链博客的曝光量,也能实时关注一些博主的最新动态,说实现,我心动了~
又有哪位博主会愿意拒绝自己写的博文被特意标记出来让更多人的看到呢?毕竟,博客写出来的本质就是分享不是吗?
所以,我决定也给自己的博客加一个博友圈,心动不如行动,行动不如马上去动~
经过了解,网上这种rss订阅工具有很多,我最终选择了Freshrss,别问为什么选这个,这个问题就好比你问南方人为啥吃米饭,北方人为啥吃面条一样让人无解。
我选择的是docker-compose进行部署Freshrss
docker-compose.yml
version: "3" services: freshrss-app: image: freshrss/freshrss:latest container_name: freshrss-app hostname: freshrss-app restart: unless-stopped ports: - "8080:80" volumes: - ./freshrss/data:/var/www/FreshRSS/data - ./freshrss/extensions:/var/www/FreshRSS/extensions environment: CRON_MIN: '*/45' TZ: Asia/Shanghai
数据库方面,我选择的是免费的第三方supabase。
搭建Freshrss,基本没啥难度。然后我参考了一些博客提供的博友圈原理,就是
1.通过api的方式调用Freshrss来实时获取订阅的博文信息以json文件形式保存在本地
2.读取json输出在要展示的博客页面上。
第一步有几个坑,$authToken = substr($loginResponse, strpos($loginResponse, 'Auth=') + 5);输出的字符串有空格,会导致拉取文章失败,所以需要trim清除下,第二个file_get_contents函数需要对应文件读写权限
最后,博主的实现代码:
rss.php
<?php /** * 获取最新订阅文章并生成JSON文件 */ function getAllSubscribedArticlesAndSaveToJson($user, $password) { $apiUrl = '你的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); $authToken = trim($authToken); $articlesUrl = $apiUrl . '/reader/api/0/stream/contents/reading-list?&n=10'; $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 = '你的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文件中'; // 获取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; // 生成文章列表 foreach (array_slice($articles, 0, $itemsPerPage) as $article) { $articles_list =' 图标:' . htmlspecialchars($article['icon']) . ' 站点标题:' . htmlspecialchars($article['site_name']) . ' 文章标题:' . htmlspecialchars($article['title']) . ' 文章内容摘要:' . htmlspecialchars($article['description']) . ' 文章链接:' . htmlspecialchars($article['link']) . ' 文章发布时间:' . htmlspecialchars($article['time']) . ' '; echo $articles_list; } } // 调用函数并提供用户名和密码 getAllSubscribedArticlesAndSaveToJson('用户名', '你的api密码');
然后最后就是怎么在博客中进行展示的问题了,我第一个想法是写一个独立页面来展示,后面觉得一个脱离博客的独立页面博友圈,那还叫博友么,脱节了啊。第二个想法是侧边栏进行展示,以类似公告滚动的方法,如下:
但是和主题博客样式不搭,怕破坏了整体,反而突兀,其次,是以纯html的方法插入侧边栏还是写个类似组件的方式插入侧边栏呢?再加上,这个功能依赖Freshrss服务,后期服务的变动,迁移,搭建又是个问题。经过深思熟虑之下,脑子突然蹦出一句:不忘初心!我当初选择这个主题的原因是因为简洁,如今的所作所为究竟是在干什么?
再仔细一想,如今各个模块都算完善,再搞下去就画蛇添足了。所以,博友圈,不要也罢!
感觉么啥用 很鸡肋
也不能说没啥用,不过用别人的也行,哈哈
我也是,当初弄完就没用过,只是享受折腾的乐趣
博友圈我觉得还行的,真的是方便了不少,与主题搭配下来可以再慢慢优化。
从开始到放弃,哈哈 挺好的。
哈哈哈,折腾到最后竟然放弃了,可还行φ( ̄∇ ̄o)
改的不错,很好看。右边的天气很有创意,就是这评论验证码,超过10的我都不会了,还好去百度了一下
主要是主题框架好,简洁美观,可塑性好φ( ̄∇ ̄o)