The posts domain
api.posts is your content engine — blog posts, forum threads, articles, announcements. Full CRUD with soft-delete and restore.
Function reference
| Function | Returns | Description |
|---|---|---|
api.posts.get(id) |
table or nil | Get a single post |
api.posts.list(filter?) |
{ items, total } |
Search, filter, paginate posts |
api.posts.create(data) |
table | Create a new post |
api.posts.update(id, data) |
table | Update post fields |
api.posts.delete(id, hard?) |
boolean | Soft-delete. Pass "hard" for permanent |
api.posts.restore(id) |
table | Restore a soft-deleted post |
Creating a post
local post = api.posts.create({
forumid = 5,
title = "Hello World",
content = "My first blog post!",
format = "html",
status = 1 -- 1 = published
})
Listing posts in a forum
-- Newest published posts, page 1
local result = api.posts.list({
forumid = 5,
status = 1, -- published
order = "id_desc", -- newest first
limit = 10
})
for _, post in ipairs(result.items) do
print(post.title .. " by " .. post.owner.username)
end
List filter
api.posts.list({
forumid = 5, -- filter by forum
user = 42, -- filter by author
status = 1, -- 0=draft, 1=published, 2=pending, 3=trash
search = "lua", -- search in content
order = "id_desc", -- sort order
page = 1,
limit = 50
})
Soft vs hard delete
-- Soft delete (sets status=3, recoverable)
api.posts.delete(123)
-- Hard delete (permanent, cannot recover)
api.posts.delete(123, "hard")
-- Restore a soft-deleted post
api.posts.restore(123)
Blog homepage
app:get("/blog", function(ctx)
local page = tonumber(req.query.page) or 1
local posts = api.posts.list({
forumid = BLOG_FORUM_ID,
status = 1,
order = "id_desc",
page = page,
limit = 12
})
return ctx:render("blog", {
posts = posts.items,
total = posts.total,
page = page,
has_next = posts.total > page * 12
})
end)
Single post page
app:get("/blog/:slug", function(ctx)
local result = api.posts.list({
search = ctx.params.slug,
status = 1,
limit = 1
})
if result.total == 0 then
return ctx:error("Post not found", 404)
end
return ctx:render("post", { post = result.items[1] })
end)
Admin: managing posts
app:post("/admin/posts/:id/delete", function(ctx)
if not env.is_admin then
return ctx:error("Forbidden", 403)
end
api.posts.delete(tonumber(ctx.params.id))
ctx:flash("success", "Post deleted")
return ctx:redirect("/admin/posts")
end, { middleware = "auth" })
Next: api.messages — private messaging between users.