Coder Social home page Coder Social logo

gold's Introduction

THIS PACKAGE IS DEPRECATED. PLEASE USE Ace WHICH IS A REFINEMENT OF THIS PACKAGE.

Gold - Template engine for Go

wercker status GoDoc

Gold is a template engine for Go. This simplifies HTML coding in Go web application development. This is influenced by Slim and Jade.

Example

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>

Implementation Example

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)
}

Syntax

doctype

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">

Creating Simple Tags

div
  address
  i
  strong

becomes

<div>
	<address></address>
	<i></i>
	<strong></strong>
</div>

Putting Texts Inside Tags

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>

Adding Attributes to Tags

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>

IDs and Classes

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

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

style
  h1 {color: red;}
  p {color: blue;}

becomes

<style>
	h1 {color: red;}
	p {color: blue;}
</style>

Comments

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>

Includes

Following Gold template includes ./index.gold.

p Hello Gold
include ./index name=Foo

./index.gold

p Included tempalte
input type=text value=%{name}

Inheritance

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>

Optional Blocks

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>

Expressions

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}}

Load templates from binary data generated by go-bindata

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)
	}
}

Parse template strings

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)
}

Templates base directory

You can set a base directory of Gold templates by calling Generetor.SetBaseDir():

  var g = gold.NewGenerator(true).SetBaseDir("/tmp/gold-templates")

Debug writer

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)

Get intermediate HTML source codes

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>

Pretty Print

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>

Martini middleware

Docs

Syntax Highlighting

gold's People

Contributors

yosssi avatar

Stargazers

Fidel H Viegas avatar  avatar B1nj0y avatar Sukhorukov Olexandr avatar machida avatar adakoda avatar Ian Mikhailov avatar 胡傲果 avatar Denis Kreshikhin avatar Zhang Lin avatar shinriyo avatar yukihir0 avatar Hiroki Oiwa avatar  avatar Yannick Heinrich avatar Timothy avatar kaiinui avatar Daniel Blanco avatar Maythee Anegboonlap avatar Kunio Ozawa avatar Gear avatar CMGS avatar Thawatchai Piyawat avatar Jovany Leandro G.C avatar  avatar Dmitry Bondarenko avatar Manu MA avatar S.Y. Lee avatar Patrick D'appollonio avatar Anton Taraev avatar Sudhakar avatar Csaba Szerző avatar Rakhmad Azhari avatar Roberto Dip avatar Oz Tiram avatar Michael Reynolds avatar hunslater avatar  avatar Attila Oláh avatar Roman Minkin avatar Stefano J. Attardi avatar gihnius avatar  avatar Angel Estrada avatar Dee Cheung avatar Ekin Koc avatar Sho Kusano avatar Nikita Semenistyi avatar Rainer Borene avatar Peter Vrba avatar  avatar Pawel Kasperek avatar Jackson Geller avatar Daniel Durante avatar Adrian Cooney avatar Marius avatar Sim Sun avatar Preetam avatar Khalid Lafi avatar Maiah Macariola avatar Gilles Fabio avatar jigsaw avatar Ian Lee avatar Kaung Htet avatar Yung Hwa Kwon avatar xiayf avatar Brian Lai avatar Guo Yu avatar TJ Holowaychuk avatar Pike avatar Denis Bakhtin avatar webwlsong avatar Mark Kubacki avatar Ryo Sato avatar Railsmechanic avatar Yuta Yamada avatar Govinda Fichtner avatar Sergei Silnov avatar Cihangir avatar Brian Ketelsen avatar Kenji Yano avatar Wei Dai avatar Zach Marcantel avatar Damon Zhao avatar Marin avatar Daisuke Murase avatar Sebastian Ruml avatar Ralph Caraveo avatar Quinn Slack avatar Théo Crevon avatar John D'Agostino avatar Owais Lone avatar The Dude avatar Satish Puranam avatar Adam Stokes avatar Florent Viel avatar Omer Katz avatar Fabio avatar Taichi Nakashima avatar Sam Granieri avatar

Watchers

Rakhmad Azhari avatar Kunio Ozawa avatar dryaf avatar James Cloos avatar hunslater avatar  avatar sudix avatar gouchangxing avatar wercker avatar  avatar

gold's Issues

Optional blocks

When I have a layout I'd like to have something like:

block title
title Blah

Which means I could override title in my templates if I wanted to, otherwise it would use title blah.

At the moment this is not possible and you're forced to specify the blocks in the derived templates. I think this would be a good feature and template engines like jinja2 allow you to do this.

additional engines

javascript: is a useful alias for <script type=text/javascript>.

please consider adding additional aliases such as css:.

also please consider adding an API to register preprocessing engines or filters such as:

  • sass:
  • coffee: or coffeescript:
  • markdown:

parse parent & child as string

Is there a way to load parent and child templates from string, without relying on disk? I'd love to explore this for Drone, but we need to load templates from memory

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

Support template base directories

If engine base directory is e.g. /tmp/templates
Then extends layouts/basic

Would mean /tmp/templates/layouts/basic.

Ideally adding this functionality would not break existing code so one could keep using ./template and ../template respectively.

This is first mentioned in #7.

One thing I think we would improve if you could specify a base directory where your engine looks for templates so instead of doing include ../helpers/blah you could do: include helpers/blah and you tell the engine that your template base dir is /path/to/basedir and it only ever lets you look inside there.

Not sure how that could be implemented without a breaking change unless you add it to the generator. What you really want is an area where templates are as its own sandbox and reference stuff that way e.g. extends layout, include helpers/my_helper. You could add it as a property to the generator and if the property is set then use the sandbox, otherwise default behaviour. Or even add a template locator function a user of the library can implement and pass in. Let me know what you think and if you think it makes sense we could close this issue and open a new one.

Template macros

In templates I find myself writing the same template stuff e.g. render input forms with twitter bootstrap classes around it over and over again and was wondering if something like template macros in jinja2 could be implemented. First they could be imported from another file and then reused.

For example I want to make a template macro called renderInput that generates a form input I'd like to create a reusable gold helper in helpers.gold file. See http://jinja.pocoo.org/docs/templates/#macros for something similar.

I'm not sure if this is possible, but thought I'd raise it here.

Meta tags dont parse

Hi, I really am interested in gold and been wanting to keep my previous work compatible (since gold is almost like jade) but I notice that the meta tags dont parse like they should. When it is parsed into html, I get

<meta(http-equiv=content-type content="text/html;" charset="utf-8)"></meta(http-equiv=content-type>

Is there something I am missing or a specific way of doing this?

Enhancement: Ability to decode as well as encode

I am currently working on a project and would love to add this functionality to it. However, I will be rolling out multiple ways in which you can edit (WYSIWYG) which means that I need to store the raw html and be able to convert that HTML back to gold format.

I'd be happy to fork and put some work in to this if it is a direction you want to go, however I do not have experience yet parsing HTML in Go, and I know the encoding/xml package may have issues with it.

Thoughts?

[ANNOUNCEMENT] Gold is deprecated

This is an announcement for all who use Gold.

Hi, I'm an author of Gold. Thanks for using this package.

I decided to re-create this package as a new one because I wanted to refine and simplify the source code, data structure and APIs of this package for its future enhancement.

I just finished creating a new HTML template engine and released it.

Ace - HTML template engine for Go

I would be glad if you could use this new package hereafter.

Best regards,
Keiji

HTML comments

Good day, really like your work, but is there any possibility to write html comments in gold, e.g.:

Thank you!

Debugging errors

I find it sometimes where hard to find out where particular errors are coming from. Line numbers given in the panic trace don't match up with the template. I think that may be because the error is corresponding to the template after it's being translated from Gold into the Go HTML template. Would it be possible somehow to retrieve the compiled output from the trace so I can display it on my website in order to make a nice error page?

Conditional attributes

Hi, thanks for this lovely package.
I was wondering how to add some conditional attributes to a tag.
For example, one can do this in amber:

div
    .hasfriends ? Friends > 0

In gold, the following does not work as it creates another div.

div
    {{if gt .Friends 0}} 
       .hasfriends 
    {{end}}

BTW, is there any rule to indent the {{...}} expression in the template?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.