1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# gomponents
[](https://godoc.org/github.com/maragudk/gomponents)
[](https://codecov.io/gh/maragudk/gomponents)
gomponents are declarative view components in Go, that can render to HTML.
gomponents aims to make it easy to build HTML pages of reusable components,
without the use of a template language. Think server-side-rendered React,
but without the virtual DOM and diffing.
The implementation is still incomplete, but usable. The API may change until version 1 is reached.
Check out the blog post [gomponents: declarative view components in Go](https://www.maragu.dk/blog/gomponents-declarative-view-components-in-go/)
for background.
## Features
- Write declarative HTML in Go without all the strings, so you get
- Type safety
- Auto-completion
- Nice formatting with `gofmt`
- Simple API that's easy to learn and use
- Build reusable view components
- No external dependencies
## Usage
Get the library using `go get`:
```shell script
go get -u github.com/maragudk/gomponents
```
Then do something like this:
```go
package main
import (
"net/http"
g "github.com/maragudk/gomponents"
"github.com/maragudk/gomponents/attr"
"github.com/maragudk/gomponents/el"
)
func main() {
_ = http.ListenAndServe("localhost:8080", handler())
}
func handler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
page := Page("Hi!", r.URL.Path)
_ = page.Render(w)
}
}
func Page(title, path string) g.Node {
return el.Document(
el.HTML(
g.Attr("lang", "en"),
el.Head(
el.Title(title),
el.Style(g.Attr("type", "text/css"), g.Raw(".is-active{font-weight: bold}")),
),
el.Body(
Navbar(path),
el.H1(title),
el.P(g.Textf("Welcome to the page at %v.", path)),
),
),
)
}
func Navbar(path string) g.Node {
return g.El("nav",
el.A("/", attr.Classes{"is-active": path == "/"}, g.Text("Home")),
el.A("/about", attr.Classes{"is-active": path == "/about"}, g.Text("About")),
)
}
```
You could also use a page template to simplify your code a bit:
```go
package main
import (
"net/http"
g "github.com/maragudk/gomponents"
"github.com/maragudk/gomponents/attr"
c "github.com/maragudk/gomponents/components"
"github.com/maragudk/gomponents/el"
)
func main() {
_ = http.ListenAndServe("localhost:8080", handler())
}
func handler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
page := Page("Hi!", r.URL.Path)
_ = page.Render(w)
}
}
func Page(title, path string) g.Node {
return c.HTML5(c.DocumentProps{
Title: title,
Language: "en",
Head: []g.Node{el.Style(g.Attr("type", "text/css"), g.Raw(".is-active{font-weight: bold}"))},
Body: []g.Node{
Navbar(path),
el.H1(title),
el.P(g.Textf("Welcome to the page at %v.", path)),
},
})
}
func Navbar(path string) g.Node {
return g.El("nav",
el.A("/", attr.Classes{"is-active": path == "/"}, g.Text("Home")),
el.A("/about", attr.Classes{"is-active": path == "/about"}, g.Text("About")),
)
}
```
For more complete examples, see [the examples directory](examples/).
|