Skip to content

Commit d9a6bd5

Browse files
committed
feat: send data to template
1 parent 2c861f6 commit d9a6bd5

File tree

8 files changed

+102
-61
lines changed

8 files changed

+102
-61
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
h1 {
2+
color: red;
3+
text-align: center;
4+
}

code_examples/http/index.html renamed to code_examples/http/html/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>Zumbra</title>
7+
<link rel="stylesheet" href="/static/style.css">
78
</head>
89
<body>
910
<h1>Hello World</h1>
10-
<p>This is a zumbra test</p>
11+
<p>This is a test</p>
1112
</body>
1213
</html>
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
registerRoute("GET", "/", serveFile("index.html"));
2-
server(3333);
1+
serveStatic("/static", "./code_examples/http/html/assets");
2+
registerRoute("GET", "/", serveFile("./code_examples/http/html/index.html", {"name": "Zumbra"}));
3+
server(3333);

evaluator/builtins.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func init() {
1515
"indexOf", "addToDict", "deleteFromDict",
1616
"toString", "toInt", "toFloat", "toBool", "date", "organize", "toUppercase", "toLowercase", "capitalize",
1717
"removeWhiteSpaces", "sum", "bhaskara", "getFromDict", "sendEmail", "randomInteger", "randomFloat", "sendWhatsapp",
18-
"dictKeys", "dictValues", "replace", "server", "get", "json_parse", "registerRoute", "file", "html", "serveFile",
18+
"dictKeys", "dictValues", "replace", "server", "get", "json_parse", "registerRoute", "html", "serveFile", "serveStatic",
1919
}
2020

2121
for _, name := range names {

object/builtins/builtins.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,15 @@ var Builtins = []struct {
124124
{
125125
"registerRoute", RegisterRoutesBuiltin(),
126126
},
127-
{
128-
"file", FileBuiltin(),
129-
},
130127
{
131128
"html", HtmlHandlerBuiltin(),
132129
},
133130
{
134131
"serveFile", ServeFileBuiltin(),
135132
},
133+
{
134+
"serveStatic", ServerStaticBuiltin(),
135+
},
136136
}
137137

138138
func NewBoolean(value bool) *object.Boolean {

object/builtins/file_builtin.go

Lines changed: 0 additions & 54 deletions
This file was deleted.

object/builtins/http_builtins.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ type Route struct {
1515
Middlewares []func(http.ResponseWriter, *http.Request) bool
1616
}
1717

18+
type StaticRoute struct {
19+
RoutePrefix string
20+
StaticDir string
21+
}
22+
23+
var staticRoutes []StaticRoute
24+
1825
var registerRoutes []Route
1926

2027
func CreateServerBuiltin() *object.Builtin {
@@ -30,8 +37,13 @@ func CreateServerBuiltin() *object.Builtin {
3037
return NewError("argument to `server` must be INTEGER, got %s", args[0].Type())
3138
}
3239

40+
for _, sr := range staticRoutes {
41+
http.Handle(sr.RoutePrefix+"/", http.StripPrefix(sr.RoutePrefix, http.FileServer(http.Dir(sr.StaticDir))))
42+
}
43+
3344
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
3445
route := matchRoute(r)
46+
3547
if route == nil {
3648
http.NotFound(w, r)
3749
return
@@ -182,6 +194,30 @@ func HtmlHandlerBuiltin() *object.Builtin {
182194
}
183195
}
184196

197+
func ServerStaticBuiltin() *object.Builtin {
198+
return &object.Builtin{
199+
Fn: func(args ...object.Object) object.Object {
200+
if len(args) != 2 {
201+
return NewError("wrong number of arguments. got=%d, want=2", len(args))
202+
}
203+
204+
prefix, ok1 := args[0].(*object.String)
205+
dir, ok2 := args[1].(*object.String)
206+
207+
if !ok1 || !ok2 {
208+
return NewError("method and path must be STRING")
209+
}
210+
211+
staticRoutes = append(staticRoutes, StaticRoute{
212+
RoutePrefix: prefix.Value,
213+
StaticDir: dir.Value,
214+
})
215+
216+
return nil
217+
},
218+
}
219+
}
220+
185221
func matchRoute(r *http.Request) *Route {
186222
for _, route := range registerRoutes {
187223
if route.Method != r.Method {

object/builtins/serve_file_builtin.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package builtins
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"strings"
7+
"zumbra/object"
8+
)
9+
10+
func ServeFileBuiltin() *object.Builtin {
11+
return &object.Builtin{
12+
Fn: func(args ...object.Object) object.Object {
13+
if len(args) != 1 && len(args) != 2 {
14+
return NewError("serveFile expects 1 or 2 arguments")
15+
}
16+
17+
pathObj, ok := args[0].(*object.String)
18+
if !ok {
19+
return NewError("first argument to serveFile must be STRING, got=%s", args[0].Type())
20+
}
21+
22+
path := filepath.Clean(pathObj.Value)
23+
24+
content, err := os.ReadFile(path)
25+
if err != nil {
26+
return NewError("failed to read file: %s", err)
27+
}
28+
29+
html := string(content)
30+
31+
if len(args) == 1 {
32+
return &object.String{Value: html}
33+
}
34+
35+
dictObj, ok := args[1].(*object.Dict)
36+
if !ok {
37+
return NewError("second argument to serveFile must be DICT, got=%s", args[1].Type())
38+
}
39+
40+
for _, pair := range dictObj.Pairs {
41+
key, ok1 := pair.Key.(*object.String)
42+
value, ok2 := pair.Value.(*object.String)
43+
44+
if ok1 && ok2 {
45+
placeholder := "{{" + key.Value + "}}"
46+
html = strings.ReplaceAll(html, placeholder, value.Value)
47+
}
48+
}
49+
50+
return &object.String{Value: html}
51+
},
52+
}
53+
}

0 commit comments

Comments
 (0)