Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/notnite/htmlua
Serverside website rendering in vanilla Lua with the redbean web server
https://github.com/notnite/htmlua
redbean
Last synced: 4 days ago
JSON representation
Serverside website rendering in vanilla Lua with the redbean web server
- Host: GitHub
- URL: https://github.com/notnite/htmlua
- Owner: NotNite
- License: mit
- Created: 2024-01-09T16:12:51.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-05-02T17:58:52.000Z (7 months ago)
- Last Synced: 2024-05-03T04:42:55.238Z (7 months ago)
- Topics: redbean
- Language: Lua
- Homepage:
- Size: 35.2 KB
- Stars: 12
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# htmlua
htmlua converts this:
```lua
document {
html {
head {
meta { charset = "utf-8" },
title "Hello, world!"
},body {
h1 "Hello, world!",
p "This is a paragraph."
}
}
}
```into this:
```html
Hello, world!
Hello, world!
This is a paragraph.
```
...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](https://redbean.dev/) web server.
It is suggested to read `src/pages/index.html.lua`, as it is heavily commented.
## Why?
I recently read [Ben Visness](https://bvisness.me/luax/)'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.
## Installation
- Copy the contents of this repository into a new folder.
- Download `redbean.com` from the redbean website.
- Execute `./run.sh` to pack the web server and run it.## How it works
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" }`.
## Using htmlua
### Creating your first page
Create `pages/index.html.lua`:
```lua
return function()
return document {
html {
head {
meta { charset = "utf-8" },
title "Hello, world!"
},body {
h1 "Hello, world!",
p "This is a paragraph."
}
}
}
end
```### Adding more HTML elements
Put a line like this in your `.init.lua`:
```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 ``
- `empty: boolean = false` - whether to close the element wiith `/>` if there are no children### Creating a reusable component
```lua
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" }
}
}
}
end
```### Routing
Paths get tried in this order:
- `pages/:path/index.lua`
- `pages/:path/index.html.lua`
- `pages/:path.html.lua`
- `pages/:path.lua`## Testimonials
- "this is based i like this" -
- "Stop programming" -
- ":(" -
- "omg Roblox" -