THIS PACKAGE IS DEPRECATED. PLEASE USE Ace WHICH IS A REFINEMENT OF THIS PACKAGE.
Gold is a template engine for Go. This simplifies HTML coding in Go web application development. This is influenced by Slim and Jade.
doctype html
html lang=en
head
title {{.Title}}
body
h1 Gold - Template engine for Go
#container.wrapper
{{if true}}
p You can use an expression of Go text/template package in a Gold template.
{{end}}
p.
Gold is a template engine for Go.
This simplifies HTML coding in Go web application development.
javascript:
var msg = 'Welcome to Gold!';
alert(msg);
becomes
<!DOCTYPE html>
<html lang="en">
<head>
<title>Gold</title>
</head>
<body>
<h1>Gold - Template engine for Go</h1>
<div id="container" class="wrapper">
<p>You can use an expression of Go html/template package in a Gold template.</p>
<p>
Gold is a template engine for Go.
This simplifies HTML coding in Go web application development.
</p>
</div>
<script type="text/javascript">
msg = 'Welcome to Gold!';
alert(msg);
</script>
</body>
</html>
package main
import (
"github.com/yosssi/gold"
"net/http"
)
// Create a generator which parses a Gold templates and
// returns a html/template package's template.
// You can have a generator cache templates by passing
// true to NewGenerator function.
var g = gold.NewGenerator(false)
func handler(w http.ResponseWriter, r *http.Request) {
// ParseFile parses a Gold template and
// returns an html/template package's template.
tpl, err := g.ParseFile("./top.gold")
if err != nil {
panic(err)
}
data := map[string]interface{}{"Title": "Gold"}
// Call Execute method of the html/template
// package's template.
err = tpl.Execute(w, data)
if err != nil {
panic(err)
}
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
doctype html
becomes
<!DOCTYPE html>
Following doctypes are available:
doctype html
<!DOCTYPE html>
doctype xml
<?xml version="1.0" encoding="utf-8" ?>
doctype transitional
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
doctype strict
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
doctype frameset
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
doctype 1.1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
doctype basic
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
doctype mobile
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
You can also use your own literal custom doctype:
doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN">
div
address
i
strong
becomes
<div>
<address></address>
<i></i>
<strong></strong>
</div>
p Welcome to Gold
p
| You can insert single text.
p.
You can insert
multiple texts.
becomes
<p>Welcome to Gold</p>
<p>You can insert single text.</p>
<p>
You can insert
multiple texts.
</p>
a href=https://github.com/yosssi/gold target=_blank Gold GitHub Page
button data-action=btnaction style="font-weight: bold; font-size: 1rem;"
| This is a button
becomes
<a href="https://github.com/yosssi/gold" target="_blank">Gold GitHub Page</a>
<button data-action="btnaction" style="font-weight: bold; font-size: 1rem;">This is a button</button>
h1#title.main-title Welcome to Gold
#container
.wrapper
| Hello Gold
becomes
<h1 id="title" class="main-title">Welcome to Gold</h1>
<div id="container">
<div class="wrapper">Hello Gold</div>
</div>
javascript:
alert(1);
alert(2);
script type=text/javascript
alert(3);
alert(4);
becomes
<script type="text/javascript">
alert(1);
alert(2);
</script>
<script type="text/javascript">
alert(3);
alert(4);
</script>
style
h1 {color: red;}
p {color: blue;}
becomes
<style>
h1 {color: red;}
p {color: blue;}
</style>
div
p Hello Gold 1
// p Hello Gold 2
//
div
p Hello Gold 3
p Hello Gold 4
div
p Hello Gold 5
becomes
<div>
<p>Hello Gold 1</p>
</div>
<div>
<p>Hello Gold 5</p>
</div>
Following Gold template includes ./index.gold
.
p Hello Gold
include ./index name=Foo
./index.gold
p Included tempalte
input type=text value=%{name}
Gold tamplates can inherit other Gold templates as below:
parent.gold
doctype html
html
head
title Gold
body
block content
footer
block footer
child.gold
extends ./parent
block content
#container
| Hello Gold
block footer
.footer
| Copyright XXX
the above Gold templates generate the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>Gold</title>
</head>
<body>
<div id="container">Hello Gold</div>
<footer>
<div class="footer">Copyright XXX</div>
</footer>
</body>
</html>
You can set a default value to the blocks as below:
parent.gold
doctype html
html
head
block title
title Default Title
child1.gold
extends ./parent
block title
title Child1 Title
child2.gold
extends ./parent
child1.gold template generates the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>Child1 Title</title>
</head>
</html>
child2.gold template generates the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>Default Title</title>
</head>
</html>
You can embed text/template package's expressions into Gold templates because Gold template wraps this package's Template. text/template package's documentation describes its expressions in detail.
div
{{if .IsProduction}}
p This is a production code.
{{end}}
div
{{range .Rows}}
p {{.}}
{{end}}
You can use an equal mark(=) to output an expression value:
div
= .Title
the above code is equivalent to the blow code:
div
{{.Title}}
You can load templates from binary data generated by go-bindata by setting the Asset
function (which is generated by go-bindata) to the generator
.
package main
import (
"os"
"github.com/yosssi/gold"
)
// Set the `Asset` function generated by go-bindata to the `generator`.
var g = gold.NewGenerator(true).SetAsset(Asset)
func main() {
tpl, err := g.ParseFile("templates/top.gold")
if err != nil {
panic(err)
}
data := map[string]interface{}{"Title": "Gold"}
err = tpl.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}
You can parse template strings and load templates from memory by using the generator's ParseString
method.
package main
import (
"net/http"
"github.com/yosssi/gold"
)
// Create a generator which parses a Gold templates and
// returns a html/template package's template.
// You can have a generator cache templates by passing
// true to NewGenerator function.
var g = gold.NewGenerator(true)
func handler(w http.ResponseWriter, r *http.Request) {
// template strings
parent := `
doctype html
html
head
title Gold
body
block content
footer
block footer
`
child := `
extends parent
block content
#container
| Hello Gold
block footer
.footer
| Copyright XXX
`
stringTemplates := map[string]string{"parent": parent, "child": child}
// ParseString parses a Gold template strings and
// returns an html/template package's template.
tpl, err := g.ParseString(stringTemplates, "child")
if err != nil {
panic(err)
}
data := map[string]interface{}{"Title": "Gold"}
// Call Execute method of the html/template
// package's template.
err = tpl.Execute(w, data)
if err != nil {
panic(err)
}
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
You can set a base directory of Gold templates by calling Generetor.SetBaseDir()
:
var g = gold.NewGenerator(true).SetBaseDir("/tmp/gold-templates")
You can set a debug writer to the Gold generator so that you can inspect the intermediate HTML source codes generated by Gold:
var g = gold.NewGenerator(false).SetPrettyPrint(true).SetDebugWriter(os.Stdout)
Generator.ParseFileWithHTML and Generator.ParseStringWithHTML return intermediate HTML source codes which Gold generates. You can write these HTML source codes for debugging.
Example:
package main
import (
"fmt"
"html/template"
"net/http"
"github.com/yosssi/gohtml"
"github.com/yosssi/gold"
)
var g = gold.NewGenerator(false).SetPrettyPrint(true)
func handler(w http.ResponseWriter, r *http.Request) {
parent := `
doctype html
html
head
title {{.Title}}
body
block content
footer
block footer
`
child := `
extends parent
block content
#container
{{.Msg.NotExistProperty}}
block footer
.footer
| Copyright XXX
`
stringTemplates := map[string]string{"parent": parent, "child": child}
tpl, html, err := g.ParseStringWithHTML(stringTemplates, "child")
if err != nil {
panic(err)
}
data := map[string]interface{}{"Title": "Gold", "Msg": "Hello!"}
err = tpl.Execute(w, data)
if err != nil {
fmt.Fprintf(w, "<pre>Error:\n%s\nHTML:\n%s</pre>", err.Error(), gohtml.AddLineNo(template.HTMLEscapeString(html)))
}
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
Output:
Error:
template: child:10:12: executing "child" at <.Msg.NotExistPropert...>: can't evaluate field NotExistProperty in type interface {}
HTML:
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>
5 {{.Title}}
6 </title>
7 </head>
8 <body>
9 <div id="container">
10 {{.Msg.NotExistProperty}}
11 </div>
12 <footer>
13 <div class="footer">
14 Copyright XXX
15 </div>
16 </footer>
17 </body>
18 </html>
You can format the result HTML source codes by using GoHTML package. gohtml.Writer formats HTML source codes and writes them.
Example:
package main
import (
"os"
"github.com/yosssi/gohtml"
"github.com/yosssi/gold"
)
var g = gold.NewGenerator(false)
func main() {
// template strings
parent := `
doctype html
html
head
title Gold
body
block content
footer
block footer
`
child := `
extends parent
block content
#container
= .Msg
block footer
.footer
| Copyright XXX
`
stringTemplates := map[string]string{"parent": parent, "child": child}
tpl, err := g.ParseString(stringTemplates, "child")
if err != nil {
panic(err)
}
data := map[string]interface{}{"Msg": "Hello, Gold!"}
err = tpl.Execute(gohtml.NewWriter(os.Stdout), data)
if err != nil {
panic(err)
}
}
Output:
<!DOCTYPE html>
<html>
<head>
<title>
Gold
</title>
</head>
<body>
<div id="container">
Hello, Gold!
</div>
<footer>
<div class="footer">
Copyright XXX
</div>
</footer>
</body>
</html>