昨天 Follow 开始公测,于是便下载体验了一下,界面确实很简洁,功能比我现在用的 Inoreader 更符合我的期望,而且它还可以认证为 RSS 的作者,认证完之后用 Follow 订阅的用户就可以看到作者的认证标识,这个功能很吸引我。但是在我的博客的 RSS 中,只有摘要,没有全文,总觉得少点儿什么,于是便想着怎么把全文输出到 RSS 中。
前段时间看到 Astro 的 Container API,这个 API 可以在服务端获取组件的输出,于是便想到可以用这个 API 来获取全文,然后输出到 RSS 中,今天试了一下还真可以。
Container API
先来看下官方是怎么说的:Container API 允许你在隔离环境中渲染 Astro 组件。不过,这个 API 还在实验阶段,可能会有变化。
用法如下:
import { experimental_AstroContainer } from "astro/container";
const container = await experimental_AstroContainer.create();
RSS 全文输出
大概思路就是在 rss.xml.js 中定义路由,然后在这个路由中使用 Container API 获取全文,最后输出到 RSS 中。
import { loadRenderers } from "astro:container";
import { getCollection } from "astro:content";
import { SITE_DESCRIPTION, SITE_TITLE } from "@/consts";
import { getContainerRenderer } from "@astrojs/mdx";
import rss from "@astrojs/rss";
import { experimental_AstroContainer as AstroContainer } from "astro/container";
export async function GET(context) {
if (!context.site) {
throw new TypeError("context.site falsy");
}
const container = await AstroContainer.create({
renderers: await loadRenderers([getContainerRenderer()]),
});
const blog = await getCollection("blog");
const posts = blog
.filter(({ data: { draft = false } }) => !draft)
.sort(
({ data: { date: dateA } }, { data: { date: dateB } }) =>
dateB.valueOf() - dateA.valueOf(),
);
return rss({
title: SITE_TITLE,
description: `${SITE_DESCRIPTION}`,
site: context.site,
items: await Promise.all(
posts.map(async (post) => ({
...post.data,
pubDate: post.data.date,
description: post.data.tldr,
link: `/blog/${post.slug}/`,
content: await container.renderToString((await post.render()).Content),
})),
),
});
}
Follow 认证
最后,说下怎么添加 Follow 认证。有好几种方式,我这里用的是在 <description>
标签中添加 Follow 生成的 feedId 和 userId。
return rss({
//...
description: `${SITE_DESCRIPTION} feedId:{feedId}+userId:{userId}`,
// ...
});
评论