commit 7747d415cc0dce08e3f3dde5466bc37077c40f5b
parent 2f877b63b8b09272567f8b00164426d844e9cfe7
Author: vx-clutch <[email protected]>
Date: Wed, 3 Dec 2025 21:50:51 -0500
alpha p6
Diffstat:
6 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/TODO b/TODO
@@ -1,2 +0,0 @@
-Add an interval element
-Add favicon support
diff --git a/core/builtin.lua b/core/builtin.lua
@@ -3,13 +3,8 @@ local std = require("core.std")
local M = {}
M.__index = M
-local function encode(str)
- return str:gsub("([^%w%-%_%.%~])", function(c)
- return string.format("%%%02X", string.byte(c)) end) end
-
function M.fes(header, footer)
- local config = {}
- local site_config = {}
+ local config = {} local site_config = {}
local fes_mod = package.loaded.fes
if fes_mod and fes_mod.config then
config = fes_mod.config
@@ -18,20 +13,18 @@ function M.fes(header, footer)
end
end
- local raw_favicon = site_config.favicon or [[<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">🔥</text></svg>]]
-
local self = {
- version = site_config.version or "",
- title = site_config.title or "Document",
- copyright = site_config.copyright or "© The Copyright Holder",
- favicon = "data:image/svg+xml," .. encode(raw_favicon),
+ version = site_config.version,
+ title = site_config.title,
+ copyright = site_config.copyright,
+ favicon = site_config.favicon,
header = header or [[
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
-<link rel="icon" href="{{FAVICON}}">
+{{FAVICON}}
<title>{{TITLE}}</title>
<style>
html, body { min-height: 100%; margin: 0; padding: 0; background: #0f1113; color: #e6eef3; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.5; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
@@ -132,10 +125,9 @@ end
function M:build()
local header = self.header
- local safe_title = self.title or "Document"
- local safe_favicon = self.favicon:gsub("%%", "%%%%")
- header = header:gsub("{{TITLE}}", safe_title)
- header = header:gsub("{{FAVICON}}", safe_favicon)
+ header = header:gsub("{{TITLE}}", self.title or "Document")
+ local favicon_html = self.favicon and ('<link rel="icon" type="image/x-icon" href="' .. self.favicon .. '">')
+ header = header:gsub("{{FAVICON}}", favicon_html or [[<link rel="icon" href="data:image/svg+xml,<svg xmlns=%%22http://www.w3.org/2000/svg%%22 viewBox=%%220 0 100 100%%22><text y=%%22.9em%%22 font-size=%%2290%%22>🔥</text></svg>">]])
local footer = self.footer:gsub("{{COPYRIGHT}}", self.copyright or "© The Copyright Holder")
return header .. table.concat(self.parts, "\n") .. footer
end
diff --git a/examples/favicon/Fes.toml b/examples/favicon/Fes.toml
@@ -0,0 +1,5 @@
+[app]
+
+name = "favicon"
+version = "0.0.1"
+authors = ["vx-clutch"]
+\ No newline at end of file
diff --git a/examples/favicon/static/image/favicon.ico b/examples/favicon/static/image/favicon.ico
Binary files differ.
diff --git a/examples/favicon/www/index.lua b/examples/favicon/www/index.lua
@@ -0,0 +1,9 @@
+local fes = require("fes")
+local site = fes.fes()
+
+site.title = "favicon"
+site.favicon = "static/image/favicon.ico"
+
+site:h1("Hello, World!")
+
+return site
diff --git a/src/server/server.go b/src/server/server.go
@@ -24,10 +24,10 @@ type reqData struct {
params map[string]string
}
-func handleDir(entries []os.DirEntry, wwwDir string, routes map[string]string, base string) error {
+func handleDir(entries []os.DirEntry, dir string, routes map[string]string, base string) error {
for _, entry := range entries {
if entry.IsDir() {
- sub := filepath.Join("www", entry.Name())
+ sub := filepath.Join(dir, entry.Name())
subs, err := os.ReadDir(sub)
if err != nil {
return fmt.Errorf("failed to read %s: %w", sub, err)
@@ -45,7 +45,7 @@ func handleDir(entries []os.DirEntry, wwwDir string, routes map[string]string, b
}
if strings.HasSuffix(entry.Name(), ".lua") {
name := strings.TrimSuffix(entry.Name(), ".lua")
- path := filepath.Join("www", entry.Name())
+ path := filepath.Join(dir, entry.Name())
if name == "index" {
if base == "" {
routes["/"] = path
@@ -61,6 +61,14 @@ func handleDir(entries []os.DirEntry, wwwDir string, routes map[string]string, b
routes[base+"/"+name] = path
}
}
+ } else {
+ name := entry.Name()
+ path := filepath.Join(dir, entry.Name())
+ if base == "" {
+ routes["/"+name] = path
+ } else {
+ routes[base+"/"+name] = path
+ }
}
}
return nil
@@ -262,10 +270,6 @@ func Start(dir string) error {
return fmt.Errorf("failed to parse Fes.toml: %w", err)
}
- entries, err := os.ReadDir("www")
- if err != nil {
- return fmt.Errorf("failed to read www directory: %w", err)
- }
notFoundData := `
<html>
@@ -290,15 +294,25 @@ func Start(dir string) error {
}
routes := make(map[string]string)
+
+ entries, err := os.ReadDir("www")
+ if err != nil {
+ return fmt.Errorf("failed to read www directory: %w", err)
+ }
handleDir(entries, "www", routes, "")
+ entries, err = os.ReadDir("static")
+ if err == nil {
+ handleDir(entries, "static", routes, "")
+ }
+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
lp, ok := routes[path]
if !ok {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(notFoundData))
- fmt.Printf("> %s.lua ", filepath.Base(path))
+ fmt.Printf("> %s ", path)
color.Yellow("not found")
return
}