Go Attribute Templating System
gats is exactly what it sounds like. It is a templating system written in go that uses html/xml attributes for its control structures.
Drop me a line and I'll see what I can do to support your use case. Or just drop me a line to say you like it, that's fine too :-D .
Two reasons, first and foremost it's because all the other templating systems I could find had some funky non-html syntax which means that the templates couldn't render in a browser without processing. Also, because I thought it would be a good starter project for learning Go.
The point has been raised that gats is remarkably similar to TAL (http://wiki.zope.org/ZPT/TALSpecification14), this was originally accidental, but now that I'm aware of TAL I've gone ahead and added the two basic constructs that TAL has that gats didn't: omit-tag and content.
As of now the only fundamental difference between TAL and gats is the complexity of the expressions. gats is very simple, all expressions must be the name of a field in the data that the template will be rendered with. Beyond that, the order of operations is different than TAL: in TAL variables are bound in ancestor first order, in gats it's just the opposite, there are no variables so it binds in descendents first order. The attributes map as follows:
- tal:define == not necessary in gats
- tal:condition == gatsif
- tal:repeat == gatsrepeatover
- tal:content == gatscontent
- tal:replace == gatscontent && gatsomittag
- tal:attributes == gatsattributes
- tal:omit-tag == gatsomittag
gats uses my own fork of goquery, which in turn requires Go's experimental html package and cascadia, so these are all required. It just should be a simple matter of following this guide: http://code.google.com/p/go-wiki/wiki/InstallingExp and then running
go get github.com/dunmatt/gats
and if not, please please please file a bug so I can correct this doc!
- gatsattribute : A string in the format "attributeName;fieldName" which will render to attributeName="{value of the string fieldName}".
- gatsattributes : A map[string]string of attributes to programmatically give the element.
- gatscontent : Replace the children of the attributed element with either the raw string, or the html parse tree.
- gatsif : If the name given as a value is in the data and evaluates to true, show this element, otherwise remove it (and all its kids).
- gatsomittag : Replace the attributed element with its children.
- gatsremove : Remove the attributed element and all of its children from the DOM.
- gatsrepeatover : Populate a copy of the attributed element (and its children) with each item in the named array/slice (in order).
- gatstext : Replace the children of the attributed element with the named string. This is much like gatscontent, except that it html escapes everything, so the string will display to the user instead of potentially becoming part of the DOM.
- gatstransclude : Insert the selected subtree from another page/template into this one. The syntax is gatstransclude="filename;css_selector", which translates to "open filename and copy everything that matches css_selector into this document as children of the attributed element".
- v0.4.0 : Added gatsattribute
- v0.3.0 : Added gatstransclude
- v0.2.0 : Added gatsomittag and gatscontent
- v0.1.0 : Initial release.
Just decorate some html however you want (yay, it even supports nesting!):
<html>
<head>
<title>Yo Dawg</title>
</head>
<body>
Yo dawg, stuff:
<ul gatsif="showul">
<li>things</li>
<li>misc</li>
</ul>
<div gatscontent="cont" gatsattribute="class;year"></div>
<table>
<tr>
<th gatsattributes="Titleattrs">Title</th>
<th>Author</th>
<th>Year</th>
<th>Bibtex</th>
</tr>
<tr gatsrepeatover="Entries">
<td><b gatsomittag="unr" gatstext="title">Doing stuff with items<b></td>
<td gatsrepeatover="Entries">Me</td>
<td gatstext="year">Soon</td>
<td gatstext="bibtex">@InCollection{ scheutz11affectcomm,
author = {Matthias Scheutz},
title = {Evolution of Affect and Communication},
booktitle = {Affective Computing and Interaction: Psychological, Cognitive and Neuroscientific Perspectives},
year = {2011},
editor = {Didem G\:{o}k\c{c}ay and G\:{o}lsen Yildirim},
publisher = {{IGI} Global},
link = {http://hrilab.tufts.edu/publications/scheutz11affectcomm.pdf},
}
</td>
</tr>
<tr gatsremove="true">
<td>This</td>
<td>row</td>
<td>should</td>
<td>disappear</td>
</tr>
</table>
</body>
</html>
Then build a struct with names that match the elements in the template and call RenderTemplateFile. Note that under the covers GATS uses reflection, so any field that gets iterated over (gatsrepeatover and gatsattributes) absolutely must be public.
package main
import (
"exp/html"
"fmt"
"github.com/dunmatt/gats"
"os"
)
type pub struct {
title string
bibtex string
}
type data struct {
showul bool
Entries []pub
Titleattrs map[string]string
year string
//cont string
cont *html.Node
}
func main() {
d := data{
showul: true,
Entries: []pub{
{title: "first", bibtex: "meh"},
{title: "the matrix", bibtex: "look over there ---->"},
{title: "the three amigos", bibtex: "a plethora of laughs"}},
Titleattrs: make(map[string]string),
year: "2013",
//cont: "<hr/>",
cont: &html.Node{
Data: "hr",
Type: html.ElementNode,
},
}
d.Titleattrs["hi"] = "there"
d.Titleattrs["test"] = "data"
e := gats.RenderTemplateFile("exampleGood.html", &d, os.Stdout)
if e != nil {
fmt.Println(e)
}
}
To yield:
<html><head>
<title>Yo Dawg</title>
</head>
<body>
Yo dawg, stuff:
<ul>
<li>things</li>
<li>misc</li>
</ul>
<div class="2013"><hr/></div>
<table>
<tbody><tr>
<th test="data" hi="there">Title</th>
<th>Author</th>
<th>Year</th>
<th>Bibtex</th>
</tr>
<tr>
<td>first</td>
<td>Me</td><td>Me</td><td>Me</td>
<td>2013</td>
<td>meh</td>
</tr><tr>
<td>the matrix</td>
<td>Me</td><td>Me</td><td>Me</td>
<td>2013</td>
<td>look over there ----></td>
</tr><tr>
<td>the three amigos</td>
<td>Me</td><td>Me</td><td>Me</td>
<td>2013</td>
<td>a plethora of laughs</td>
</tr>
</tbody></table>
</body></html>