~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.


55c30218 Peter John

3 years ago
improve utils
_example/components/page.go CHANGED
@@ -3,8 +3,6 @@ package components
3
3
  import (
4
4
  "html/template"
5
5
 
6
- "github.com/pyros2097/gromer"
7
- "github.com/pyros2097/gromer/_example/assets"
8
6
  . "github.com/pyros2097/gromer/handlebars"
9
7
  )
10
8
 
@@ -239,19 +237,14 @@ func Page(props PageProps) *Template {
239
237
  <meta name="author" content="pyrossh" />
240
238
  <meta name="keywords" content="pyros.sh, pyrossh, gromer" />
241
239
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, viewport-fit=cover" />
242
- <link rel="icon" href="{{ iconUrl }}" />
240
+ <link rel="icon" href="{{ GetAssetUrl "images/icon.png" }}" />
243
- <link rel="stylesheet" href="{{ stylesCssUrl }}" />
241
+ <link rel="stylesheet" href="{{ GetStylesUrl }}" />
244
- <script src="{{ htmxJsUrl }}"></script>
242
+ <script src="{{ GetAlpineJsUrl }}"></script>
245
- <script src="{{ alpineJsUrl }}" defer=""></script>
243
+ <script src="{{ GetHtmxJsUrl }}" defer=""></script>
246
244
  </head>
247
245
  <body>
248
246
  {{ props.Children }}
249
247
  </body>
250
248
  </html>
251
- `).Props(
252
- "iconUrl", gromer.GetAssetUrl(assets.FS, "images/icon.png"),
253
- "stylesCssUrl", gromer.GetStylesUrl(),
254
- "htmxJsUrl", gromer.GetAssetUrl(assets.FS, "js/htmx@1.7.0.js"),
255
- "alpineJsUrl", gromer.GetAssetUrl(assets.FS, "js/alpinejs@3.9.6.js"),
256
- )
249
+ `)
257
250
  }
_example/main.go CHANGED
@@ -22,7 +22,7 @@ func init() {
22
22
 
23
23
  gromer.RegisterContainer(containers.TodoCount)
24
24
  gromer.RegisterContainer(containers.TodoList)
25
-
25
+ gromer.RegisterAssets(assets.FS)
26
26
  }
27
27
 
28
28
  func main() {
@@ -33,7 +33,8 @@ func main() {
33
33
 
34
34
  staticRouter := baseRouter.NewRoute().Subrouter()
35
35
  staticRouter.Use(gromer.CacheMiddleware)
36
+ gromer.GromerRoute(staticRouter, "/gromer/")
36
- gromer.StaticRoute(staticRouter, "/assets/", assets.FS)
37
+ gromer.StaticRoute(staticRouter, "/assets/")
37
38
  gromer.StylesRoute(staticRouter, "/styles.css")
38
39
 
39
40
  pageRouter := baseRouter.NewRoute().Subrouter()
_example/pages/get.go CHANGED
@@ -47,6 +47,15 @@ var _ = Css(`
47
47
  }
48
48
  `)
49
49
 
50
+ // var (
51
+ // Container = Css(`
52
+ // background: #fff;
53
+ // margin: 130px 0 40px 0;
54
+ // position: relative;
55
+ // box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
56
+ // `)
57
+ // )
58
+
50
59
  type GetParams struct {
51
60
  Page int `json:"page"`
52
61
  Filter string `json:"filter"`
{_example/assets → assets}/js/alpinejs@3.9.6.js RENAMED
File without changes
{_example/assets → assets}/js/htmx@1.7.0.js RENAMED
File without changes
cmd/gromer/main.go CHANGED
@@ -199,6 +199,7 @@ func init() {
199
199
  {{/each}}
200
200
  {{#each containerNames as |name| }}gromer.RegisterContainer(containers.{{ name }})
201
201
  {{/each}}
202
+ gromer.RegisterAssets(assets.FS)
202
203
  }
203
204
 
204
205
  func main() {
@@ -209,7 +210,8 @@ func main() {
209
210
  {{/if}}
210
211
  staticRouter := baseRouter.NewRoute().Subrouter()
211
212
  staticRouter.Use(gromer.CacheMiddleware)
213
+ gromer.GromerRoute(staticRouter, "/gromer/")
212
- gromer.StaticRoute(staticRouter, "/assets/", assets.FS)
214
+ gromer.StaticRoute(staticRouter, "/assets/")
213
215
  gromer.StylesRoute(staticRouter, "/styles.css")
214
216
 
215
217
  pageRouter := baseRouter.NewRoute().Subrouter()
go.mod CHANGED
@@ -20,6 +20,8 @@ require (
20
20
  require (
21
21
  cloud.google.com/go v0.94.0 // indirect
22
22
  cloud.google.com/go/firestore v1.5.0 // indirect
23
+ github.com/alecthomas/participle/v2 v2.0.0-alpha9 // indirect
24
+ github.com/alecthomas/repr v0.1.0 // indirect
23
25
  github.com/blang/semver v3.5.1+incompatible // indirect
24
26
  github.com/davecgh/go-spew v1.1.1 // indirect
25
27
  github.com/go-playground/locales v0.14.0 // indirect
go.sum CHANGED
@@ -99,6 +99,11 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
99
99
  github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
100
100
  github.com/GoogleCloudPlatform/cloudsql-proxy v1.24.0/go.mod h1:3tx938GhY4FC+E1KT/jNjDw7Z5qxAEtIiERJ2sXjnII=
101
101
  github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
102
+ github.com/alecthomas/participle/v2 v2.0.0-alpha9 h1:TnflwDbtf5/aG6JMbmdiA+YB3bLg0sc6yRtmAfedfN4=
103
+ github.com/alecthomas/participle/v2 v2.0.0-alpha9/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA=
104
+ github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
105
+ github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
106
+ github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
102
107
  github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
103
108
  github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
104
109
  github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
http.go CHANGED
@@ -22,6 +22,7 @@ import (
22
22
 
23
23
  "github.com/go-playground/validator/v10"
24
24
  "github.com/gorilla/mux"
25
+ "github.com/pyros2097/gromer/assets"
25
26
  "github.com/pyros2097/gromer/handlebars"
26
27
  "github.com/rs/zerolog"
27
28
  "github.com/rs/zerolog/log"
@@ -48,9 +49,14 @@ func init() {
48
49
  PartsExclude: []string{zerolog.TimestampFieldName},
49
50
  })
50
51
  }
52
+ handlebars.GlobalHelpers.Add("GetStylesUrl", GetStylesUrl)
53
+ handlebars.GlobalHelpers.Add("GetAssetUrl", GetAssetUrl)
54
+ handlebars.GlobalHelpers.Add("GetAlpineJsUrl", GetAlpineJsUrl)
55
+ handlebars.GlobalHelpers.Add("GetHtmxJsUrl", GetHtmxJsUrl)
51
56
  }
52
57
 
53
58
  var RouteDefs []RouteDefinition
59
+ var appAssets embed.FS
54
60
 
55
61
  type RouteDefinition struct {
56
62
  Pkg string `json:"pkg"`
@@ -66,6 +72,10 @@ func getFunctionName(temp interface{}) string {
66
72
  return strs[len(strs)-1]
67
73
  }
68
74
 
75
+ func RegisterAssets(fs embed.FS) {
76
+ appAssets = fs
77
+ }
78
+
69
79
  func RegisterComponent(fn any, props ...string) {
70
80
  name := getFunctionName(fn)
71
81
  fnType := reflect.TypeOf(fn)
@@ -449,8 +459,12 @@ func StatusHandler(h interface{}) http.Handler {
449
459
  })).(http.Handler)
450
460
  }
451
461
 
452
- func StaticRoute(router *mux.Router, path string, fs embed.FS) {
462
+ func StaticRoute(router *mux.Router, path string) {
453
- router.PathPrefix(path).Methods("GET").Handler(http.StripPrefix(path, http.FileServer(http.FS(fs))))
463
+ router.PathPrefix(path).Methods("GET").Handler(http.StripPrefix(path, http.FileServer(http.FS(appAssets))))
464
+ }
465
+
466
+ func GromerRoute(router *mux.Router, path string) {
467
+ router.PathPrefix(path).Methods("GET").Handler(http.StripPrefix(path, http.FileServer(http.FS(assets.FS))))
454
468
  }
455
469
 
456
470
  func StylesRoute(router *mux.Router, path string) {
@@ -488,9 +502,9 @@ func getSum(k string, cb func() [16]byte) string {
488
502
  return sum
489
503
  }
490
504
 
491
- func GetAssetUrl(fs embed.FS, path string) string {
505
+ func GetAssetUrl(path string) string {
492
506
  sum := getSum(path, func() [16]byte {
493
- data, err := fs.ReadFile(path)
507
+ data, err := appAssets.ReadFile(path)
494
508
  if err != nil {
495
509
  panic(err)
496
510
  }
@@ -499,6 +513,14 @@ func GetAssetUrl(fs embed.FS, path string) string {
499
513
  return fmt.Sprintf("/assets/%s?hash=%s", path, sum)
500
514
  }
501
515
 
516
+ func GetHtmxJsUrl() string {
517
+ return "/gromer/js/htmx@1.7.0.js"
518
+ }
519
+
520
+ func GetAlpineJsUrl() string {
521
+ return "/gromer/js/alpinejs@3.9.6.js"
522
+ }
523
+
502
524
  func GetStylesUrl() string {
503
525
  sum := getSum("styles.css", func() [16]byte {
504
526
  return md5.Sum([]byte(handlebars.GetStyles()))