Created
November 27, 2024 15:32
-
-
Save hawx/ecf41b22d2fd61fa6f4055daf92fbfdc to your computer and use it in GitHub Desktop.
Elm style templating for Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"os" | |
) | |
type Attr map[string]string | |
func (a Attr) writeTo(w io.Writer) error { | |
for k, v := range a { | |
if _, err := w.Write([]byte{' '}); err != nil { | |
return err | |
} | |
if _, err := w.Write([]byte(k)); err != nil { | |
return err | |
} | |
if _, err := w.Write([]byte{'=', '"'}); err != nil { | |
return err | |
} | |
if _, err := w.Write([]byte(v)); err != nil { | |
return err | |
} | |
if _, err := w.Write([]byte{'"'}); err != nil { | |
return err | |
} | |
} | |
return nil | |
} | |
type Node struct { | |
text string | |
// or | |
el string | |
attr Attr | |
children []Node | |
} | |
func (n Node) writeTo(w io.Writer) error { | |
if n.text != "" { | |
_, err := w.Write([]byte(n.text)) | |
return err | |
} | |
w.Write([]byte{'<'}) | |
w.Write([]byte(n.el)) | |
n.attr.writeTo(w) | |
w.Write([]byte{'>'}) | |
for _, child := range n.children { | |
child.writeTo(w) | |
} | |
w.Write([]byte{'<', '/'}) | |
w.Write([]byte(n.el)) | |
w.Write([]byte{'>'}) | |
return nil | |
} | |
func h(el string, attr Attr, children []Node) Node { | |
return Node{el: el, attr: attr, children: children} | |
} | |
func text(s string) Node { | |
return Node{text: s} | |
} | |
func render(w io.Writer, node Node) error { | |
return node.writeTo(w) | |
} | |
// so could then export | |
func Body(attr Attr, children []Node) Node { | |
return h("body", attr, children) | |
} | |
func Div(attr Attr, children []Node) Node { | |
return h("div", attr, children) | |
} | |
func H1(attr Attr, children []Node) Node { | |
return h("h1", attr, children) | |
} | |
// and similar helpers for Attr if wanted | |
func main() { | |
doc := Body(Attr{}, []Node{ | |
Div(Attr{"class": "box"}, []Node{ | |
H1(Attr{"class": "heading-big"}, []Node{ | |
text("Hello"), | |
}), | |
}), | |
}) | |
render(os.Stdout, doc) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment