gobyexample/public/text-templates

259 lines
17 KiB
Plaintext
Generated

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Go by Example: Text Templates</title>
<link rel=stylesheet href="site.css">
</head>
<script>
onkeydown = (e) => {
if (e.key == "ArrowLeft") {
window.location.href = 'string-formatting';
}
if (e.key == "ArrowRight") {
window.location.href = 'regular-expressions';
}
}
</script>
<body>
<div class="example" id="text-templates">
<h2><a href="./">Go by Example</a>: Text Templates</h2>
<table>
<tr>
<td class="docs">
<p>Go offers built-in support for creating dynamic content or showing customized
output to the user with the <code>text/template</code> package. A sibling package
named <code>html/template</code> provides the same API but has additional security
features and should be used for generating HTML.</p>
</td>
<td class="code empty leading">
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<a href="https://go.dev/play/p/pDwkw1iMACF"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;os&#34;</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;text/template&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>We can create a new template and parse its body from
a string.
Templates are a mix of static text and &ldquo;actions&rdquo; enclosed in
<code>{{...}}</code> that are used to dynamically insert content.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t1</span> <span class="o">:=</span> <span class="nx">template</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">&#34;t1&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">t1</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">t1</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="s">&#34;Value is {{.}}\n&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>Alternatively, we can use the <code>template.Must</code> function to
panic in case <code>Parse</code> returns an error. This is especially
useful for templates initialized in the global scope.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t1</span> <span class="p">=</span> <span class="nx">template</span><span class="p">.</span><span class="nf">Must</span><span class="p">(</span><span class="nx">t1</span><span class="p">.</span><span class="nf">Parse</span><span class="p">(</span><span class="s">&#34;Value: {{.}}\n&#34;</span><span class="p">))</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>By &ldquo;executing&rdquo; the template we generate its text with
specific values for its actions. The <code>{{.}}</code> action is
replaced by the value passed as a parameter to <code>Execute</code>.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t1</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="s">&#34;some text&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">t1</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">t1</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;Go&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;Rust&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;C++&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;C#&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>Helper function we&rsquo;ll use below.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">Create</span> <span class="o">:=</span> <span class="kd">func</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">t</span> <span class="kt">string</span><span class="p">)</span> <span class="o">*</span><span class="nx">template</span><span class="p">.</span><span class="nx">Template</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">template</span><span class="p">.</span><span class="nf">Must</span><span class="p">(</span><span class="nx">template</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">name</span><span class="p">).</span><span class="nf">Parse</span><span class="p">(</span><span class="nx">t</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>If the data is a struct we can use the <code>{{.FieldName}}</code> action to access
its fields. The fields should be exported to be accessible when a
template is executing.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t2</span> <span class="o">:=</span> <span class="nf">Create</span><span class="p">(</span><span class="s">&#34;t2&#34;</span><span class="p">,</span> <span class="s">&#34;Name: {{.Name}}\n&#34;</span><span class="p">)</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t2</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Name</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl"> <span class="p">}{</span><span class="s">&#34;Jane Doe&#34;</span><span class="p">})</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>The same applies to maps; with maps there is no restriction on the
case of key names.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t2</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;Name&#34;</span><span class="p">:</span> <span class="s">&#34;Mickey Mouse&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>if/else provide conditional execution for templates. A value is considered
false if it&rsquo;s the default value of a type, such as 0, an empty string,
nil pointer, etc.
This sample demonstrates another
feature of templates: using <code>-</code> in actions to trim whitespace.</p>
</td>
<td class="code leading">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t3</span> <span class="o">:=</span> <span class="nf">Create</span><span class="p">(</span><span class="s">&#34;t3&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;{{if . -}} yes {{else -}} no {{end}}\n&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">t3</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="s">&#34;not empty&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">t3</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="s">&#34;&#34;</span><span class="p">)</span></span></span></code></pre>
</td>
</tr>
<tr>
<td class="docs">
<p>range blocks let us loop through slices, arrays, maps or channels. Inside
the range block <code>{{.}}</code> is set to the current item of the iteration.</p>
</td>
<td class="code">
<pre class="chroma"><code><span class="line"><span class="cl"> <span class="nx">t4</span> <span class="o">:=</span> <span class="nf">Create</span><span class="p">(</span><span class="s">&#34;t4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;Range: {{range .}}{{.}} {{end}}\n&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">t4</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;Go&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;Rust&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;C++&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;C#&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</td>
</tr>
</table>
<table>
<tr>
<td class="docs">
</td>
<td class="code">
<pre class="chroma"><code><span class="line"><span class="cl"><span class="gp">$</span> go run templates.go
</span></span><span class="line"><span class="cl"><span class="go">Value: some text
</span></span></span><span class="line"><span class="cl"><span class="go">Value: 5
</span></span></span><span class="line"><span class="cl"><span class="go">Value: [Go Rust C++ C#]
</span></span></span><span class="line"><span class="cl"><span class="go">Name: Jane Doe
</span></span></span><span class="line"><span class="cl"><span class="go">Name: Mickey Mouse
</span></span></span><span class="line"><span class="cl"><span class="go">yes
</span></span></span><span class="line"><span class="cl"><span class="go">no
</span></span></span><span class="line"><span class="cl"><span class="go">Range: Go Rust C++ C# </span></span></span></code></pre>
</td>
</tr>
</table>
<p class="next">
Next example: <a href="regular-expressions">Regular Expressions</a>.
</p>
<p class="footer">
by <a href="https://markmcgranaghan.com">Mark McGranaghan</a> and <a href="https://eli.thegreenplace.net">Eli Bendersky</a> | <a href="https://github.com/mmcgrana/gobyexample">source</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>
</p>
</div>
<script>
var codeLines = [];
codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A \"os\"\u000A \"text/template\"\u000A)\u000A');codeLines.push('func main() {\u000A');codeLines.push(' t1 :\u003D template.New(\"t1\")\u000A t1, err :\u003D t1.Parse(\"Value is {{.}}\\n\")\u000A if err !\u003D nil {\u000A panic(err)\u000A }\u000A');codeLines.push(' t1 \u003D template.Must(t1.Parse(\"Value: {{.}}\\n\"))\u000A');codeLines.push(' t1.Execute(os.Stdout, \"some text\")\u000A t1.Execute(os.Stdout, 5)\u000A t1.Execute(os.Stdout, []string{\u000A \"Go\",\u000A \"Rust\",\u000A \"C++\",\u000A \"C#\",\u000A })\u000A');codeLines.push(' Create :\u003D func(name, t string) *template.Template {\u000A return template.Must(template.New(name).Parse(t))\u000A }\u000A');codeLines.push(' t2 :\u003D Create(\"t2\", \"Name: {{.Name}}\\n\")\u000A');codeLines.push(' t2.Execute(os.Stdout, struct {\u000A Name string\u000A }{\"Jane Doe\"})\u000A');codeLines.push(' t2.Execute(os.Stdout, map[string]string{\u000A \"Name\": \"Mickey Mouse\",\u000A })\u000A');codeLines.push(' t3 :\u003D Create(\"t3\",\u000A \"{{if . -}} yes {{else -}} no {{end}}\\n\")\u000A t3.Execute(os.Stdout, \"not empty\")\u000A t3.Execute(os.Stdout, \"\")\u000A');codeLines.push(' t4 :\u003D Create(\"t4\",\u000A \"Range: {{range .}}{{.}} {{end}}\\n\")\u000A t4.Execute(os.Stdout,\u000A []string{\u000A \"Go\",\u000A \"Rust\",\u000A \"C++\",\u000A \"C#\",\u000A })\u000A}\u000A');codeLines.push('');
</script>
<script src="site.js" async></script>
</body>
</html>