~repos /gromer
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.
78c3dc4e
—
Peter John 3 years ago
rename example
- _example/components/todo.go +1 -1
- _example/db/init.go +1 -1
- _example/main.go +7 -7
- _example/makefile +1 -1
- _example/pages/api/todos/_todoId_/delete.go +1 -1
- _example/pages/api/todos/_todoId_/get.go +1 -1
- _example/pages/api/todos/_todoId_/put.go +1 -1
- _example/pages/api/todos/get.go +1 -1
- _example/pages/api/todos/post.go +1 -1
- _example/pages/get.go +2 -2
- api_explorer.go +14 -1
- go.mod +1 -0
- go.sum +2 -0
- http.go +1 -1
- readme.md +26 -21
_example/components/todo.go
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
package components
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
"github.com/pyros2097/gromer/
|
|
4
|
+
"github.com/pyros2097/gromer/_example/db"
|
|
5
5
|
. "github.com/pyros2097/gromer/handlebars"
|
|
6
6
|
)
|
|
7
7
|
|
_example/db/init.go
CHANGED
|
@@ -4,7 +4,7 @@ import (
|
|
|
4
4
|
"database/sql"
|
|
5
5
|
|
|
6
6
|
_ "github.com/lib/pq"
|
|
7
|
-
"github.com/pyros2097/gromer/
|
|
7
|
+
"github.com/pyros2097/gromer/_example/config"
|
|
8
8
|
)
|
|
9
9
|
|
|
10
10
|
var Query *Queries
|
_example/main.go
CHANGED
|
@@ -9,13 +9,13 @@ import (
|
|
|
9
9
|
"github.com/rs/zerolog/log"
|
|
10
10
|
"gocloud.dev/server"
|
|
11
11
|
|
|
12
|
-
"github.com/pyros2097/gromer/
|
|
12
|
+
"github.com/pyros2097/gromer/_example/assets"
|
|
13
|
-
"github.com/pyros2097/gromer/
|
|
13
|
+
"github.com/pyros2097/gromer/_example/components"
|
|
14
|
-
"github.com/pyros2097/gromer/
|
|
14
|
+
"github.com/pyros2097/gromer/_example/pages"
|
|
15
|
-
"github.com/pyros2097/gromer/
|
|
15
|
+
"github.com/pyros2097/gromer/_example/pages/about"
|
|
16
|
-
"github.com/pyros2097/gromer/
|
|
16
|
+
"github.com/pyros2097/gromer/_example/pages/api/recover"
|
|
17
|
-
"github.com/pyros2097/gromer/
|
|
17
|
+
"github.com/pyros2097/gromer/_example/pages/api/todos"
|
|
18
|
-
"github.com/pyros2097/gromer/
|
|
18
|
+
"github.com/pyros2097/gromer/_example/pages/api/todos/_todoId_"
|
|
19
19
|
|
|
20
20
|
)
|
|
21
21
|
|
_example/makefile
CHANGED
|
@@ -23,7 +23,7 @@ build:
|
|
|
23
23
|
go build -o main
|
|
24
24
|
|
|
25
25
|
docker-build:
|
|
26
|
-
docker build -f ../
|
|
26
|
+
docker build -f ../_example/Dockerfile -t example-app:develop ../
|
|
27
27
|
|
|
28
28
|
docker-run: export DATABASE_URL=postgres://postgres:demo@docker.for.mac.host.internal:5432/postgres?sslmode=disable
|
|
29
29
|
docker-run:
|
_example/pages/api/todos/_todoId_/delete.go
CHANGED
|
@@ -3,7 +3,7 @@ package todos_todoId_
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
5
|
|
|
6
|
-
"github.com/pyros2097/gromer/
|
|
6
|
+
"github.com/pyros2097/gromer/_example/db"
|
|
7
7
|
)
|
|
8
8
|
|
|
9
9
|
func DELETE(ctx context.Context, id string) (string, int, error) {
|
_example/pages/api/todos/_todoId_/get.go
CHANGED
|
@@ -5,7 +5,7 @@ import (
|
|
|
5
5
|
"fmt"
|
|
6
6
|
"strings"
|
|
7
7
|
|
|
8
|
-
"github.com/pyros2097/gromer/
|
|
8
|
+
"github.com/pyros2097/gromer/_example/db"
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
type GetParams struct {
|
_example/pages/api/todos/_todoId_/put.go
CHANGED
|
@@ -4,7 +4,7 @@ import (
|
|
|
4
4
|
"context"
|
|
5
5
|
"time"
|
|
6
6
|
|
|
7
|
-
"github.com/pyros2097/gromer/
|
|
7
|
+
"github.com/pyros2097/gromer/_example/db"
|
|
8
8
|
)
|
|
9
9
|
|
|
10
10
|
type PutParams struct {
|
_example/pages/api/todos/get.go
CHANGED
|
@@ -4,7 +4,7 @@ import (
|
|
|
4
4
|
"context"
|
|
5
5
|
|
|
6
6
|
. "github.com/pyros2097/gromer"
|
|
7
|
-
"github.com/pyros2097/gromer/
|
|
7
|
+
"github.com/pyros2097/gromer/_example/db"
|
|
8
8
|
)
|
|
9
9
|
|
|
10
10
|
type GetParams struct {
|
_example/pages/api/todos/post.go
CHANGED
|
@@ -5,7 +5,7 @@ import (
|
|
|
5
5
|
"time"
|
|
6
6
|
|
|
7
7
|
"github.com/google/uuid"
|
|
8
|
-
"github.com/pyros2097/gromer/
|
|
8
|
+
"github.com/pyros2097/gromer/_example/db"
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
type PostParams struct {
|
_example/pages/get.go
CHANGED
|
@@ -4,8 +4,8 @@ import (
|
|
|
4
4
|
"context"
|
|
5
5
|
|
|
6
6
|
. "github.com/pyros2097/gromer"
|
|
7
|
-
_ "github.com/pyros2097/gromer/
|
|
7
|
+
_ "github.com/pyros2097/gromer/_example/components"
|
|
8
|
-
"github.com/pyros2097/gromer/
|
|
8
|
+
"github.com/pyros2097/gromer/_example/pages/api/todos"
|
|
9
9
|
. "github.com/pyros2097/gromer/handlebars"
|
|
10
10
|
)
|
|
11
11
|
|
api_explorer.go
CHANGED
|
@@ -6,6 +6,7 @@ import (
|
|
|
6
6
|
"html/template"
|
|
7
7
|
"strings"
|
|
8
8
|
|
|
9
|
+
"github.com/carlmjohnson/versioninfo"
|
|
9
10
|
. "github.com/pyros2097/gromer/handlebars"
|
|
10
11
|
)
|
|
11
12
|
|
|
@@ -461,6 +462,14 @@ func ApiExplorer(ctx context.Context) (HtmlContent, int, error) {
|
|
|
461
462
|
justify-content: flex-start;
|
|
462
463
|
}
|
|
463
464
|
|
|
465
|
+
.flex-1 {
|
|
466
|
+
flex: 1;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.justify-end {
|
|
470
|
+
justify-content: flex-end;
|
|
471
|
+
}
|
|
472
|
+
|
|
464
473
|
.mr-4 {
|
|
465
474
|
margin-right: 1rem;
|
|
466
475
|
}
|
|
@@ -572,7 +581,7 @@ func ApiExplorer(ctx context.Context) (HtmlContent, int, error) {
|
|
|
572
581
|
<body>
|
|
573
582
|
<div class="flex flex-col">
|
|
574
583
|
<div class="flex w-full p-2 bg-gray-50 border-b border-gray-200 items-center justify-start">
|
|
575
|
-
<div class="flex mr-4 text-gray-700 text-2xl font-bold"> API Explorer
|
|
584
|
+
<div class="flex mr-4 text-gray-700 text-2xl font-bold"> API Explorer</div>
|
|
576
585
|
<div class="text-xl">
|
|
577
586
|
<select id="api-select" class="form-select block">
|
|
578
587
|
{{#each routes as |route|}}
|
|
@@ -585,6 +594,9 @@ func ApiExplorer(ctx context.Context) (HtmlContent, int, error) {
|
|
|
585
594
|
<div class="flex ml-3 mr-3">
|
|
586
595
|
<button id="run" class="bg-gray-200 border border-gray-400 hover:bg-gray-200 focus:outline-none rounded-md text-gray-700 text-md font-bold pt-2 pb-2 pl-6 pr-6"> RUN </button>
|
|
587
596
|
</div>
|
|
597
|
+
<div class="flex flex-1 justify-end">
|
|
598
|
+
(commit {{ commit }})
|
|
599
|
+
</div>
|
|
588
600
|
</div>
|
|
589
601
|
<div class="flex">
|
|
590
602
|
<div class="flex flex-row" style="width: 50%;;">
|
|
@@ -783,6 +795,7 @@ func ApiExplorer(ctx context.Context) (HtmlContent, int, error) {
|
|
|
783
795
|
</body>
|
|
784
796
|
</html>
|
|
785
797
|
`).Props(
|
|
798
|
+
"commit", versioninfo.Revision[0:7],
|
|
786
799
|
"routes", apiRoutes,
|
|
787
800
|
"apiData", template.HTML(string(apiData)),
|
|
788
801
|
).Render()
|
go.mod
CHANGED
|
@@ -22,6 +22,7 @@ require (
|
|
|
22
22
|
cloud.google.com/go/firestore v1.5.0 // indirect
|
|
23
23
|
github.com/aymerick/douceur v0.2.0 // indirect
|
|
24
24
|
github.com/aymerick/raymond v2.0.2+incompatible // indirect
|
|
25
|
+
github.com/carlmjohnson/versioninfo v0.22.1 // indirect
|
|
25
26
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
26
27
|
github.com/go-playground/locales v0.14.0 // indirect
|
|
27
28
|
github.com/go-playground/universal-translator v0.18.0 // indirect
|
go.sum
CHANGED
|
@@ -132,6 +132,8 @@ github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76e
|
|
|
132
132
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
|
133
133
|
github.com/bradleyjkemp/cupaloy v2.3.0+incompatible h1:UafIjBvWQmS9i/xRg+CamMrnLTKNzo+bdmT/oH34c2Y=
|
|
134
134
|
github.com/bradleyjkemp/cupaloy v2.3.0+incompatible/go.mod h1:Au1Xw1sgaJ5iSFktEhYsS0dbQiS1B0/XMXl+42y9Ilk=
|
|
135
|
+
github.com/carlmjohnson/versioninfo v0.22.1 h1:NVwTmCUpSoxBxy8+z10CbyBazeRZ4R2n6QgrNi3Wd6M=
|
|
136
|
+
github.com/carlmjohnson/versioninfo v0.22.1/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8=
|
|
135
137
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
136
138
|
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
137
139
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
http.go
CHANGED
|
@@ -329,7 +329,7 @@ func WrapCache(h http.Handler) http.Handler {
|
|
|
329
329
|
}
|
|
330
330
|
|
|
331
331
|
func Static(router *mux.Router, path string, fs embed.FS) {
|
|
332
|
-
router.PathPrefix(path).Handler(http.StripPrefix(path,
|
|
332
|
+
router.PathPrefix(path).Handler(http.StripPrefix(path, http.FileServer(http.FS(fs))))
|
|
333
333
|
}
|
|
334
334
|
|
|
335
335
|
func Handle(router *mux.Router, method, route string, h interface{}) {
|
readme.md
CHANGED
|
@@ -3,10 +3,15 @@
|
|
|
3
3
|
[](https://github.com/pyros2097/gromer)
|
|
4
4
|
|
|
5
5
|
**gromer** is a framework and cli to build web apps in golang.
|
|
6
|
-
It uses a declarative syntax using
|
|
6
|
+
It uses a declarative syntax using inline handlebar templates for components and pages.
|
|
7
|
-
|
|
8
7
|
It also generates http handlers for your routes which follow a particular folder structure. Similar to other frameworks like nextjs, sveltekit.
|
|
9
|
-
These handlers are also normal functions and can be imported in other packages directly ((inspired by [Encore](https://encore.dev/)).
|
|
8
|
+
These handlers are also normal functions and can be imported in other packages directly. ((inspired by [Encore](https://encore.dev/)).
|
|
9
|
+
|
|
10
|
+
# Requirements
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
go >= v1.18
|
|
14
|
+
```
|
|
10
15
|
|
|
11
16
|
# Install
|
|
12
17
|
|
|
@@ -33,10 +38,10 @@ Let's assume you have a template (a string of some kind):
|
|
|
33
38
|
|
|
34
39
|
```handlebars
|
|
35
40
|
<!-- some input -->
|
|
36
|
-
<h1>{{
|
|
41
|
+
<h1>{{name}}</h1>
|
|
37
42
|
<ul>
|
|
38
43
|
{{#each names}}
|
|
39
|
-
<li>{{
|
|
44
|
+
<li>{{@value}}</li>
|
|
40
45
|
{{/each}}
|
|
41
46
|
</ul>
|
|
42
47
|
```
|
|
@@ -56,7 +61,7 @@ Given that string, you can render the template like such:
|
|
|
56
61
|
### If Statements
|
|
57
62
|
|
|
58
63
|
```handlebars
|
|
59
|
-
{{#if true
|
|
64
|
+
{{#if true}}
|
|
60
65
|
render this
|
|
61
66
|
{{/if}}
|
|
62
67
|
```
|
|
@@ -64,9 +69,9 @@ Given that string, you can render the template like such:
|
|
|
64
69
|
#### Else Statements
|
|
65
70
|
|
|
66
71
|
```handlebars
|
|
67
|
-
{{#if false
|
|
72
|
+
{{#if false}}
|
|
68
73
|
won't render this
|
|
69
|
-
{{
|
|
74
|
+
{{else}}
|
|
70
75
|
render this
|
|
71
76
|
{{/if}}
|
|
72
77
|
```
|
|
@@ -74,7 +79,7 @@ Given that string, you can render the template like such:
|
|
|
74
79
|
#### Unless Statements
|
|
75
80
|
|
|
76
81
|
```handlebars
|
|
77
|
-
{{#unless true
|
|
82
|
+
{{#unless true}}
|
|
78
83
|
won't render this
|
|
79
84
|
{{/unless}}
|
|
80
85
|
```
|
|
@@ -85,15 +90,15 @@ Given that string, you can render the template like such:
|
|
|
85
90
|
|
|
86
91
|
When looping through `arrays` or `slices`, the block being looped through will be access to the "global" context, as well as have four new variables available within that block:
|
|
87
92
|
|
|
88
|
-
|
|
93
|
+
- `@first` [`bool`] - is this the first pass through the iteration?
|
|
89
|
-
|
|
94
|
+
- `@last` [`bool`] - is this the last pass through the iteration?
|
|
90
|
-
|
|
95
|
+
- `@index` [`int`] - the counter of where in the loop you are, starting with `0`.
|
|
91
|
-
|
|
96
|
+
- `@value` - the current element in the array or slice that is being iterated over.
|
|
92
97
|
|
|
93
98
|
```handlebars
|
|
94
99
|
<ul>
|
|
95
100
|
{{#each names}}
|
|
96
|
-
<li>{{
|
|
101
|
+
<li>{{@index}} - {{@value}}</li>
|
|
97
102
|
{{/each}}
|
|
98
103
|
</ul>
|
|
99
104
|
```
|
|
@@ -103,7 +108,7 @@ By using "block parameters" you can change the "key" of the element being access
|
|
|
103
108
|
```handlebars
|
|
104
109
|
<ul>
|
|
105
110
|
{{#each names as |name|}}
|
|
106
|
-
<li>{{
|
|
111
|
+
<li>{{name}}</li>
|
|
107
112
|
{{/each}}
|
|
108
113
|
</ul>
|
|
109
114
|
```
|
|
@@ -122,15 +127,15 @@ To change both the key and the index name you can pass two "block parameters"; t
|
|
|
122
127
|
|
|
123
128
|
Looping through `maps` using the `each` helper is also supported, and follows very similar guidelines to looping through `arrays`.
|
|
124
129
|
|
|
125
|
-
|
|
130
|
+
- `@first` [`bool`] - is this the first pass through the iteration?
|
|
126
|
-
|
|
131
|
+
- `@last` [`bool`] - is this the last pass through the iteration?
|
|
127
|
-
|
|
132
|
+
- `@key` - the key of the pair being accessed.
|
|
128
|
-
|
|
133
|
+
- `@value` - the value of the pair being accessed.
|
|
129
134
|
|
|
130
135
|
```handlebars
|
|
131
136
|
<ul>
|
|
132
137
|
{{#each users}}
|
|
133
|
-
<li>{{
|
|
138
|
+
<li>{{@key}} - {{@value}}</li>
|
|
134
139
|
{{/each}}
|
|
135
140
|
</ul>
|
|
136
141
|
```
|
|
@@ -140,7 +145,7 @@ By using "block parameters" you can change the "key" of the element being access
|
|
|
140
145
|
```handlebars
|
|
141
146
|
<ul>
|
|
142
147
|
{{#each users as |user|}}
|
|
143
|
-
<li>{{
|
|
148
|
+
<li>{{@key}} - {{user}}</li>
|
|
144
149
|
{{/each}}
|
|
145
150
|
</ul>
|
|
146
151
|
```
|