some restructuring + readme

This commit is contained in:
2025-11-27 00:57:34 +02:00
parent 4947880c4a
commit d29dff57c4
6 changed files with 156 additions and 0 deletions

1
.gitignore vendored
View File

@@ -8,3 +8,4 @@
!/Makefile
!/Dockerfile
!/README.md

65
README.md Normal file
View File

@@ -0,0 +1,65 @@
# My website platform
I use this custom lua HTTP server for my personal web page. It works with lua-written pages, as well as markdown pages. It is completely customizable.
## How to use?
Compile with the provided `Makefile` (you will need `mklua`). Then, just use the `bin/website` binary. It accepts one argument - the config. The config is a lua file that must return an object with these fields:
- port: what port to bind to
- luapages: a `package.path`-like string for resolving lua pages
- pages: a `package.path`-like string for resolving markdown pages
- static: a `package.path`-like string for resolving static resources
- path: a `package.path`-like string for resolving custom plugins and lua libraries
- pages_base: a lua package name to be used as the base page template
Anything else is up to the user's implementation. However, the built-in plugins work with these additional fields:
- title: the default title of the website
- routes: any additional routes that should be added to the navbar, if any
- ignores: a lua pattern, that ignores a certain page from listing when its top-most segment matches
You can read any other config values from the config object.
## Plugins and templating
Templating is done via the tools, given in the `template` package. It has two fundamental APIs: `elements` and `slot`. Any field from `elements` is a function that accepts an object that contains a map of attributes and a list of children and returns a valid HTML. Then, `slot` is a function that may be used in place of `elements`. It calls a single callback with the current page being templated and a callback to emit more elements, results of `elements`. This is used when you want to generate HTML procedurally.
Example:
```lua
local e = require "template".elements;
local slot = require "template".slot;
...
return e.div {
class = "my-class",
e.span { "This is some text" },
e.span "This is a short form of the above",
slot(function (self, emit)
emit(e.span { "The current page is " .. self.path });
for i = 1, 10 do
emit(e.span { tostring(i) });
end
end),
}
```
The above will emit HTML like this:
```html
<div class="my-class">
<span>This is some text</span>
<span>This is a short form of the above</span>
<span>The current page is [page path]</span>
<span>1</span>
<span>2</span>
<span>3</span>
...
</div>
```
Three plugins are available by default - breadcrumbs, list and navbar. They can be used to build out a page.

View File

@@ -0,0 +1,22 @@
local resolve = require "resolve";
--- @param self page
--- @param cb fun(url: string, title: string)
return function (self, cb)
local curr = "/";
for part in self.path:gmatch "[^/]+" do
curr = curr .. part;
local meta;
if curr == self.path then
meta = self.meta;
else
local page = assert(resolve(self.config, curr))();
meta = page.meta;
end
cb(curr, meta.title or part);
curr = curr .. "/";
end
end

47
src/plugin/list.lua Normal file
View File

@@ -0,0 +1,47 @@
local resolve = require "resolve";
local p = require "utils.path";
local fs = require "sync.fs";
local asserted = require "utils.asserted";
--- @param cb fun(url: string)
return function (ignores, config, path, cb)
local res = {};
local _, file = resolve(config, path);
local dir = p.dirname(file);
for name in asserted(fs.readdir(dir)) do
local ignored = false;
if name:match "%.lua$" then
name = name:sub(1, -5);
elseif name:match "%.md$" then
name = name:sub(1, -4);
elseif not resolve(config, p.join(path, name)) then
ignored = true;
end
if not ignored and ignores then
for i = 1, #ignores do
if name:find(ignores[i]) then
ignored = true;
break;
end
end
end
if not ignored and config.ignores then
for i = 1, #config.ignores do
if name:find(config.ignores[i]) then
ignored = true;
break;
end
end
end
if not ignored then
cb((p.join(path, name)));
end
end
return res;
end

19
src/plugin/navbar.lua Normal file
View File

@@ -0,0 +1,19 @@
local list = require "plugin.list";
local resolve = require "resolve";
--- @param self page
---@param cb fun(url: string, title: string)
return function (self, cb)
list(nil, self.config, self.path, function (path)
local page = assert(resolve(self.config, path))();
local name = page.meta.title or page.path:match "[^/]+$";
cb(self.config.routes.url, self.config.title);
end);
if self.config.routes then
for i = 1, self.config.routes do
cb(self.config.routes[i].url, self.config.routes[i].title);
end
end
end

View File

@@ -1,5 +1,7 @@
require "utils.printing";
require "template";
require "plugin.breadcrumbs";
require "plugin.navbar";
local sync = require "sync";
local tcp = require "sync.tcp";