Templates are essentially static text files that are used to create
dynamic content by replacing variables with actual values and transforms into
an HTML and Text file. This approach makes it easier to design an HTML page or a text file. Golang uses the same
principle to generate dynamic webpages.
Templates In Go
Go web templates allow us to serve personalized results to users. Go templates are simple but powerful methods to customize the output by applying them to a data structure (Inputs). Golang standard library has two packages with the same interface having subtle web-specific differences in the latter like encoding script tags to prevent them from running, parsing maps as JSON in view, and more. text/templates This package implements data-driven templates for generating text output safe against code injection. html/templates This package implements data-driven templates for generating HTML output safe against code injection. It provides the same interface as a package text/template and should be used instead oftext/template
whenever the output is HTML.
Template Naming
Go templating does not have any defined file extension. One of the most popular extensions is.tmpl
supported by vim-go and
referenced in the text/template godocs. The extension .gohtml
supports syntax highlighting in both
Atom and Go
Sublime editors. While the extension is not important
it is still good to be consistent within a project for clarity.
Parsing Templates
Single
Get the template using provided string and store it in the t.
t, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
Get the template at the filename and store it in t.
t, err := template.Parse(filename)
Multiple
Parse and stores all templates for provided list of filenames t, err := template.ParseFiles(filenames)
Find all templates matching the pattern and store the templates.
t, err := template.ParseGlob(pattern)
Must
Must is a helper that wraps a call to a function returning (*Template, error) and panics if the error is non-nil.
t := template.Must(template.New("name").Parse("text"))
Executing Templates
Once a template is parsed, it can be executed safely in parallel, although if parallel executions share a
Writer the output may be interleaved. Once execution completes the content of the parsed template (t) will
be written to the io.Writer.
Input Data is an interface passed to the template that will be useable by the template to replace variables
with actual values. There are two options to execute them.
Single
t.Execute(io.Writer, data)
will be used for single template execution.
Named
t.ExecuteTemplate(io.Writer, name, data)
will be used for executing a specific template with
the name.
Variables
The template package allows you to define and use variables. A template variable can be a
boolean, string, character,
integer, floating-point,] imaginary, or
complex constant in Go syntax.
The Dot (.) Operator
{{ . }}
Input Data passed to the template can be accessed using a dot.
Fields
{{ .FieldName }}
If the data is a complex type then its fields can be accessed using the dot.
Nested Fields
{{ .Struct.StructTwo.Field }}
Dots can be chained together if the data contains multiple
complex structures.
Definition
Data passed to the template can also be saved in a variable and used throughout the template{{ $value := . }}
. We use the $value to create a variable then initialize it
with the value passed to the template. To use the variable we call it in the template with
{{ $value }}
.
Actions
Remove White Space
By default, all text between actions is copied verbatim when the template is executed as a result it can add a various number of whitespaces. We can change the template code to remove additional whitespaces or make use–
(Minus) symbol to remove leading and
trilling spaces.
{{-
All trailing white space is trimmed from the immediately preceding text
-}}
All leading white space is trimmed from the immediately following text
Comments
{{/* A comment */}}
A comment is discarded by the template executor. Comments may contain
newlines. Comments do not nest and must start and end at the delimiters
Pipeline
Unix users should be familiar with the pipe operator, like ls| grep “test”
. This command
filters files and only shows those that contain the world test. Similar to that go template supports pipes.
Anything in the {{ }}
is considered a data pipeline. {{ . | html }}
is a pipeline
to escape input data into HTML to avoid any vulnerable XSS attack.
If / Else
Unlike any other language go template allows us to check values using the If / else block. The empty values for a variable are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero. for example:{{if pipeline}} Exists {{end}}
If the value of the pipeline is empty,
no output is generated; otherwise, Exists is printed. {{if pipeline}} Exists {{else}} Not Available {{end}}
If the value of the pipeline is empty,
Not Available is printed; otherwise, Exists is printed.
Dot is unaffected.
Range
Unlike any other language, Go templates allows us to iterate through a collection of values using the range. The value of the pipeline must be an array, slice, map, or channel. If the value is a map and the keys are of the basic type with a defined order, the elements will be visited in sorted key order.{{range pipeline }} T1 {{end}}
If the value of the pipeline has length zero, nothing is output;
otherwise, the dot is set to the successive elements of the array, slice, or map, and T1 is executed. {{range pipeline }} T1 {{else}} T0 {{end}}
If the value of the pipeline has length zero, the
dot is unaffected and T0 is executed; otherwise, the dot is set to the successive elements of the array,
slice, or map and T1 is executed.
With
{{with pipeline}} T1 {{end}}
If the value of the pipeline is empty, no output is generated;
otherwise, dot is set to the value of the pipeline, and T1 is executed. {{with pipeline}} T1 {{else}} T0 {{end}}
If the value of the pipeline is empty, the dot is
unaffected and T0 is executed; otherwise, the dot is set to the value of the pipeline and T1 is executed.
Functions
{{ if and .User .User.Admin }}
Go template allows us to call different functions to evaluate
input data and generate the required output.
Built-In Functions
There are a couple of built-in functions support is available outofbox in the go template package.Comparison Functions
-
eq
returns the Boolean truth ofarg1 == arg2
-
ne
returns the Boolean truth ofarg1 != arg2
-
lt
returns the Boolean truth ofarg1 < arg2
-
le
returns the Boolean truth ofarg1 <= arg2
-
gt
returns the Boolean truth ofarg1 > arg2
-
ge
returns the Boolean truth ofarg1 >= arg2
-
and
returns the Boolean AND of its arguments by returning the first empty argument or the last argument. -
or
returns the Boolean OR of its arguments by returning the first non-empty argument or the last argument -
not
returns the Boolean negation of its single argument.
Helper Functions
- print an alias for fmt.Sprint
- printf an alias for fmt.Sprintf
- println an alias for fmt.Sprintln
- len returns the integer length of its argument.
- index returns the result of indexing its first argument by the following arguments. Each indexed item must be a map, slice, or array.
- html returns the escaped HTML equivalent of the textual representation of its arguments.
- slice returns the result of slicing its first argument by the remaining arguments. The first argument must be a string, slice, or array.
- js returns the escaped JavaScript equivalent of the textual representation of its arguments.
- urlquery returns the escaped value of the textual representation of its arguments in a form suitable for embedding in a URL query.
Calling Functions
Go templates support the execution of custom functions defined by the user such asTemplates can call methods (Struct Function) of objects in the template to return data.
{{ if .User.HasPermission "feature-a" }}
Go template allows us to call function variable on Input Data, to achieve this we must
change the template call function variable using call keyword.
{{ if (call .User.HasPermission "feature-b") }}
Another way to call functions is to create custom global function with
template.FuncMap
. This method creates global methods that can be used throughout the
entire application. FuncMap
has type map[string]interface{}
mapping strings to
functions. The mapped functions must have either a single return value, or two return values where the
second has type error.
{{ if hasPermission .User "feature-a" }}
Encoding & HTML
html/template package uses code context to encode any characters that need to be encoded to be rendered
correctly. Type template.HTML should be used consciously this can cause a
vulnerable XSS attack if user input is dangerous (contains vulnerable XSS attack). For
example the < and > in "<h1>Title</h1>"
will be encoded as amp;lt;h1>Title</h1>. Type
template.HTML
can be used to skip encoding by telling Go the string is safe.
Template.HTML("<h1>A Safe header</h1>")
will then be <h1>A Safe header</h1>
Nested Templates & Layouts
Unlike any web application frameworks, certain part of templates can be reused across other templates, like header and footer. Rather than updating each template separately we can use a nested template that all other templates can use.
master = `Names: {{block "list" .}}{{"\n"}}{{range .}}{{println "-" .}}{{end}}{{end}}`
overlay = `{{define "list"}} {{join . ", "}}{{end}}`
overlay = `{{define "list"}} {{join . ", "}}{{end}}`
Example
Template
Post a Comment
Post a Comment