Initial commit, blog system works

This commit is contained in:
2026-07-16 21:08:50 -05:00
commit 3841122960
22 changed files with 5628 additions and 0 deletions

70
.lua/feed.lua Normal file
View File

@@ -0,0 +1,70 @@
-- 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 = {
["&"] = "&amp;", ["<"] = "&lt;", [">"] = "&gt;",
['"'] = "&quot;", ["'"] = "&apos;",
}
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