好的,让我们来实现 RSS 订阅功能。这将允许用户通过 RSS 阅读器订阅博客的最新文章。
第十一部分:实现 RSS 订阅功能
- 首先,我们需要安装一个用于生成 RSS feed 的库。我们将使用
feed库。在项目根目录运行以下命令:
bun add feed- 创建一个新的文件
src/utils/rss.ts来处理 RSS feed 的生成:
import { Feed } from 'feed';
import { Post } from '../types';
export function generateRSSFeed(posts: Post[], siteURL: string) {
const feed = new Feed({
title: "My Blog",
description: "Latest posts from My Blog",
id: siteURL,
link: siteURL,
language: "en",
favicon: `${siteURL}/favicon.ico`,
copyright: "All rights reserved 2023, My Blog",
updated: new Date(posts[0].createdAt), // Assumes posts are sorted by date
feedLinks: {
rss2: `${siteURL}/rss.xml`,
},
});
posts.forEach((post) => {
feed.addItem({
title: post.title,
id: `${siteURL}/posts/${post.id}`,
link: `${siteURL}/posts/${post.id}`,
description: post.content.substring(0, 200) + '...', // Short excerpt
content: post.content,
author: [
{
name: post.author,
},
],
date: new Date(post.createdAt),
});
});
return feed.rss2();
}- 更新
src/routes/posts.ts以包含 RSS feed 生成:
import { Elysia } from "elysia";
import { db } from "../db";
import { posts, users, tags, postTags } from "../db/schema";
import { eq, desc } from "drizzle-orm";
import { authMiddleware } from "../middleware/auth";
import { generateRSSFeed } from "../utils/rss";
export const postRoutes = new Elysia()
.use(authMiddleware)
// ... 其他路由保持不变
.get("/rss.xml", async ({ set }) => {
const allPosts = await db.select({
id: posts.id,
title: posts.title,
content: posts.content,
createdAt: posts.createdAt,
author: users.username,
})
.from(posts)
.leftJoin(users, eq(posts.authorId, users.id))
.orderBy(desc(posts.createdAt))
.limit(10)
.all();
const siteURL = "http://localhost:3000"; // 替换为你的实际网站 URL
const rssFeed = generateRSSFeed(allPosts, siteURL);
set.headers['Content-Type'] = 'application/rss+xml';
return rssFeed;
});- 更新
src/index.ts以包含新的 RSS 路由:
import { Elysia } from "elysia";
import { html } from "@elysiajs/html";
import { staticPlugin } from "@elysiajs/static";
import { authRoutes, auth } from "./routes/auth";
import { postRoutes } from "./routes/posts";
import { userRoutes } from "./routes/users";
import { commentRoutes } from "./routes/comments";
import { migrate } from "drizzle-orm/libsql/migrator";
import { db } from "./db";
import { renderFile } from "eta";
import path from "path";
// ... 前面的代码保持不变
const app = new Elysia()
.use(html())
.use(staticPlugin())
.use(auth)
.use(authRoutes)
.use(postRoutes)
.use(userRoutes)
.use(commentRoutes)
// ... 其他路由保持不变
.get("/rss.xml", async ({ set }) => {
return await postRoutes.handle({ method: 'GET', path: '/rss.xml' });
})
.listen(3000);
console.log(`Server is running at ${app.server?.hostname}:${app.server?.port}`);- 更新
src/views/layouts/main.eta以添加 RSS feed 的链接:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= it.title %> - My Blog</title>
<link rel="stylesheet" href="/styles/main.css">
<link rel="alternate" type="application/rss+xml" title="RSS Feed for My Blog" href="/rss.xml" />
<script src="https://unpkg.com/htmx.org@1.9.2"></script>
</head>
<body>
<header>
<nav>
<a href="/">Home</a>
<a href="/posts/new">New Post</a>
<% if (it.user) { %>
<a href="/settings">Settings</a>
<a href="/logout">Logout</a>
<% } else { %>
<a href="/login">Login</a>
<a href="/register">Register</a>
<% } %>
<a href="/rss.xml">RSS Feed</a>
</nav>
</header>
<main>
<%~ it.body %>
</main>
<footer>
<p>© 2023 My Blog</p>
</footer>
</body>
</html>- 在
public目录中添加一个favicon.ico文件(你可以使用任何你喜欢的图标)。
这些更改实现了 RSS 订阅功能:
- 创建了一个新的
/rss.xml路由,它生成包含最新 10 篇文章的 RSS feed。 - RSS feed 包含每篇文章的标题、链接、作者、发布日期和内容摘要。
- 在主布局中添加了 RSS feed 的链接,使用户可以轻松找到并订阅。
- 在 HTML 头部添加了 RSS feed 的元标签,使 RSS 阅读器可以自动发现 feed。
这个功能允许用户通过他们喜欢的 RSS 阅读器订阅你的博客,从而增加了博客的可访问性和用户粘性。
接下来,我们可以考虑添加以下功能:
- 文章搜索功能
- 用户头像上传
- 文章分类系统
- 社交媒体分享按钮
你希望继续哪个方向,或者有其他想法吗?