htmlua converts this:
document { html { head { meta { charset = "utf-8" }, title "Hello, world!" }, body { h1 "Hello, world!", p "This is a paragraph." } } }into this:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Hello, world!</title> </head> <body> <h1>Hello, world!</h1> <p>This is a paragraph.</p> </body> </html>...all dynamically at request time. It is effectively serverside rendering where your output file is being rendered from Lua functions. It is written in 100% vanilla Lua and can be integrated into any Lua environment. It supports a component-like system for reusing blocks of HTML. It runs on six operating systems with a single file thanks to the redbean web server.
It is suggested to read src/pages/index.html.lua, as it is heavily commented.
I recently read Ben Visness's article about their custom Lua dialect for JSX-like elements. I thought I could build a system just as flexible to use in vanilla Lua.
- Copy the contents of this repository into a new folder.
- Download
redbean.comfrom the redbean website. - Execute
./run.shto pack the web server and run it.
This abuses a few tricks in the Lua language spec:
- Functions that take a single argument can be called without parenthesis (
ident("a")=ident "a") - Key value pairs and array-like entries into tables can be mixed (
{ a = "b", "c" })
The keywords are actually functions in the global scope that create the HTML element and return a string. Props are identified by key/value pairs and children are identified as entries in the table. Valueluess props (such as autoplay on the video element) can be specified with _ = { "autoplay" }.
Create pages/index.html.lua:
return function() return document { html { head { meta { charset = "utf-8" }, title "Hello, world!" }, body { h1 "Hello, world!", p "This is a paragraph." } } } endPut a line like this in your .init.lua:
h2 = htmlua.elem("h2")You can provide a second argument for options for this element:
close: boolean = true- whether to close the element with</name>empty: boolean = false- whether to close the element wiith/>if there are no children
local htmlua = require("htmlua") local MyComponent = htmlua.component(function(props, children) return { h1("Hello, " .. props.name .. "!"), p "This is a reusable component." } end) return function() return document { html { head { meta { charset = "utf-8" } }, body { MyComponent { name = "world" }, hr {}, MyComponent { name = "Lua" } } } } endPaths get tried in this order:
pages/:path/index.luapages/:path/index.html.luapages/:path.html.luapages/:path.lua
- "this is based i like this" - https://c7.pm/
- "Stop programming" - https://coolmathgames.tech/
- ":(" - https://camora.dev/
- "omg Roblox" - https://jabco.page/