1
0
View components in pure Go, that render to HTML 5. https://www.gomponents.com
Go to file
2020-10-29 13:07:22 +01:00
.github/workflows Try out codecov.io (#5) 2020-09-18 14:05:53 +02:00
assert Make NodeFunc and attr implement fmt.Stringer (#6) 2020-09-18 14:38:09 +02:00
attr Add HTML5 document template (#36) 2020-10-29 12:03:43 +01:00
components Add HTML5 document template (#36) 2020-10-29 12:03:43 +01:00
el Add element helpers and refactor (#34) 2020-10-28 16:16:18 +01:00
examples/simple Add attribute helpers (#35) 2020-10-28 16:59:04 +01:00
.editorconfig Add better example in readme (#16) 2020-09-23 22:05:59 +02:00
.gitignore Add Makefile (#4) 2020-09-18 13:57:04 +02:00
CONTRIBUTING.md Add contributing instructions (#33) 2020-10-23 14:32:55 +02:00
go.mod Add first implementation of Node, El, Attr, Text 2020-09-13 22:50:19 +02:00
gomponents_test.go Don't render or error on nil children (#32) 2020-10-23 12:14:23 +02:00
gomponents.go Pass attributes as pointers (#37) 2020-10-29 13:07:22 +01:00
LICENSE Add first implementation of Node, El, Attr, Text 2020-09-13 22:50:19 +02:00
Makefile Add Makefile (#4) 2020-09-18 13:57:04 +02:00
README.md Add HTML5 document template (#36) 2020-10-29 12:03:43 +01:00

gomponents

GoDoc codecov

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 for background.

Usage

Get the library using go get:

go get -u github.com/maragudk/gomponents

Then do something like this:

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)
		_ = g.Write(w, page)
	}
}

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:

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)
		_ = g.Write(w, page)
	}
}

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.