forked from robfig/soy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
doc.go
158 lines (121 loc) · 4.91 KB
/
doc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
Package soy is an implementation of Google's Closure Templates, which are
data-driven templates for generating HTML.
Compared to html/template, Closure Templates have a few advantages
* Intuitive templating language that supports simple control flow, expressions and arithmetic.
* The same templates may be used from Go, Java, and Javascript.
* Internationalization is built in
and specific to this implementation:
* High performance (> 3x faster than html/template in BenchmarkSimpleTemplate)
* Hot reload for templates
* Parse a directory tree of templates
Refer to the official language spec for details:
https://developers.google.com/closure/templates/
Template example
Here is Hello World
{namespace examples.simple}
/**
* Says hello to the world.*/
// */
/* {template .helloWorld}
Hello world!
{/template}
Here is a more customized version that addresses us by name and can use
greetings other than "Hello".
/**
* Greets a person using "Hello" by default.
* @param name The name of the person.
* @param? greetingWord Optional greeting word to use instead of "Hello".*/
// */
/* {template .helloName}
{if not $greetingWord}
Hello {$name}!
{else}
{$greetingWord} {$name}!
{/if}
{/template}
This last example renders a greeting for each person in a list of names.
It demonstrates a [foreach] loop with an [ifempty] command. It also shows how to
call other templates and insert their output using the [call] command. Note that
the [data="all"] attribute in the call command passes all of the caller's
template data to the callee template.
/**
* Greets a person and optionally a list of other people.
* @param name The name of the person.
* @param additionalNames The additional names to greet. May be an empty list.*/
// */
/* {template .helloNames}
// Greet the person.
{call .helloName data="all" /}<br>
// Greet the additional people.
{foreach $additionalName in $additionalNames}
{call .helloName}
{param name: $additionalName /}
{/call}
{if not isLast($additionalName)}
<br> // break after every line except the last
{/if}
{ifempty}
No additional people to greet.
{/foreach}
{/template}
This example is from
https://developers.google.com/closure/templates/docs/helloworld_java.
Many more examples of soy language features/commands may be seen here:
https://github.com/DarkDNA/soy/blob/master/testdata/features.soy
Usage example
These are the high level steps:
* Create a soy.Bundle and add templates to it (the literal template strings,
files, or directories).
* Compile the bundle of templates, resulting in a "Tofu" instance. It provides
access to all your soy.
* Render a HTML template from Tofu by providing the template name and a data
object.
Typically in a web application you have a directory containing views for all of
your pages. For example:
app/views/
app/views/account/
app/views/feed/
...
This code snippet will parse a file of globals, all soy templates within
app/views, and provide back a Tofu intance that can be used to render any
declared template. Additionally, if "mode == dev", it will watch the soy files
for changes and update your compiled templates in the background (or log compile
errors to soy.Logger). Error checking is omitted.
On startup:
tofu, _ := soy.NewBundle().
WatchFiles(true). // watch soy files, reload on changes
AddGlobalsFile("views/globals.txt"). // parse a file of globals
AddTemplateDir("views"). // load *.soy in all sub-directories
CompileToTofu()
To render a page:
var obj = map[string]interface{}{
"user": user,
"account": account,
}
tofu.Render(resp, "acme.account.overview", obj)
Structs may be used as the data context too, but keep in mind that they are
converted to data maps -- unlike html/template, the context is pure data, and
you can not call methods on it.
var obj = HomepageContext{
User: user,
Account: account,
}
tofu.Render(resp, "acme.account.overview", obj)
See soyhtml.StructOptions for knobs to control how your structs get converted to
data maps.
Project Status
The goal is full compatibility and feature parity with the official Closure
Templates project.
The server-side templating functionality is well tested and nearly complete,
except for two notable areas: contextual autoescaping and
internationalization/bidi support. Contributions welcome.
The Javascript generation is early and lacks many generation options, but
it successfully passes the server-side template test suite. Note that it is
possible to run the official Soy compiler to generate your javascript templates
at build time, even if you use this package for server-side templates.
Please see the TODO file for features that have yet to be implemented.
Please open a Github Issue for any bugs / problems / comments, or if you find a
template that renders differently than with the official compiler.
*/
package soy