71 lines
2.2 KiB
Lua
71 lines
2.2 KiB
Lua
-- feed.lua — Atom feed (RFC 4287) for published blog posts.
|
|
|
|
local db = require "db"
|
|
local md = require "md"
|
|
local config = require "config"
|
|
|
|
local M = {}
|
|
|
|
local XML_ESC = {
|
|
["&"] = "&", ["<"] = "<", [">"] = ">",
|
|
['"'] = """, ["'"] = "'",
|
|
}
|
|
local function xesc(s)
|
|
return (tostring(s or ""):gsub("[&<>\"']", XML_ESC))
|
|
end
|
|
|
|
M.FEED_LIMIT = 20
|
|
|
|
--- Build the Atom feed document. Returns the XML string.
|
|
function M.atom()
|
|
local base = config.base_url()
|
|
local title = config.get("site_title")
|
|
local author = config.get("site_author")
|
|
local posts = db.list_published_page("blog", M.FEED_LIMIT, 0)
|
|
|
|
-- Feed-level updated: newest updated_at, or "now" for an empty feed.
|
|
local feed_updated = os.date("!%Y-%m-%dT%H:%M:%SZ")
|
|
if posts[1] then
|
|
feed_updated = posts[1].updated_at
|
|
for _, p in ipairs(posts) do
|
|
if p.updated_at > feed_updated then feed_updated = p.updated_at end
|
|
end
|
|
end
|
|
|
|
local out = {
|
|
'<?xml version="1.0" encoding="utf-8"?>',
|
|
'<feed xmlns="http://www.w3.org/2005/Atom">',
|
|
"<title>" .. xesc(title) .. "</title>",
|
|
'<link href="' .. xesc(base) .. '/"/>',
|
|
'<link rel="self" type="application/atom+xml" href="' .. xesc(base) .. '/atom.xml"/>',
|
|
"<id>" .. xesc(base) .. "/</id>",
|
|
"<updated>" .. xesc(feed_updated) .. "</updated>",
|
|
}
|
|
if author ~= "" then
|
|
out[#out + 1] = "<author><name>" .. xesc(author) .. "</name></author>"
|
|
end
|
|
local tagline = config.get("site_tagline")
|
|
if tagline ~= "" then
|
|
out[#out + 1] = "<subtitle>" .. xesc(tagline) .. "</subtitle>"
|
|
end
|
|
|
|
for _, p in ipairs(posts) do
|
|
local url = base .. "/blog/" .. EscapePath(p.slug)
|
|
out[#out + 1] = "<entry>"
|
|
.. "<title>" .. xesc(p.title) .. "</title>"
|
|
.. '<link href="' .. xesc(url) .. '"/>'
|
|
.. "<id>" .. xesc(url) .. "</id>"
|
|
.. "<published>" .. xesc(p.created_at) .. "</published>"
|
|
.. "<updated>" .. xesc(p.updated_at) .. "</updated>"
|
|
.. (p.summary ~= ""
|
|
and ("<summary>" .. xesc(p.summary) .. "</summary>") or "")
|
|
.. '<content type="html">' .. xesc(md.render(p.body)) .. "</content>"
|
|
.. "</entry>"
|
|
end
|
|
|
|
out[#out + 1] = "</feed>"
|
|
return table.concat(out, "\n")
|
|
end
|
|
|
|
return M
|