-- 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 = { '', '', "" .. xesc(title) .. "", '', '', "" .. xesc(base) .. "/", "" .. xesc(feed_updated) .. "", } if author ~= "" then out[#out + 1] = "" .. xesc(author) .. "" end local tagline = config.get("site_tagline") if tagline ~= "" then out[#out + 1] = "" .. xesc(tagline) .. "" end for _, p in ipairs(posts) do local url = base .. "/blog/" .. EscapePath(p.slug) out[#out + 1] = "" .. "" .. xesc(p.title) .. "" .. '' .. "" .. xesc(url) .. "" .. "" .. xesc(p.created_at) .. "" .. "" .. xesc(p.updated_at) .. "" .. (p.summary ~= "" and ("" .. xesc(p.summary) .. "") or "") .. '' .. xesc(md.render(p.body)) .. "" .. "" end out[#out + 1] = "" return table.concat(out, "\n") end return M