alpha p6
This commit is contained in:
@@ -3,13 +3,8 @@ local std = require("core.std")
|
|||||||
local M = {}
|
local M = {}
|
||||||
M.__index = 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)
|
function M.fes(header, footer)
|
||||||
local config = {}
|
local config = {} local site_config = {}
|
||||||
local site_config = {}
|
|
||||||
local fes_mod = package.loaded.fes
|
local fes_mod = package.loaded.fes
|
||||||
if fes_mod and fes_mod.config then
|
if fes_mod and fes_mod.config then
|
||||||
config = fes_mod.config
|
config = fes_mod.config
|
||||||
@@ -18,20 +13,18 @@ function M.fes(header, footer)
|
|||||||
end
|
end
|
||||||
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 = {
|
local self = {
|
||||||
version = site_config.version or "",
|
version = site_config.version,
|
||||||
title = site_config.title or "Document",
|
title = site_config.title,
|
||||||
copyright = site_config.copyright or "© The Copyright Holder",
|
copyright = site_config.copyright,
|
||||||
favicon = "data:image/svg+xml," .. encode(raw_favicon),
|
favicon = site_config.favicon,
|
||||||
header = header or [[
|
header = header or [[
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="icon" href="{{FAVICON}}">
|
{{FAVICON}}
|
||||||
<title>{{TITLE}}</title>
|
<title>{{TITLE}}</title>
|
||||||
<style>
|
<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; }
|
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()
|
function M:build()
|
||||||
local header = self.header
|
local header = self.header
|
||||||
local safe_title = self.title or "Document"
|
header = header:gsub("{{TITLE}}", self.title or "Document")
|
||||||
local safe_favicon = self.favicon:gsub("%%", "%%%%")
|
local favicon_html = self.favicon and ('<link rel="icon" type="image/x-icon" href="' .. self.favicon .. '">')
|
||||||
header = header:gsub("{{TITLE}}", safe_title)
|
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>">]])
|
||||||
header = header:gsub("{{FAVICON}}", safe_favicon)
|
|
||||||
local footer = self.footer:gsub("{{COPYRIGHT}}", self.copyright or "© The Copyright Holder")
|
local footer = self.footer:gsub("{{COPYRIGHT}}", self.copyright or "© The Copyright Holder")
|
||||||
return header .. table.concat(self.parts, "\n") .. footer
|
return header .. table.concat(self.parts, "\n") .. footer
|
||||||
end
|
end
|
||||||
|
|||||||
5
examples/favicon/Fes.toml
Normal file
5
examples/favicon/Fes.toml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[app]
|
||||||
|
|
||||||
|
name = "favicon"
|
||||||
|
version = "0.0.1"
|
||||||
|
authors = ["vx-clutch"]
|
||||||
BIN
examples/favicon/static/image/favicon.ico
Normal file
BIN
examples/favicon/static/image/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
9
examples/favicon/www/index.lua
Normal file
9
examples/favicon/www/index.lua
Normal file
@@ -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
|
||||||
@@ -24,10 +24,10 @@ type reqData struct {
|
|||||||
params map[string]string
|
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 {
|
for _, entry := range entries {
|
||||||
if entry.IsDir() {
|
if entry.IsDir() {
|
||||||
sub := filepath.Join("www", entry.Name())
|
sub := filepath.Join(dir, entry.Name())
|
||||||
subs, err := os.ReadDir(sub)
|
subs, err := os.ReadDir(sub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read %s: %w", sub, err)
|
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") {
|
if strings.HasSuffix(entry.Name(), ".lua") {
|
||||||
name := strings.TrimSuffix(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 name == "index" {
|
||||||
if base == "" {
|
if base == "" {
|
||||||
routes["/"] = path
|
routes["/"] = path
|
||||||
@@ -61,6 +61,14 @@ func handleDir(entries []os.DirEntry, wwwDir string, routes map[string]string, b
|
|||||||
routes[base+"/"+name] = path
|
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
|
return nil
|
||||||
@@ -262,10 +270,6 @@ func Start(dir string) error {
|
|||||||
return fmt.Errorf("failed to parse Fes.toml: %w", err)
|
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 := `
|
notFoundData := `
|
||||||
<html>
|
<html>
|
||||||
@@ -290,15 +294,25 @@ func Start(dir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
routes := make(map[string]string)
|
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, "")
|
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) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
path := r.URL.Path
|
path := r.URL.Path
|
||||||
lp, ok := routes[path]
|
lp, ok := routes[path]
|
||||||
if !ok {
|
if !ok {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
w.Write([]byte(notFoundData))
|
w.Write([]byte(notFoundData))
|
||||||
fmt.Printf("> %s.lua ", filepath.Base(path))
|
fmt.Printf("> %s ", path)
|
||||||
color.Yellow("not found")
|
color.Yellow("not found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user