GoDOM is a Go library that allows for the creation and rendering of HTML elements in a type-safe and idiomatic manner. It draws inspiration from the gomponents library, providing an alternative approach for constructing HTML in Go.
- Type-Safe Elements and Attributes: GoDOM offers a strong typing system to prevent runtime errors due to incorrect usage of elements or attributes.
- Easily Extensible: Use custom elements and attributes, or extend the existing ones.
- Conditional Rendering: GoDOM supports conditional attributes and elements, which allows elements or attributes to be included or excluded based on certain conditions.
- Delayed Rendering: Elements and attributes can be constructed immediately before rendering, allowing for dynamic changes between the time of construction and the rendering phase.
- html/template integration: GoDOM can be used together with
While both GoDOM and gomponents provide tools for constructing HTML in Go, there are notable differences:
- Design Philosophy: While gomponents focuses on creating a pure-functional way of building HTML, GoDOM provides a more direct way of working with elements and attributes.
- Additional Features: GoDOM offers features like delayed and conditional rendering out of the box.
If you're looking for a purely functional approach, gomponents might be more suitable. If you want a direct way of manipulating and rendering HTML with additional utilities or want to implement a reusable set of advanced components, GoDOM is the way to go.
Here's a basic example of using GoDOM:
Imagine you're building a blog post page. The blog post might have an optional author bio, and if the blog post is featured, it might have special stylings.
package main
import (
"bytes"
"fmt"
. "github.com/tbe/godom"
"github.com/tbe/godom/helpers"
"github.com/tbe/godom/util"
)
func main() {
isFeatured := true // this can be dynamically set based on data
showAuthorBio := true
// Conditional class for featured post
featuredClass := util.IfAttr(isFeatured, Class("featured"))
// Conditional author bio
authorBio := util.IfElem(showAuthorBio, Div(Class("author-bio"))(
P()(Content("This is the author's bio. It provides information about the author.")),
))
// Delayed attribute example: A function that decides the attribute based on some condition
dynamicAttribute := util.DelayedAttribute(func(attrs map[string]string, _ *[]string, _ *[]types.Attribute) {
if isFeatured {
attrs["data-highlight"] = "true"
}
})
// Delayed element: Maybe we decide to render a special note for featured articles
featuredNote := util.DelayedElement(func() types.Element {
if isFeatured {
return P(Class("featured-note"))(Content("This is a featured article!"))
}
return util.IfElem(false, nil) // returns an empty group if not featured
})
// Construct the full document
doc := Group(
Doctype(),
HTML()(
Header()(
Meta(Charset("utf-8")),
Title()(Content("Blog Post Title")),
),
Body()(
Div(Class("blog-post"), featuredClass, dynamicAttribute)(
H1()(Content("Blog Post Title")),
P()(Content("This is the introduction of the blog post.")),
featuredNote,
authorBio,
),
),
),
)
var buf bytes.Buffer
doc.Render(&buf)
fmt.Println(buf.String())
}
The template package within GoDOM provides a powerful bridge between GoDOM elements and traditional HTML templating. It offers a seamless way to combine static template constructs with dynamic GoDOM elements, enabling efficient and optimized rendering.
Consider a scenario where you have a GoDOM element for an article, but you want the article's content and attributes to be populated dynamically:
package main
import (
"bytes"
. "github.com/tbe/godom"
"github.com/tbe/godom/helpers"
"github.com/tbe/godom/template"
)
func main() {
// Create a new template
tmpl := template.New("article")
// Define the structure using GoDOM and the template placeholders
articleElement := Div(Class("article"), tmpl.Attribute("data-id"))(
H2()(tmpl.Placeholder("title")),
P()(tmpl.Placeholder("content")),
)
// Parse the GoDOM element into the template
template.Must(tmpl.Parse(articleElement))
// Render the template with dynamic content
var buf bytes.Buffer
tmpl.Execute(&buf, &template.Context{
Placeholders: map[string]types.Element{
"title": helpers.NewStringElement("Dynamic Article Title"),
"content": helpers.NewStringElement("This is the dynamically inserted content for our article."),
},
Attributes: map[string]types.Attribute{
"data-id": Data_("id", "12345"),
},
})
// Output will be:
// <div class="article" data-id="12345">
// <h2>Dynamic Article Title</h2>
// <p>This is the dynamically inserted content for our article.</p>
// </div>
}
Contributions to GoDOM are welcome! Feel free to open issues or submit pull requests.