TEMPLATE / READY TO REMIX
Guestbook
A persistent server-side guestbook with public notes.
preview
This template runs Lua on its host. The source below is not executed by this web preview.
STATIC PREVIEW · OPEN IN LANTERN FOR INTERACTIVE FORMS
Guestbook
Leave a note for the next traveler.
Explore
Built for our world.
Make it yours
Edit this page with Lantern.
↗ Back to Lantern
app.lua
return function(ctx)
local P=ctx.page
local entries=ctx.read('entries',{})
if ctx.method=='POST' and ctx.path=='/sign' then
local text=tostring(ctx.fields.message or ''):sub(1,240)
if text:match('%S') then
entries[#entries+1]={text=text,id=ctx.requestId}
while #entries>30 do table.remove(entries,1) end
ctx.write('entries',entries)
end
return {kind='redirect',path='/'}
end
if ctx.path~='/' then return nil end
local children={P.heading{text='Leave a little warmth'},P.paragraph{text='A guestbook for passing travelers. Notes are public.'}}
for _,entry in ipairs(entries) do children[#children+1]=P.paragraph{text=entry.text} end
children[#children+1]=P.form{action='/sign',children={P.input{name='message',text='Your note'},P.submit{text='Sign guestbook'}}}
return {kind='page',page=P.document('Guestbook',children)}
end
index.json
{
"version": 1,
"title": "Guestbook",
"children": [
{
"type": "heading",
"text": "Guestbook"
},
{
"type": "paragraph",
"text": "Leave a note for the next traveler."
},
{
"type": "columns",
"children": [
{
"type": "section",
"children": [
{
"type": "heading",
"text": "Explore"
},
{
"type": "paragraph",
"text": "Built for our world."
}
]
},
{
"type": "section",
"children": [
{
"type": "heading",
"text": "Make it yours"
},
{
"type": "paragraph",
"text": "Edit this page with Lantern."
}
]
}
]
},
{
"type": "link",
"text": "Back to Lantern",
"href": "ln://home"
}
]
}