前言
在前几天加入了「Remark42评论系统」后,又被Follow-新一代信息阅读器感染,也想着给自己的博客加上RSS功能。于是便开始研究如何快速给自己的博客加上这个功能。
RSS是通过提供一份xml文件来提供feed的,xml中的主要内容就是博客文章的信息,其中一个标签就是时间,RSS的阅读器也是通过这个时间标签来判断是否有最近更新的文章。
如下图所示就是来自我很喜欢的一个博主(pseudoyu)的Rss的xml文件:
而我们要做的就是要为自己的网站生成这样一份文件。
工具准备
Pandoc-不同文件格式相互转换的利器。由于我的文章都是Markdown格式的,而RSS的阅读器都是只能读html格式的内容,所以要把Markdown的文章内容转成html格式的。
下载的方式非常简单,参考官网的Installation就可以,我同时在我的本地mac和linux服务器中「个人服务器常用工具」都下载了该工具。
使用起来也很简单,比如下面这个命令就是将md格式的文件输出成一个html的文件。
shell
pandoc -f markdown input.md -t html -o output.html
编写Go语言脚本来生成XML
一个XML中要包含多篇最近写的文章,不能一个一个的来使用命令来手动生成html的内容然后再贴到xml中,所以这里编写了一个GO语言的脚本来实现。
go
package service
import (
"encoding/xml"
"fmt"
"log"
"os"
"os/exec"
"strings"
"time"
"tunan-blog/env"
"tunan-blog/internal/repository"
)
// Item RSS 项结构体
type Item struct {
Title string `xml:"title"`
Link string `xml:"link"`
Description string `xml:"description"`
ContentEncoded string `xml:"content:encoded"`
PubDate string `xml:"pubDate"`
}
// RSS 结构体
type RSS struct {
XMLName xml.Name `xml:"rss"`
Version string `xml:"version,attr"`
Channel Channel `xml:"channel"`
XmlnsDc string `xml:"xmlns:dc,attr"`
XmlnsContent string `xml:"xmlns:content,attr"`
XmlnsAtom string `xml:"xmlns:atom,attr"`
XmlnsItunes string `xml:"xmlns:itunes,attr"`
}
// Channel RSS 项结构体
type Channel struct {
Title string `xml:"title"`
Link string `xml:"link"`
Description string `xml:"description"`
Follow FollowChange `xml:"follow_challenge"`
Items []Item `xml:"item"`
}
// FollowChange 用于follow feed 的claim
type FollowChange struct {
FeedId string `xml:"feedId"`
UserId string `xml:"userId"`
}
func RssXmlCreat() {
param := repository.ArticleQueryParam{
PageSize: 20,
PageIndex: 1,
}
// 查询文章列表
articleList, _, _ := repository.QueryArticle(param)
if len(articleList) == 0 {
return
}
var items []Item
// 遍历列表
for _, article := range articleList {
// 使用 Pandoc 转换 Markdown 为 HTML
cmd := exec.Command("pandoc", "-f", "markdown", "-t", "html")
cmd.Stdin = strings.NewReader(article.Content)
htmlOutput, err := cmd.Output()
if err != nil {
log.Printf("Pandoc error for ID %d: %v", article.Id, err)
continue
}
// 创建 RSS 项
item := Item{
Title: article.Title,
Link: fmt.Sprintf("%s/blog/%s", env.Prop.Website.Url, article.Slug), // 替换成你的链接格式
Description: article.Title,
ContentEncoded: string(htmlOutput),
PubDate: article.GmtCreate.Format(time.RFC822),
}
items = append(items, item)
}
// 创建 RSS 结构体
rss := RSS{
Version: "2.0",
XmlnsDc: "http://purl.org/dc/elements/1.1/",
XmlnsContent: "http://purl.org/rss/1.0/modules/content/",
XmlnsAtom: "http://www.w3.org/2005/Atom",
XmlnsItunes: "http://www.itunes.com/dtds/podcast-1.0.dtd",
Channel: Channel{
Title: env.Prop.Website.Title, // 替换成你的 RSS 标题
Link: env.Prop.Website.Url, // 替换成你的 RSS 链接
Description: env.Prop.Website.Description, // 替换成你的 RSS 描述
Follow: FollowChange{
FeedId: env.Prop.Website.FollowFeedId,
UserId: env.Prop.Website.FollowUserId,
},
Items: items,
},
}
// 将 RSS 数据编码为 XML
xmlData, err := xml.MarshalIndent(rss, "", " ")
if err != nil {
log.Fatal(err)
}
// 输出 XML 文件
err = os.WriteFile("rss.xml", xmlData, 0644)
if err != nil {
log.Fatal(err)
}
fmt.Println("RSS feed generated successfully!")
}
其中env.Prop中的内容是我写在配置文件中的内容,主要是一些网站的标题、URL等内容。
yaml
website:
url: your_website_url
title: your_website_title
description: your_website_description
follow_feed_id: follow_feed_id_for_claim
follow_user_id: follow_user_id_for_claim
这段代码很简单,就是从数据库中读取出多篇文章,然后生成一个个的item,塞入到外层的标签中。
配置nginx
通过本地生成xml文件然后上传到服务器,或者直接在服务器上生成该文件,最终都需要将文件放到服务器上。比如我想让我的博客访问者通过https://www.tunan.fun/rss.xml
来访问我某个路径下的rss
文件。
在nginx的配置文件中添加相应的映射即可:
shell
server {
server_name www.tunan.fun tun.fun;
location /rss.xml {
alias /home/yaodao/my-app/tunan-blog/rss.xml;
try_files $uri =404;
}
}
follow体验
这几个月的时间,开源的「follow系统」算是火的一塌糊涂,它自称为Next generation information broswer
。到目前2024-10-21
为止,已经达到了13.3k star
。
有幸在其交流的discord
社区上抢到了一个邀请码:
体验了一下,觉得它真的很好用,支持的数据源很多,我主要的还是关注一些博客和Youtube的视频。
当把自己的Feed: https://www.tunan.fun/rss.xml
输入到follow中进行搜索即可,非常简单。
并且当完成订阅后,直接搜索tunan
、tunan.fun
这些关键词就能找到相应的feed:
如果认真看了上面的xml生成,发现有一个follow_change
的标签对,这个是为了证明follow上的订阅是自己的。当订阅了属于自己feed时,就可以对其声明,声明的方式很简单,follow给出了三种方法:
- Content
- Description
- RSS Tag
我这里用的就是第三种在xml中添加标签的方法。当完成claim
后就会显示出一个对号
的认证标识。
也欢迎大家来follow订阅我的feed!!!有问题请在我的博客评论区进行评论~