[SSS] Creating an RSS feed
Back when the blog was written in Ruby, I wrote that I eventually went ahead and implemented an RSS feed, and that it was much easier than expected. Turns out I didn't even need a library to do it, it's only a matter of creating an XML document.
Sure, it might be prettier to assign properties (e.g rss.item.content = "content here") versus creating the document manually (e.g xml += <content>content here</content>), but with proper formatting, the latter can look pretty great too. Besides, printing the document, or looking at the source in a browser will be easier to track / spot bugs.
Let's start with adding the route to our droplet:
func addRoutes() -> Droplet {
get("/feed", handler: FeedController.create)
// [...]
}Let's now create our Feed controller, that needs to have a method with the same signature as the handler:
struct FeedController {
static func create(with request: Request) throws -> ResponseRepresentable {
// 1
let posts = try Post.makeQuery().sorted().all()
guard !posts.isEmpty else { return Response(redirect: "/") }
// 2
request.setValue("application/xml", forHTTPHeaderField: "Content-Type")
// 3
var xml = ""
xml += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
xml += "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
xml += "<title type=\"text\">Roland Leth</title>\n"
// [...]
posts.forEach {
xml += "<entry>\n"
// 4
xml += "\t<id>\(url)</id>\n" // 5
xml += "\t<title>\($0.title)</title>\n"
// [...]
xml += "</entry>\n"
}
xml += "</feed>"
return xml // 6
}In here, we have to set the content type to XML (2), fetch the posts (1), and create our document, bit by bit (3), finally returning the xml string (6).
This might be a lot of xml += ... typing, but it keeps everything nicely aligned. Also, the hassle of adding tabs (4) and new lines (5) all over the place will pay off when printing / looking at the source in a browser. You can check the whole file here.