~repos /gromer

#golang#htmx#ssr

git clone https://pyrossh.dev/repos/gromer.git

gromer is a framework and cli to build multipage web apps in golang using htmx and alpinejs.


20c6446c pyros2097

tag: v0.2.0

v0.2.0

5 years ago
make new helmet api
app_common.go ADDED
@@ -0,0 +1,15 @@
1
+ package app
2
+
3
+ var (
4
+ body *elem
5
+ content UI
6
+ renderFunc RenderFunc
7
+ helmet = &Helmet{}
8
+ )
9
+
10
+ type Helmet struct {
11
+ Title string
12
+ Description string
13
+ Keywords string
14
+ Author string
15
+ }
app_nowasm.go CHANGED
@@ -66,12 +66,12 @@ func Reload() {
66
66
  panic("wasm required")
67
67
  }
68
68
 
69
- func Route(path string, render RenderFunc, info RouteInfo) {
69
+ func Route(path string, render RenderFunc) {
70
70
  println("registering route: " + path)
71
71
  router.GET(path, render)
72
72
  }
73
73
 
74
- func createPage(info RouteInfo, ui UI) *bytes.Buffer {
74
+ func createPage(ui UI) *bytes.Buffer {
75
75
  isLambda := os.Getenv("_LAMBDA_SERVER_PORT") != ""
76
76
  page := bytes.NewBuffer(nil)
77
77
  page.WriteString("<!DOCTYPE html>\n")
@@ -82,10 +82,10 @@ func createPage(info RouteInfo, ui UI) *bytes.Buffer {
82
82
  }
83
83
  Html(
84
84
  Head(
85
- Title(info.Title),
85
+ Title(helmet.Title),
86
- Meta("description", info.Description),
86
+ Meta("description", helmet.Description),
87
- Meta("author", info.Author),
87
+ Meta("author", helmet.Author),
88
- Meta("keywords", info.Keywords),
88
+ Meta("keywords", helmet.Keywords),
89
89
  Meta("viewport", "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover"),
90
90
  Link("icon", basePath+"icon.png"),
91
91
  Link("apple-touch-icon", basePath+"icon.png"),
app_wasm.go CHANGED
@@ -7,13 +7,6 @@ import (
7
7
  "github.com/pyros2097/wapp/js"
8
8
  )
9
9
 
10
- var (
11
- body *elem
12
- content UI
13
- rootPrefix string
14
- renderFunc RenderFunc
15
- )
16
-
17
10
  func Run() {
18
11
  handle, _, _ := router.Lookup("GET", js.Window.URL().Path)
19
12
  if handle == nil {
@@ -52,7 +45,7 @@ func Reload() {
52
45
  })
53
46
  }
54
47
 
55
- func Route(path string, render RenderFunc, info RouteInfo) {
48
+ func Route(path string, render RenderFunc) {
56
49
  router.GET(path, render)
57
50
  }
58
51
 
@@ -88,6 +81,6 @@ func initContent() {
88
81
  // return u.Fragment != ""
89
82
  // }
90
83
 
91
- func createPage(info RouteInfo, ui UI) *bytes.Buffer {
84
+ func createPage(ui UI) *bytes.Buffer {
92
85
  return &bytes.Buffer{}
93
86
  }
attributes.go CHANGED
@@ -36,6 +36,11 @@ func OnInput(cb js.EventHandlerFunc) OnInputAttribute {
36
36
  return OnInputAttribute{cb: cb}
37
37
  }
38
38
 
39
+ type HelmetTitle string
40
+ type HelmetDescription string
41
+ type HelmetAuthor string
42
+ type HelmetKeywords string
43
+
39
44
  func mergeAttributes(parent *elem, uis ...interface{}) {
40
45
  elems := []interface{}{}
41
46
  for _, v := range uis {
@@ -54,8 +59,18 @@ func mergeAttributes(parent *elem, uis ...interface{}) {
54
59
  parent.setEventHandler("change", c.cb)
55
60
  case OnInputAttribute:
56
61
  parent.setEventHandler("input", c.cb)
62
+ case HelmetTitle:
63
+ helmet.Title = string(c)
64
+ case HelmetDescription:
65
+ helmet.Description = string(c)
66
+ case HelmetAuthor:
67
+ helmet.Author = string(c)
68
+ case HelmetKeywords:
69
+ helmet.Keywords = string(c)
57
70
  case UI:
58
71
  elems = append(elems, c)
72
+ default:
73
+ panic("unknown type in render")
59
74
  }
60
75
  }
61
76
  parent.setBody(elems...)
attributes_test.go CHANGED
@@ -28,7 +28,7 @@ func Counter(c *RenderContext) UI {
28
28
  )
29
29
  }
30
30
 
31
- func TestRoute(c *RenderContext) UI {
31
+ func HomeRoute(c *RenderContext) UI {
32
32
  return Div(
33
33
  Div(),
34
34
  Counter(c),
@@ -42,7 +42,7 @@ func TestCreatePage(t *testing.T) {
42
42
  Head(
43
43
  Title("Title"),
44
44
  ),
45
- Body(TestRoute(NewRenderContext())),
45
+ Body(HomeRoute(NewRenderContext())),
46
46
  ).Html(page)
47
47
  assert.Equal(t, "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"UTF-8\">\n <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n <meta http-equiv=\"encoding\" content=\"utf-8\">\n <title>\n Title\n </title>\n </head>\n <body>\n <div>\n <div></div>\n <div class=\"flex flex-col justify-center align-items-center\">\n <div class=\"flex flex-row justify-center align-items-center yellow\">\n Counter\n </div>\n <div class=\"flex flex-row justify-center align-items-center\">\n <div>\n -\n </div>\n <div>\n 0\n </div>\n <div>\n +\n </div>\n </div>\n </div>\n </div>\n </body>\n</html>", page.String())
48
48
  }
example/about.go CHANGED
@@ -5,5 +5,11 @@ import (
5
5
  )
6
6
 
7
7
  func About(c *RenderContext) UI {
8
+ return Div(
9
+ HelmetTitle("wapp-example"),
10
+ HelmetDescription("wapp is a framework"),
11
+ HelmetAuthor("pyros2097"),
12
+ HelmetKeywords("wapp,wapp-example,golang,framework,frontend,ui,wasm,isomorphic"),
8
- return Div(Text("About Me"))
13
+ Text("About Me"),
14
+ )
9
15
  }
example/example DELETED
Binary file
example/main.go CHANGED
@@ -5,15 +5,9 @@ import (
5
5
  )
6
6
 
7
7
  func main() {
8
- info := RouteInfo{
9
- Title: "wapp-example",
10
- Description: "wapp is a framework",
11
- Author: "pyros2097",
12
- Keywords: "wapp,wapp-example,golang,framework,frontend,ui,wasm,isomorphic",
13
- }
14
- Route("/about", About, info)
8
+ Route("/about", About)
15
- Route("/clock", Clock, info)
9
+ Route("/clock", Clock)
16
- Route("/container", Container, info)
10
+ Route("/container", Container)
17
- Route("/", Index, info)
11
+ Route("/", Index)
18
12
  Run()
19
13
  }
makefile DELETED
@@ -1,13 +0,0 @@
1
- bootstrap:
2
- @echo "\033[94m• Setting up go test for wasm to run in the browser\033[00m"
3
- go get -u github.com/agnivade/wasmbrowsertest
4
- mv ${GOPATH}/bin/wasmbrowsertest ${GOPATH}/bin/go_js_wasm_exec
5
-
6
- .PHONY: test
7
- test:
8
- @echo "\033[94m• Running Go vet\033[00m"
9
- go vet ./...
10
- @echo "\033[94m\n• Running Go tests\033[00m"
11
- go test -race ./...
12
- @echo "\033[94m\n• Running go wasm tests\033[00m"
13
- GOARCH=wasm GOOS=js go test ./pkg/app
tree.go → router.go RENAMED
@@ -1185,7 +1185,7 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
1185
1185
  if handle, _, tsr := root.getValue(path, r.getParams); handle != nil {
1186
1186
  println("route: " + req.URL.Path)
1187
1187
  if render, ok := handle.(RenderFunc); ok {
1188
- page := createPage(RouteInfo{}, render(NewRenderContext()))
1188
+ page := createPage(render(NewRenderContext()))
1189
1189
  w.Header().Set("Content-Length", strconv.Itoa(page.Len()))
1190
1190
  w.Header().Set("Content-Type", "text/html")
1191
1191
  w.WriteHeader(http.StatusOK)
@@ -1255,13 +1255,13 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
1255
1255
 
1256
1256
  // Handle 404
1257
1257
  if r.NotFound != nil {
1258
- page := createPage(RouteInfo{}, r.NotFound(NewRenderContext()))
1258
+ page := createPage(r.NotFound(NewRenderContext()))
1259
1259
  w.Header().Set("Content-Length", strconv.Itoa(page.Len()))
1260
1260
  w.Header().Set("Content-Type", "text/html")
1261
1261
  w.WriteHeader(http.StatusOK)
1262
1262
  w.Write(page.Bytes())
1263
1263
  } else {
1264
- page := createPage(RouteInfo{}, DefaultNotFound(NewRenderContext()))
1264
+ page := createPage(DefaultNotFound(NewRenderContext()))
1265
1265
  w.Header().Set("Content-Length", strconv.Itoa(page.Len()))
1266
1266
  w.Header().Set("Content-Type", "text/html")
1267
1267
  w.WriteHeader(http.StatusOK)
utils.go CHANGED
@@ -48,10 +48,3 @@ func btos(b []byte) string {
48
48
  func stob(s string) []byte {
49
49
  return *(*[]byte)(unsafe.Pointer(&s))
50
50
  }
51
-
52
- type RouteInfo struct {
53
- Title string
54
- Description string
55
- Author string
56
- Keywords string
57
- }
utils_test.go DELETED
@@ -1,22 +0,0 @@
1
- package app
2
-
3
- import (
4
- "testing"
5
-
6
- "github.com/stretchr/testify/assert"
7
- )
8
-
9
- func stubRoute(c *RenderContext) UI {
10
- return Div(Text("Stub"))
11
- }
12
-
13
- var testRoutes = map[string]RenderFunc{
14
- "/about": stubRoute,
15
- "/clock": stubRoute,
16
- "/container": stubRoute,
17
- "/": stubRoute,
18
- }
19
-
20
- func TestMatchPath(t *testing.T) {
21
- assert.Equal(t, true, matchPath("/", "/about"))
22
- }