some restructuring + readme
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@
|
||||
|
||||
!/Makefile
|
||||
!/Dockerfile
|
||||
!/README.md
|
||||
|
||||
65
README.md
Normal file
65
README.md
Normal 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.
|
||||
22
src/plugin/breadcrumbs.lua
Normal file
22
src/plugin/breadcrumbs.lua
Normal 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
47
src/plugin/list.lua
Normal 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
19
src/plugin/navbar.lua
Normal 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
|
||||
@@ -1,5 +1,7 @@
|
||||
require "utils.printing";
|
||||
require "template";
|
||||
require "plugin.breadcrumbs";
|
||||
require "plugin.navbar";
|
||||
|
||||
local sync = require "sync";
|
||||
local tcp = require "sync.tcp";
|
||||
|
||||
Reference in New Issue
Block a user