关于友情链接和SSG在博客中展示Flux订阅

关于友情链接和SSG在博客中展示Flux订阅

2024-04-15
#工具箱 , #分享 , #编码

友情链接

此前我一直以文章内容的形式手动展示和维护博客的友链,并在文中附上了友情链接添加的条件,此间也收到过不少好友的链接申请。

不过在 2023年11月05日 ,我对该页面的介绍做了更新,并在文中写到:

今天忽然发现我好像重新理解的「友邻」的意义,这个邻居应该是我喜欢、欣赏的,对我有「正面影响」的,而不是冰冷页面上的一个超链接而已。

所以我决定只在这个页面展示我喜欢的博客,我也并不需要他们也给我做上「友情链接」,单纯只是因为我喜欢、欣赏他们。

另外那些没有出现在这个页面上的朋友也不要心有芥蒂,并不是你的博客不优秀,毕竟「喜欢」这个词非常主观不是吗?

自那之后我就再没有对友情链接页面中的链接做过维护。

并且在之后不久基于23年11月5日的见解 博客并不是页面上的一个超链接 ,我希望能 通过他们的博客获取一些正向激励 ,而且是 持续 性的获得这种激励。

所以我开始认真 使用 订阅工具,此间还分享了 打破信息茧房及一款 RSS 阅读器推荐如何订阅 Q 外的 RSS?方法来了 两文。

更换工具

不过文中介绍到的订阅工具 yarr 因为是开发者自己做的一个工具,虽然这个工具确实兼容了多平台,但是在手机上的使用体验非常别扭,如下图所示:

因为我是习惯左手玩手机,所以在使用yarr时阅读完一篇文章后需要点击最右上角的关闭才能关闭,对于目前的只能手机尺寸来说这个操作是及其别扭的。

所以我在前不久正式切换到了 miniflux ,这是一款及其简单、专注的web端self-host订阅工具,并有着强大的扩展功能,开发者也十分活跃,之前没有选他主要是因为原生界面实在是太丑了。

不过前些日子看到 蜗牛大佬 推荐了一款miniflux的主题 Miniflux-Theme-Reeder ,所以心动+yarr的不适之下进行了更换。

不过本文不详述如何安装,有时间会更新在我的 数字花园

友链链接改为展示订阅

在后续的使用过程中发现了miniflux的强大拓展能力,所以想着能不能将我的博客订阅在友情页面内展示,经过一番研究和ChatGPT沟通后,后终于完整实现了这个功能,所以本文假定你已符合以下条件:

  • 已安装和正常使用miniflux
  • 使用ssg,最好是11ty
  • 有一定的程序基础。

一、 生成API密钥

在miniflux的keys页面中可以生成用于访问API的Token,并复制备用。

二、本地调试可以配置11ty项目环境变量

为了避免暴露,我们将token变量写入vscode的 launch.js 文件中,并在 .gitignore 文件中添加 .vscode/ 文件夹。

{
// 使用 IntelliSense 了解相关属性。 
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
    {
        "type": "node-terminal",
        "request": "launch",
        "name": "启动程序",
        "command": "yarn run start",
        "cwd": "${workspaceFolder}",
        "env": {
            "FLUX_TOKEN": "你的token" //将变量写入env中
        }
    }
]
}

并在11ty中使用 process.env.FLUX_TOKEN 调用。

const fluxToken = process.env.FLUX_TOKEN;

三、Github上配置环境变量

同理,为了能顺利使用Github Action生成网站,并部署到Netlify上,我们还需要设置Github Action变量,具体位置为Github上的11ty项目中的 /settings/secrets/action 下,添加同名 FLUX_TOKEN 变量即可。

同时修改Github Action文件,在build命令中使用该变量。

on: 
  repository_dispatch:
types:
  - update
  schedule:
- cron: '0 2 * * *' 

jobs:
  build_deploy:
runs-on: ubuntu-latest
steps:
  - uses: actions/checkout@master

  - name: Set Node.js 20.x
    uses: actions/setup-node@master
    with:
      node-version: 20.x        

  - name: Run install
    uses: borales/actions-yarn@v4
    with:
      cmd: install # will run `yarn install` command

  - name: Build production bundle
    uses: borales/actions-yarn@v4
    env:
      FLUX_TOKEN: ${{secrets.FLUX_TOKEN}} #设置在Build过程中需要使用的FLUX_TOKEN
    with:
      cmd: prod # will run `yarn prod` command


  - name: Deploy to Netlify
    uses: netlify/actions/cli@master
    env:
      NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
      NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
      build_directory: dist
    with:
      args: deploy --prod

代码实现

至此已经完成了变量配置操作,接下来是代码实现部分,这里以11ty为例,其他SSG程序可以根据程序自身特性更换实现方式。

根据miniflux的API文档 我们可以使用 get-category-entries 接口获取文章数据,请求格式为 下方所示:

GET /v1/categories/22/entries?limit=1&order=id&direction=asc
  • 其中 22 为分类编号,可以在flux中点击对应分类,url中的数字部分就是了。
  • limit 则是获取多少个订阅。
  • order 排序

不过获取的数据似乎是所有的文章数据,所以需要进行一次筛选操作。

我这里只希望展示最新的一条文章,根据和ChatGPT的交流,通过Filter过出所有博客最新的一条数据。

  //... .eleventy.js
  // Get All feeds
config.addCollection("feeds", async function (collection) {
    if (fluxToken) {
        try {
            // 请求
            const response = await fetch(
                "https://flux.1900.live/v1/categories/4/entries?order=id&direction=desc&limit=99999",
                {
                    method: "GET",
                    headers: {
                        "X-Auth-Token": fluxToken,
                    },
                }
            );
            let data = await response.json();
            data = data.entries.filter((entry, index, self) => {
                // 因为flux中订阅网站的site_url有时候会是rss地址,所以这里做了一下处理,只获取 https://xxxx.com 部分,方便访客跳转访问。
                const domain = new URL(entry.feed.site_url).origin;
                entry.feed.site_url = domain;
                return (
                    self.findIndex(
                        (item) => item.feed_id === entry.feed_id
                    ) === index
                );
            });
            return data;
        } catch (error) {
            console.log("请求错误:", error);
        }
    }
    return collection;
});

接下来在11ty的模板中遍历数据即可。

<article class="markdown book-article">
  <h2 class="book-title">
我关注的博主们
  </h2>
  <div class="book-columns flex flex-wrap">
  {% for item in collections.feeds %}
<div class="flex-even markdown-inner">
  <h3 class="ellipsis"><a href="{{item.feed.site_url}}" target="_blank">{{item.feed.title}}</a></h3>
  <div><span>{{ item.published_at | htmlDate   }}</span></div>
  <div class="ellipsis"><a href="{{item.url}}" target="_blank">{{item.title}}</a></div>
</div> 
  {% endfor %}
  </div>
</div>

效果可以看本站 https://1900.live/links/ 页面。

加入评论