3 ms·
This is a nice approach I've followed myself before. It feels like common sense web development, just writing things in a way which allows them to be reused. A
by Philip-J-Fry 2y ago
This is a nice approach I've followed myself before. It feels like common sense web development, just writing things in a way which allows them to be reused. A button will likely be the same on any page of the site, so make a button component.
I don't think this is "React-like" though. Making components isn't specific to React. We've been doing that since ASP and probably earlier. Your views still need to know what components to render here.
You can go further and just define a template function which takes a template name and a data object. Then render arbitrary children. That way your UI can be fully composed in code and the only thing your components need to know is how to render themselves.
var templateFS = os.DirFS("./templates/components/")
type Component interface {
Type() string
}
type Button struct {
Name string
}
func (b Button) Type() string {
return "button.html"
}
type Div struct {
Children []Component
}
func (d Div) Type() string {
return "div.html"
}
type Page struct {
Children []Component
}
func (p Page) Type() string {
return "page.html"
}
func main() {
component := Page{
Children: []Component{
Div{
Children: []Component{
Button{Name: "Test button"},
},
},
},
}
templates := template.New("")
funcs := template.FuncMap{
"exec": func(tpl string, data interface{}) template.HTML {
var sb strings.Builder
templates.ExecuteTemplate(&sb, tpl, data)
return template.HTML(sb.String())
},
}
templates = template.Must(templates.Funcs(funcs).ParseFS(templateFS, "*"))
templates.ExecuteTemplate(os.Stdout, component.Type(), component)
Your page.html file becomes
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{range .Children}}
{{exec .Type .}}
{{end}}
</body>
</html>
For example
- Trufa 2y agoI 100% know it's a preference/style kind of thing, and I know the React/Node isn't perfect and comes with it's downfalls, but I whenever I have to code in anything other, I just miss the visual/mental model aspect of having your tsx code basically identical to your actual html. The mental load of going from this to func main() { component := Page{ Children: []Component{ Div{ Children: []Component{ Button{Name: "Test button"}, }, }, }, } to this <Page> <div> <Button> Test button</Button> </div> </Page>` or going from this: const main = () => ( <Page> <div> <Button> Test button</Button> </div> </Page> ) To, well... case in point, exactly the same thing is just so nice.
- 38 2y agofair enough, but you're also downplaying/omitting the huge dependency cost of React, both server side and client side. so pick your poison. you're basically saying "I want server side code without having to actually code anything". of course nothing is going to beat react, its an impossible ask
- srhtftw 2y agoReminds me of https://github.com/8byt/gox https://github.com/8byt/gox which I bookmarked when working with Go but never got around to using.