mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-28 06:33:59 +08:00
166 lines
19 KiB
HTML
166 lines
19 KiB
HTML
<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="Hugo uses the excellent Go html/template library for its template engine. It is an extremely lightweight engine that provides a very small amount of logic. In our experience that it is just the right amount of logic to be able to create a good static website. If you have used other template systems from different languages or frameworks you will find a lot of similarities in Go templates.
|
|
This document is a brief primer on using Go templates."><meta name=theme-color content="#FFFFFF"><meta property="og:title" content="(Hu)go Template Primer"><meta property="og:description" content="Hugo uses the excellent Go html/template library for its template engine. It is an extremely lightweight engine that provides a very small amount of logic. In our experience that it is just the right amount of logic to be able to create a good static website. If you have used other template systems from different languages or frameworks you will find a lot of similarities in Go templates.
|
|
This document is a brief primer on using Go templates."><meta property="og:type" content="article"><meta property="og:url" content="https://books.halfrost.com/leetcode/posts/goisforlovers/"><meta property="article:published_time" content="2014-04-02T00:00:00+00:00"><meta property="article:modified_time" content="2014-04-02T00:00:00+00:00"><title>(Hu)go Template Primer | LeetCode Cookbook</title><link rel=manifest href=/leetcode/manifest.json><link rel=icon href=/leetcode/favicon.png type=image/x-icon><link rel=stylesheet href=/leetcode/book.min.6cd8553a6854f4812343f0f0c8baca31271e686434f381fbe3c7226f66639176.css integrity="sha256-bNhVOmhU9IEjQ/DwyLrKMSceaGQ084H748cib2ZjkXY="><script defer src=/leetcode/en.search.min.b89b298482a620ecdc3740829351c9d8b19cc485f00b83eaf4b57f44e1cb7e23.js integrity="sha256-uJsphIKmIOzcN0CCk1HJ2LGcxIXwC4Pq9LV/ROHLfiM="></script><script defer src=/leetcode/sw.min.f4d2776936ea9603d5b4d06bf489597dd2355c0a24f090e9e6dc2679587a2034.js integrity="sha256-9NJ3aTbqlgPVtNBr9IlZfdI1XAok8JDp5twmeVh6IDQ="></script></head><body><input type=checkbox class="hidden toggle" id=menu-control>
|
|
<input type=checkbox class="hidden toggle" id=toc-control><main class="container flex"><aside class=book-menu><nav><h2 class=book-brand><a href=/leetcode><span>LeetCode Cookbook</span></a></h2><div class=book-search><input type=text id=book-search-input placeholder=Search aria-label=Search maxlength=64 data-hotkeys=s/><div class="book-search-spinner hidden"></div><ul id=book-search-results></ul></div><ul><li><a href=https://halfrost.com target=_blank rel=noopener>被人嘲笑的梦想</a></li><li><a href=https://github.com/halfrost target=_blank rel=noopener>Github</a></li><li><a href=https://halfrost.com target=_blank rel=noopener>微信公众号</a></li><li><a href=https://twitter.com/halffrost target=_blank rel=noopener>Twitter</a></li><li><a href=https://weibo.com/halfrost target=_blank rel=noopener>Weibo</a></li></ul><ul><li><p><a href=/leetcode/docs/example/><strong>Example Site</strong></a></p></li><li><p><a href=/leetcode/docs/example/table-of-contents/>Table of Contents</a></p><ul><li><a href=/leetcode/docs/example/table-of-contents/with-toc/>With ToC</a></li><li><a href=/leetcode/docs/example/table-of-contents/without-toc/>Without ToC</a></li></ul></li><li><p><a href=/leetcode/docs/example/collapsed/>Collapsed</a></p><ul><li><a href=/leetcode/docs/example/collapsed/3rd-level/>3rd</a><ul><li><a href=/leetcode/docs/example/collapsed/3rd-level/4th-level/>4th</a><br></li></ul></li></ul></li><li><p><strong>Shortcodes</strong></p></li><li><p><a href=/leetcode/docs/shortcodes/buttons/>Buttons</a></p></li><li><p><a href=/leetcode/docs/shortcodes/columns/>Columns</a></p></li><li><p><a href=/leetcode/docs/shortcodes/expand/>Expand</a></p></li><li><p><a href=/leetcode/docs/shortcodes/hints/>Hints</a></p></li><li><p><a href=/leetcode/docs/shortcodes/katex/>Katex</a></p></li><li><p><a href=/leetcode/docs/shortcodes/mermaid/>Mermaid</a></p></li><li><p><a href=/leetcode/docs/shortcodes/tabs/>Tabs</a><br></p></li></ul><ul><li><a href=/leetcode/posts/>Blog</a></li></ul></nav><script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script></aside><div class=book-page><header class=book-header><div class="flex align-center justify-between"><label for=menu-control><img src=/leetcode/svg/menu.svg class=book-icon alt=Menu></label>
|
|
<strong>(Hu)go Template Primer</strong>
|
|
<label for=toc-control><img src=/leetcode/svg/toc.svg class=book-icon alt="Table of Contents"></label></div><aside class="hidden clearfix"><nav id=TableOfContents><ul><li><ul><li><a href=#introduction-to-go-templates>Introduction to Go Templates</a></li><li><a href=#basic-syntax>Basic Syntax</a></li><li><a href=#variables>Variables</a></li><li><a href=#functions>Functions</a></li><li><a href=#includes>Includes</a></li><li><a href=#logic>Logic</a><ul><li><a href=#iteration>Iteration</a></li><li><a href=#conditionals>Conditionals</a></li></ul></li><li><a href=#pipes>Pipes</a></li><li><a href=#context-aka-the-dot>Context (aka. the dot)</a></li></ul></li><li><a href=#hugo-parameters>Hugo Parameters</a><ul><li><a href=#using-content-page-parameters>Using Content (page) Parameters</a></li><li><a href=#using-site-config-parameters>Using Site (config) Parameters</a></li></ul></li></ul></nav></aside></header><article class=markdown><h1><a href=/leetcode/posts/goisforlovers/>(Hu)go Template Primer</a></h1><h5>Apr 2, 2014</h5><div><a href=/leetcode/categories/Development/>Development</a>,
|
|
<a href=/leetcode/categories/golang/>golang</a></div><div><a href=/leetcode/tags/go/>go</a>,
|
|
<a href=/leetcode/tags/golang/>golang</a>,
|
|
<a href=/leetcode/tags/templates/>templates</a>,
|
|
<a href=/leetcode/tags/themes/>themes</a>,
|
|
<a href=/leetcode/tags/development/>development</a></div><p><p>Hugo uses the excellent
|
|
<a href=https://golang.org/>Go</a>
|
|
<a href=https://golang.org/pkg/html/template/>html/template</a> library for
|
|
its template engine. It is an extremely lightweight engine that provides a very
|
|
small amount of logic. In our experience that it is just the right amount of
|
|
logic to be able to create a good static website. If you have used other
|
|
template systems from different languages or frameworks you will find a lot of
|
|
similarities in Go templates.</p><p>This document is a brief primer on using Go templates. The
|
|
<a href=https://golang.org/pkg/html/template/>Go docs</a>
|
|
provide more details.</p><h2 id=introduction-to-go-templates>Introduction to Go Templates
|
|
<a class=anchor href=#introduction-to-go-templates>#</a></h2><p>Go templates provide an extremely simple template language. It adheres to the
|
|
belief that only the most basic of logic belongs in the template or view layer.
|
|
One consequence of this simplicity is that Go templates parse very quickly.</p><p>A unique characteristic of Go templates is they are content aware. Variables and
|
|
content will be sanitized depending on the context of where they are used. More
|
|
details can be found in the
|
|
<a href=https://golang.org/pkg/html/template/>Go docs</a>.</p><h2 id=basic-syntax>Basic Syntax
|
|
<a class=anchor href=#basic-syntax>#</a></h2><p>Golang templates are HTML files with the addition of variables and
|
|
functions.</p><p><strong>Go variables and functions are accessible within {{ }}</strong></p><p>Accessing a predefined variable “foo”:</p><pre><code>{{ foo }}
|
|
</code></pre><p><strong>Parameters are separated using spaces</strong></p><p>Calling the add function with input of 1, 2:</p><pre><code>{{ add 1 2 }}
|
|
</code></pre><p><strong>Methods and fields are accessed via dot notation</strong></p><p>Accessing the Page Parameter “bar”</p><pre><code>{{ .Params.bar }}
|
|
</code></pre><p><strong>Parentheses can be used to group items together</strong></p><pre><code>{{ if or (isset .Params "alt") (isset .Params "caption") }} Caption {{ end }}
|
|
</code></pre><h2 id=variables>Variables
|
|
<a class=anchor href=#variables>#</a></h2><p>Each Go template has a struct (object) made available to it. In hugo each
|
|
template is passed either a page or a node struct depending on which type of
|
|
page you are rendering. More details are available on the
|
|
<a href=/layout/variables>variables</a> page.</p><p>A variable is accessed by referencing the variable name.</p><pre><code><title>{{ .Title }}</title>
|
|
</code></pre><p>Variables can also be defined and referenced.</p><pre><code>{{ $address := "123 Main St."}}
|
|
{{ $address }}
|
|
</code></pre><h2 id=functions>Functions
|
|
<a class=anchor href=#functions>#</a></h2><p>Go template ship with a few functions which provide basic functionality. The Go
|
|
template system also provides a mechanism for applications to extend the
|
|
available functions with their own.
|
|
<a href=/layout/functions>Hugo template
|
|
functions</a> provide some additional functionality we believe
|
|
are useful for building websites. Functions are called by using their name
|
|
followed by the required parameters separated by spaces. Template
|
|
functions cannot be added without recompiling hugo.</p><p><strong>Example:</strong></p><pre><code>{{ add 1 2 }}
|
|
</code></pre><h2 id=includes>Includes
|
|
<a class=anchor href=#includes>#</a></h2><p>When including another template you will pass to it the data it will be
|
|
able to access. To pass along the current context please remember to
|
|
include a trailing dot. The templates location will always be starting at
|
|
the /layout/ directory within Hugo.</p><p><strong>Example:</strong></p><pre><code>{{ template "chrome/header.html" . }}
|
|
</code></pre><h2 id=logic>Logic
|
|
<a class=anchor href=#logic>#</a></h2><p>Go templates provide the most basic iteration and conditional logic.</p><h3 id=iteration>Iteration
|
|
<a class=anchor href=#iteration>#</a></h3><p>Just like in Go, the Go templates make heavy use of range to iterate over
|
|
a map, array or slice. The following are different examples of how to use
|
|
range.</p><p><strong>Example 1: Using Context</strong></p><pre><code>{{ range array }}
|
|
{{ . }}
|
|
{{ end }}
|
|
</code></pre><p><strong>Example 2: Declaring value variable name</strong></p><pre><code>{{range $element := array}}
|
|
{{ $element }}
|
|
{{ end }}
|
|
</code></pre><p><strong>Example 2: Declaring key and value variable name</strong></p><pre><code>{{range $index, $element := array}}
|
|
{{ $index }}
|
|
{{ $element }}
|
|
{{ end }}
|
|
</code></pre><h3 id=conditionals>Conditionals
|
|
<a class=anchor href=#conditionals>#</a></h3><p>If, else, with, or, & and provide the framework for handling conditional
|
|
logic in Go Templates. Like range, each statement is closed with <code>end</code>.</p><p>Go Templates treat the following values as false:</p><ul><li>false</li><li>0</li><li>any array, slice, map, or string of length zero</li></ul><p><strong>Example 1: If</strong></p><pre><code>{{ if isset .Params "title" }}<h4>{{ index .Params "title" }}</h4>{{ end }}
|
|
</code></pre><p><strong>Example 2: If -> Else</strong></p><pre><code>{{ if isset .Params "alt" }}
|
|
{{ index .Params "alt" }}
|
|
{{else}}
|
|
{{ index .Params "caption" }}
|
|
{{ end }}
|
|
</code></pre><p><strong>Example 3: And & Or</strong></p><pre><code>{{ if and (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}}
|
|
</code></pre><p><strong>Example 4: With</strong></p><p>An alternative way of writing “if” and then referencing the same value
|
|
is to use “with” instead. With rebinds the context <code>.</code> within its scope,
|
|
and skips the block if the variable is absent.</p><p>The first example above could be simplified as:</p><pre><code>{{ with .Params.title }}<h4>{{ . }}</h4>{{ end }}
|
|
</code></pre><p><strong>Example 5: If -> Else If</strong></p><pre><code>{{ if isset .Params "alt" }}
|
|
{{ index .Params "alt" }}
|
|
{{ else if isset .Params "caption" }}
|
|
{{ index .Params "caption" }}
|
|
{{ end }}
|
|
</code></pre><h2 id=pipes>Pipes
|
|
<a class=anchor href=#pipes>#</a></h2><p>One of the most powerful components of Go templates is the ability to
|
|
stack actions one after another. This is done by using pipes. Borrowed
|
|
from unix pipes, the concept is simple, each pipeline’s output becomes the
|
|
input of the following pipe.</p><p>Because of the very simple syntax of Go templates, the pipe is essential
|
|
to being able to chain together function calls. One limitation of the
|
|
pipes is that they only can work with a single value and that value
|
|
becomes the last parameter of the next pipeline.</p><p>A few simple examples should help convey how to use the pipe.</p><p><strong>Example 1 :</strong></p><pre><code>{{ if eq 1 1 }} Same {{ end }}
|
|
</code></pre><p>is the same as</p><pre><code>{{ eq 1 1 | if }} Same {{ end }}
|
|
</code></pre><p>It does look odd to place the if at the end, but it does provide a good
|
|
illustration of how to use the pipes.</p><p><strong>Example 2 :</strong></p><pre><code>{{ index .Params "disqus_url" | html }}
|
|
</code></pre><p>Access the page parameter called “disqus_url” and escape the HTML.</p><p><strong>Example 3 :</strong></p><pre><code>{{ if or (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}}
|
|
Stuff Here
|
|
{{ end }}
|
|
</code></pre><p>Could be rewritten as</p><pre><code>{{ isset .Params "caption" | or isset .Params "title" | or isset .Params "attr" | if }}
|
|
Stuff Here
|
|
{{ end }}
|
|
</code></pre><h2 id=context-aka-the-dot>Context (aka. the dot)
|
|
<a class=anchor href=#context-aka-the-dot>#</a></h2><p>The most easily overlooked concept to understand about Go templates is that {{ . }}
|
|
always refers to the current context. In the top level of your template this
|
|
will be the data set made available to it. Inside of a iteration it will have
|
|
the value of the current item. When inside of a loop the context has changed. .
|
|
will no longer refer to the data available to the entire page. If you need to
|
|
access this from within the loop you will likely want to set it to a variable
|
|
instead of depending on the context.</p><p><strong>Example:</strong></p><pre><code> {{ $title := .Site.Title }}
|
|
{{ range .Params.tags }}
|
|
<li> <a href="{{ $baseurl }}/tags/{{ . | urlize }}">{{ . }}</a> - {{ $title }} </li>
|
|
{{ end }}
|
|
</code></pre><p>Notice how once we have entered the loop the value of {{ . }} has changed. We
|
|
have defined a variable outside of the loop so we have access to it from within
|
|
the loop.</p><h1 id=hugo-parameters>Hugo Parameters
|
|
<a class=anchor href=#hugo-parameters>#</a></h1><p>Hugo provides the option of passing values to the template language
|
|
through the site configuration (for sitewide values), or through the meta
|
|
data of each specific piece of content. You can define any values of any
|
|
type (supported by your front matter/config format) and use them however
|
|
you want to inside of your templates.</p><h2 id=using-content-page-parameters>Using Content (page) Parameters
|
|
<a class=anchor href=#using-content-page-parameters>#</a></h2><p>In each piece of content you can provide variables to be used by the
|
|
templates. This happens in the
|
|
<a href=/content/front-matter>front matter</a>.</p><p>An example of this is used in this documentation site. Most of the pages
|
|
benefit from having the table of contents provided. Sometimes the TOC just
|
|
doesn’t make a lot of sense. We’ve defined a variable in our front matter
|
|
of some pages to turn off the TOC from being displayed.</p><p>Here is the example front matter:</p><pre><code>---
|
|
title: "Permalinks"
|
|
date: "2013-11-18"
|
|
aliases:
|
|
- "/doc/permalinks/"
|
|
groups: ["extras"]
|
|
groups_weight: 30
|
|
notoc: true
|
|
---
|
|
</code></pre><p>Here is the corresponding code inside of the template:</p><pre><code> {{ if not .Params.notoc }}
|
|
<div id="toc" class="well col-md-4 col-sm-6">
|
|
{{ .TableOfContents }}
|
|
</div>
|
|
{{ end }}
|
|
</code></pre><h2 id=using-site-config-parameters>Using Site (config) Parameters
|
|
<a class=anchor href=#using-site-config-parameters>#</a></h2><p>In your top-level configuration file (eg, <code>config.yaml</code>) you can define site
|
|
parameters, which are values which will be available to you in chrome.</p><p>For instance, you might declare:</p><div class=highlight><pre style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-yaml data-lang=yaml><span style=color:#66d9ef>params</span>:
|
|
<span style=color:#66d9ef>CopyrightHTML</span>: <span style=color:#e6db74>"Copyright &#xA9; 2013 John Doe. All Rights Reserved."</span>
|
|
<span style=color:#66d9ef>TwitterUser</span>: <span style=color:#e6db74>"spf13"</span>
|
|
<span style=color:#66d9ef>SidebarRecentLimit</span>: <span style=color:#ae81ff>5</span>
|
|
</code></pre></div><p>Within a footer layout, you might then declare a <code><footer></code> which is only
|
|
provided if the <code>CopyrightHTML</code> parameter is provided, and if it is given,
|
|
you would declare it to be HTML-safe, so that the HTML entity is not escaped
|
|
again. This would let you easily update just your top-level config file each
|
|
January 1st, instead of hunting through your templates.</p><pre><code>{{if .Site.Params.CopyrightHTML}}<footer>
|
|
<div class="text-center">{{.Site.Params.CopyrightHTML | safeHtml}}</div>
|
|
</footer>{{end}}
|
|
</code></pre><p>An alternative way of writing the “if” and then referencing the same value
|
|
is to use “with” instead. With rebinds the context <code>.</code> within its scope,
|
|
and skips the block if the variable is absent:</p><pre><code>{{with .Site.Params.TwitterUser}}<span class="twitter">
|
|
<a href="https://twitter.com/{{.}}" rel="author">
|
|
<img src="/images/twitter.png" width="48" height="48" title="Twitter: {{.}}"
|
|
alt="Twitter"></a>
|
|
</span>{{end}}
|
|
</code></pre><p>Finally, if you want to pull “magic constants” out of your layouts, you can do
|
|
so, such as in this example:</p><pre><code><nav class="recent">
|
|
<h1>Recent Posts</h1>
|
|
<ul>{{range first .Site.Params.SidebarRecentLimit .Site.Recent}}
|
|
<li><a href="{{.RelPermalink}}">{{.Title}}</a></li>
|
|
{{end}}</ul>
|
|
</nav>
|
|
</code></pre></p></article><footer class=book-footer><div class="flex flex-wrap justify-between"></div></footer><label for=menu-control class="hidden book-menu-overlay"></label></div><aside class=book-toc><nav id=TableOfContents><ul><li><ul><li><a href=#introduction-to-go-templates>Introduction to Go Templates</a></li><li><a href=#basic-syntax>Basic Syntax</a></li><li><a href=#variables>Variables</a></li><li><a href=#functions>Functions</a></li><li><a href=#includes>Includes</a></li><li><a href=#logic>Logic</a><ul><li><a href=#iteration>Iteration</a></li><li><a href=#conditionals>Conditionals</a></li></ul></li><li><a href=#pipes>Pipes</a></li><li><a href=#context-aka-the-dot>Context (aka. the dot)</a></li></ul></li><li><a href=#hugo-parameters>Hugo Parameters</a><ul><li><a href=#using-content-page-parameters>Using Content (page) Parameters</a></li><li><a href=#using-site-config-parameters>Using Site (config) Parameters</a></li></ul></li></ul></nav></aside></main></body></html> |