Unpretentious short and sweet declarative HTML Builder.
Demos can be found on: https://golangui.com
- Valid (X)HTML
- Programmatically generate (X)HTML
- Pure GO code
- No need to transfer HTML files
- No need to embed HTML files
- No need for using template files
- Full reuse of the code
- Fully eliminates the quirks of the standard template package
- Great for email templates too
- Nice looking fluent interface
- Easy to extend and build your own flavor on top
- Dynamic UI with conditions
- Conditional attributes
- Lots of demos and examples
- Works with any CSS library
- Works with any JS library
- Out of the box support for Alpine.js
- Out of the box support for HTMX
- Section containing div container (Bootstrap) with a message "Hello world"
import "github.com/gouniverse/hb"
// 1. Create a div container with "Hello world" message
div := hb.Div().Class("container").Text("Hello world")
// 2. Create a section with padding of 40px containing the container
section := hb.Section().Style("padding:40px;").Child(div)
// 3. Render to HTML to display
html := section.ToHTML()
!!! For more examples look below in the README
go get -u github.com/gouniverse/hb
- A() - shortcut for <a> tag
- Abbr() - shortcut for <abbr> tag
- Address() - shortcut for <address> tag
- Article() - shortcut for <article> tag
- Aside() - shortcut for <aside> tag
- BR() - shortcut for <br> tag
- Button() - shortcut for <button> tag
- Caption() - shortcut for <caption> tag
- Code() - shortcut for <code> tag
- Div() - shortcut for <div> tag
- Form() - shortcut for <form> tag
- I() - shortcut for <i> tag
- Header() - shortcut for <header> tag
- Heading1() - shortcut for <h1> tag
- Heading2() - shortcut for <h2> tag
- Heading3() - shortcut for <h3> tag
- Heading4() - shortcut for <h4> tag
- Heading5() - shortcut for <h5> tag
- Heading6() - shortcut for <h6> tag
- Hyperlink() - shortcut for <a> tag
- HR() - shortcut for <hr> tag
- HTML(html string) - creates empty tag with the HTML content
- Image() - shortcut for <img> tag
- Input() - shortcut for <input> tag
- LI() - shortcut for <li> tag
- Label() - shortcut for <label> tag
- Nav() - shortcut for <nav> tag
- Navbar() - shortcut for <navbar> tag
- OL() - shortcut for <ol> tag
- Option() - shortcut for <option> tag
- Paragraph() - shortcut for <p> tag
- PRE() - shortcut for <pre> tag
- Script() - shortcut for <script> tag
- ScriptURL() - shortcut for <script src="{SRC}"> tag
- Select() - shortcut for <select> tag
- Span() - shortcut for <span> tag
- Style() - shortcut for <style> tag
- StyleURL() - shortcut for <link> tag
- Section() - shortcut for <section> tag
- Sub() - shortcut for <sub> tag
- Sup() - shortcut for <sup> tag
- NewTag(tagName string) - for custom tags
- Table() - shortcut for <table> tag
- TBody() - shortcut for <tbody> tag
- TD() - shortcut for <td> tag
- Template() - shortcut for <template> tag
- Text(text string) - creates empty tag with the escaped text content
- TextArea() - shortcut for <textarea> tag
- TH() - shortcut for <th> tag
- Thead() - shortcut for <thead> tag
- TR() - shortcut for <tr> tag
- UL() - shortcut for <ul> tag
- Webpage() - full HTML page withe head, body, meta, styles and scripts
- Wrap() - convenience method to taglessly (without a root wrapping element) group elements together
Examples can be found on: https://golangui.com
- Action(action string) - shortcut to add an "action" attribute
- Attr(key, value string) - shortcut for SetAttribute
- AttrIf(condition bool, key, value string) - conditional setting of attribute
- AttrIfF(condition bool, key string, valueFunc func() string) - conditional setting of attribute using function
- AttrIfElse(condition bool, key, valueIf string, valueElse string) - conditional setting of attribute
- Attrs(map[string]string) - shortcut for setting multiple attributes
- AttrsIf(condition bool, attrs map[string]string) - conditional setting of attributes
- AttrsIfF(condition bool, attrsFunc func() map[string]string) - conditional setting of attributes using function
- AttrsIfElse(condition, attrsIf map[string]string, attrsElse map[string]string) - conditional setting of attributes
- AddChild(tag Tag) - adds a child element
- AddChildren(tag []Tag) - adds an array of child elements
- AddClass(className string) - adds a class name to the "class" attribute
- AddHTML(html string) - adds HTML content to the element
- AddStyle(style string) - adds a style to the "style" attribute
- AddText(text string) - adds escaped text content to the element
- Child(tag Tag) - shortcut for AddChild
- ChildIf(condition bool, tag Tag) - conditional adding of a child
- ChildIfF(condition bool, childFunc func() *Tag) - conditional adding of a child using function
- ChildIfElse(condition bool, childIf Tag, childElse Tag) - conditional adding of a child
- Children(children []Tag) - shortcut for AddChildren
- ChildrenIf(condition bool, children []Tag) - conditional adding of children
- ChildrenIfF(condition bool, childrenFunc func() []*Tag) - conditional adding of children using function
- ChildrenIfElse(condition bool, childrenIf []Tag, childrenElse []Tag) - conditional adding of a children
- ChildrenMap(items []any, callback func(item any, index int) *Tag) []*Tag - map a slice to a slice of tags and adds as children
- Class(className string) - shortcut for AddClass
- ClassIf(condition bool, className string) - conditional adding of a class
- ClassIfElse(condition bool, classNameIf string, classNameElse string) - conditional adding of a class
- Data(name string, value string) - shortcut to add a "data-" attribute
- DataIf(condition bool, key, value string) - conditional setting of attribute
- DataIfElse(condition bool, key, valueIf string, valueElse string) - conditional setting of attribute
- Enctype(enctype string) - shortcut to add an "enctype" attribute
- HasClass(className string) - checks if the class is available
- Href(href string) - shortcut to add an "href" attribute
- HTML(html string) - shortcut for AddHTML
- ID(className string) - shortcut to add an "id" attribute
- GetAttribute(key string) string
- Method(method string) - shortcut to add a "method" attribute
- Name(name string) - shortcut to add a "name" attribute
- Placeholder(placeholder string) - shortcut to add a "placeholder" attribute
- OnBlur(js string) - shortcut to add an "onblur" attribute
- OnChange(js string) - shortcut to add an "onchange" attribute
- OnClick(js string) - shortcut to add an "onclick" attribute
- OnDblClick(js string) - shortcut to add an "ondblclick" attribute
- OnFocus(js string) - shortcut to add an "onfocus" attribute
- OnKeyDown(js string) - shortcut to add an "onkeydown" attribute
- OnKeyPress(js string) - shortcut to add an "onkeypress" attribute
- OnKeyUp(js string) - shortcut to add an "onkeyup" attribute
- OnMouseDown(js string) - shortcut to add an "onmousedown" attribute
- OnMouseOut(js string) - shortcut to add an "onmouseout" attribute
- OnMouseUp(js string) - shortcut to add an "onmouseup" attribute
- OnSubmit(js string) - shortcut to add an "onsubmit" attribute
- Role(role string) - shortcut to add a "role" attribute
- SetAttribute(key, value string) - sets an attribute (i.e. id, class, etc)
- Src(src string) - shortcut to add a "src" attribute
- Style(style string) - shortcut to add a "style" attribute
- StyleIf(condition bool, style string) - conditional adding of a style
- StyleIfElse(condition bool, styleIf string, styleElse string) - conditional adding of a style
- Target(target string) - shortcut to add a "target" attribute
- TargetIf(condition bool, target string) - conditional adding of a "target" attribute
- Text(html string) - shortcut for AddText
- TextIf(condition bool, text string) - adds escaped text if a condition is met
- TextIfElse(condition bool, textIf string, textElse string) - adds escaped text if a condition is met
- Title(title string) - shortcut for setting the "title" attribute
- TitleIf(condition bool, title string) - sets the title if a condition is met
- ToHTML() string - outputs HTML code
- Type(target string) - shortcut to add a "type" attribute
- TypeIf(condition bool, target string) - conditional setting of "type" attribute
- Value(value string) - shortcut to add a "value" attribute
- ValueIf(condition bool, value string) - conditional setting of "value" attribute
Examples can be found on: https://golangui.com
- Map[T any](items []T, callback func(item T, index int) *Tag) []*Tag - map a slice of anything to a slice of tags
- If(condition bool, trueTag *Tag) *Tag
- IfF(condition bool, trueFunc func() *Tag) *Tag
- IfElse(condition bool, trueTag *Tag, falseTag *Tag) *Tag
- IfFElseF(condition bool, trueFunc func() *Tag, falseFunc func() *Tag) *Tag
- Ternary(condition bool, trueTag *Tag, falseTag *Tag) *Tag
- TernaryF(condition bool, trueFunc func() *Tag, falseFunc func() *Tag) *Tag
HTMX (https://htmx.org/reference/) is a great match for Golang, therefore here is a shortcut for working with HTMX.
- Hx(name string, value string) - shortcut for setting an HTMX attribute
- HxConfirm(value string)
- HxDelete(value string)
- HxGet(value string)
- HxInclude(value string)
- HxIndicator(value string)
- HxOn(name string, value string)
- HxPatch(value string)
- HxPost(value string)
- HxPut(value string)
- HxSelect(value string)
- HxSelectOob(value string)
- HxSync(value string)
- HxSwap(value string)
- HxSwapOob(value string)
- HxTarget(value string)
- HxTrigger(value string)
- HxVals(value string)
- HxVars(value string)
Examples can be found on: https://golangui.com
Alpine.js (https://alpinejs.dev/) is a great match for Golang, therefore here is a shortcut for working with HTMX.
- X(name string, value string) - shortcut for setting an AlpineJS attribute
- XBind(name string, value string)
- XOn(name string, value string)
Examples can be found on: https://golangui.com
- AddChild(child *Tag)
- SetFavicon(favicon string)
- SetTitle(title string)
- AddScripts(scripts []string)
- AddScript(script string)
- AddScriptURLs(scriptURLs []string)
- AddScriptURL(scriptURL string)
- AddStyle(style string)
- AddStyles(styles []string)
- AddStyleURL(styleURL string)
- AddStyleURLs(styleURLs []string)
- NewBorderLayout() - shortcut to quickly create a border layout with top, bottom, left, right and center slots (see example below how to use it)
- AddTop(tag *Tag, alignHorizontal string, alignVertical string)
- AddBottom(tag *Tag, alignHorizontal string, alignVertical string)
- AddLeft(tag *Tag, alignHorizontal string, alignVertical string)
- AddRight(tag *Tag, alignHorizontal string, alignVertical string)
- AddCenter(tag *Tag, alignHorizontal string, alignVertical string)
Usage example:
bl := NewBorderLayout()
bl.AddTop(NewSpan().Text("TOP"), BORDER_LAYOUT_ALIGN_CENTER, BORDER_LAYOUT_ALIGN_MIDDLE)
bl.AddCenter(NewSpan().Text("CENTER"), BORDER_LAYOUT_ALIGN_CENTER, BORDER_LAYOUT_ALIGN_MIDDLE)
bl.AddBottom(NewSpan().Text("BOTTOM"), BORDER_LAYOUT_ALIGN_CENTER, BORDER_LAYOUT_ALIGN_MIDDLE)
bl.AddLeft(NewSpan().Text("LEFT"), BORDER_LAYOUT_ALIGN_CENTER, BORDER_LAYOUT_ALIGN_MIDDLE)
bl.AddRight(NewSpan().Text("RIGHT"), BORDER_LAYOUT_ALIGN_CENTER, BORDER_LAYOUT_ALIGN_MIDDLE)
blHtml := bl.ToHTML()
- NewSwal - shortcut to quickly add Sweetalert 2 dialogs (note requires adding the Sweetalert JS library). See more at: https://sweetalert2.com/download
Usage example in a form:
form.
ChildIf(data.formErrorMessage != "", hb.Swal(swal.SwalOptions{
Icon: "error",
Title: "Oops...",
Text: data.formErrorMessage,
ShowCancelButton: false,
ConfirmButtonText: "OK",
ConfirmCallback: "window.location.href = window.location.href",
})).
ChildIf(data.formSuccessMessage != "", hb.Swal(swal.SwalOptions{
Icon: "success",
Title: "Saved",
Text: data.formSuccessMessage,
ShowCancelButton: false,
ConfirmButtonText: "OK",
ConfirmCallback: "window.location.href = window.location.href",
}))
tag := &Tag{
TagName: "custom-element",
}
tag.toHTML()
For safeguarding HTML, always use the .Text(text) method of the tags, it will automatically escape any HTML tags in the output.
Using the .HTML(html) method of the tags, will output the raw HTML, and leaves you vulnerable to XSS attacks.
You can escape the HTML yourself by using the EscapeString method from the standard HTML library Link with example: https://golang.org/pkg/html/#EscapeString
- Bootstrap login form
// Elements for the form
header := hb.Heading3().text("Please sign in").Style("margin:0px;")
emailLabel := hb.Label().Text("E-mail Address")
emailInput := hb.Input().Class("form-control").Name("email").Placeholder("Enter e-mail address")
emailFormGroup := hb.Div().Class("form-group").Child(emailLabel).Child(emailInput)
passwordLabel := hb.Label().Child(hb.Text("Password"))
passwordInput := hb.Input().Class("form-control").Name("password").Type("password").Placeholder("Enter password")
passwordFormGroup := hb.Div().Class("form-group").Child(passwordLabel).Child(passwordInput)
buttonLogin := hb.Button().Class("btn btn-lg btn-success btn-block").Text("Login")
buttonRegister := hb.Hyperlink().Class("btn btn-lg btn-info float-left").Text("Register").Href("auth/register")
buttonForgotPassword := hb.Hyperlink().Class("btn btn-lg btn-warning float-right").Text("Forgot password?").Href("auth/password-restore")
// Add elements in a card
cardHeader := hb.Div().
Class("card-header").
Child(header)
cardBody := hb.Div().
Class("card-body").
Children([]*hb.Tag{
emailFormGroup,
passwordFormGroup,
buttonLogin,
})
cardFooter := hb.Div().
Class("card-footer").
Children([]*hb.Tag{
buttonRegister,
buttonForgotPassword,
})
card := hb.Div().
Class("card card-default").
Style("margin:0 auto;max-width: 360px;").
Children([]*hb.Tag{
cardHeader,
cardBody,
cardFooter
})
// Convert to HTML to display
html := card.ToHTML()
Result:
- Webpage with title, favicon, Font Awesome icons 4.7.0, jQuery 3.2.1, and Bootstrap 4.5
// 1. Webpage Title
title := "Title"
// 2. Webpage Favicon
favicon := "data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAABNTU0AVKH/AOPj4wDExMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIiAREQEREAIiIBERAREQAiIgIiICIiACIiAiIgIiIAMzMDMzAzMwAzMwMzMDMzACIiAiIgIiIAIiICIiAiIgAzMwMzMDMzADMzAzMwMzMAIiICIiAiIgAiIgIiICIiAAAAAAAAAAAAIiICIiAiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
// 3. Webpage
webpage := NewWebpage().
SetTitle(title).
SetFavicon(favicon).
AddStyleURLs([]string{
"https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css",
"https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css",
}).
AddScriptURLs([]string{
"https://code.jquery.com/jquery-3.2.1.min.js",
"https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js",
}).
AddStyle(`html,body{height:100%;font-family: Ubuntu, sans-serif;}`).AddChild(NewDiv().Text("Hello"))
- Wrap webpage in a function to be reused as a master template
// Webpage returns the webpage template for the website
func Webpage(title, content string) *hb.Webpage {
faviconImgCms := `data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAmzKzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEQEAAQERAAEAAQABAAEAAQABAQEBEQABAAEREQEAAAERARARAREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAAi6MAALu7AAC6owAAuC8AAIkjAAD//wAA//8AAP//AAD//wAA`
webpage := hb.Webpage()
webpage.SetTitle(title)
webpage.SetFavicon(faviconImgCms)
webpage.AddStyleURLs([]string{
"https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css",
})
webpage.AddScriptURLs([]string{
"https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js",
"http://code.jquery.com/jquery-3.5.1.min.js",
"https://unpkg.com/vue@next",
"https://cdn.jsdelivr.net/npm/sweetalert2@9",
})
webpage.AddScripts([]string{})
webpage.AddStyle(`html,body{height:100%;font-family: Ubuntu, sans-serif;}`)
webpage.AddStyle(`body {
font-family: "Nunito", sans-serif;
font-size: 0.9rem;
font-weight: 400;
line-height: 1.6;
color: #212529;
text-align: left;
background-color: #f8fafc;
}`)
webpage.AddChild(hb.HTML(content))
return webpage
}
// Generate HTML
html := webpage("Home", "Hello world").ToHTML()
Here is an HTMX example which submits the content of all the inputs in a div to the server (no need to be in a form) and then replaces the content of the webpage with the result.
input := NewButton().
Text("Submit")
Hx("post", "http://test.com").
Hx("include", "#DivID").
Hx("target", "#PageID").
Hx("swap", "outerHTML")
webpage.Meta(hb.Meta().Attr("http-equiv", "refresh").Attr("content", "2; url = https://www.yahoo.com"))
- https://github.com/goradd/html5tag - option to have string or stream
2024.10.05 - Added HxIndicator
2024.10.01 - Added additional shortcuts for more concise declaration
2023.12.17 - Added Map, Ternary, Text
2023.12.10 - Added Swal method for quickly adding Sweetalert
2023.09.16 - Added special case for empty "value" attribute
2023.07.26 - Added NewCaption function and Alpine.js, HTMX functions
2023.07.02 - Added NewHeader function
2023.06.09 - Added functional conditions AttrIfF, AttrsIfF, ChildIfF, ChildrenIfF
2023.05.08 - Added Alt attribute shortcut
2023.05.01 - Added NewWrap function
2023.04.27 - Added OnDblClick, OnInput, OnKeyPress, OnMouseDown, OnMouseUp, and conditionals for data
2023.04.25 - Added Placeholder, and conditionals for attributes
2023.04.15 - Added AddStyle, Src, and conditionals for style
2023.04.14 - Added Type attribute shortcut, conditionals for children and class names
2023.03.26 - Added Hx attribute shortcut for working with HTMX
2023.03.26 - Added OnBlur, OnChange, OnFocus, OnKeyDown, OnKeyUp, attribute shortcuts
2023.03.26 - Added Enctype, Href, Method, Name, target, Value attribute shortcuts
2023.01.22 - Added shortcut for <footer> tag
2023.01.14 - Flow pattern applied to BorderLayout methods
2022.09.07 - Added Child and Children shortcuts
2022.08.29 - Added default favicon to Webpage to fix 404 if missing
2022.01.07 - Added Attrs shortcut for setting multiple attributes
2021.07.30 - Added shortcut for <hr> tag
2021.03.20 - Renamed package name to hb to not conflict/confuse with the standard html package
2021.03.18 - Added shortcuts for <template> tag
2021.02.26 - Added shortcuts for <sub>, <sup> tags
2021.01.03 - Added example for webpage layout, and screenshot
2020.12.28 - Added shortcuts for <code>, <pre> tags, shortcuts sorted alphabetically
2020.12.27 - Added shortcuts for <table>, <thead>, <tbody>, <tr>, <th>, <td> tags
2020.12.26 - Fix for attribute escapes, added tests
2020.09.16 - Added shortcuts for <nav>, <navbar>, <ol>, <ul>, <li> tags
2020.06.16 - Initial commit
-
Stevelacy Daz (https://github.com/stevelacy/daz) | Last update: 19 Apr 2023
-
Extemplate (https://github.com/dannyvankooten/extemplate) | Last update: 15 Jun 2021
-
ThePlant HTMLGO (https://github.com/theplant/htmlgo) | Last update: 18 Sep 2021
-
Julvo HTMLGO (https://github.com/julvo/htmlgo) | Last update: 5 May 2020
-
Go Components (https://github.com/maragudk/gomponents)
-
Uberswe HTML (https://github.com/uberswe/html) | Last update: 24 Feb 2021
-
Elem Go (https://github.com/chasefleming/elem-go)
-
Forms from Structs (https://github.com/joncalhoun/form) Still writ
-
HTMLX (https://github.com/mdigger/htmlx) | Last update: 20 Jun 2021 An extension to the standard html package. Not lots of documentation
-
HTML as functions (https://github.com/jpincas/htmlfunc) | Last update: 23 Jan 2023 Interesting library, following Elm. Not lots of documentation
-
Templ (https://github.com/a-h/templ) | 30 Sep 2023 Building templates with JSX like syntax. Requires installing 3-rd party binaries, and additional compilation step before being usable.