Gotemplate¶
Flamingo comes with a wrapped html/template
as a simple default template engine.
Structured templating¶
Template directory¶
This module allows you to set up a deeply nested directory structure containing template files with the .html
type ending.
These files can be referenced from a controller by just using the path without .html
.
An example for such a directory structure could be:
/project/
/templates/
/deep/
/nested/
/index.html
main.go
go.mod
Here index.html
resembles an example template. For our purposes, it contains the following content:
<!-- /templates/deep/nested/index.html -->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<body>
<main>
<h1>Huzzah! It works!</h1>
<p>
This is an example text.
</p>
</main>
</body>
</html>
You can refer to the html/template documentation for further information on how to fill your template.
To render index.html
in your controller, just call
return controller.responder.Render("/deep/nested/index")
Note: The template directory's name can also be changed within your config but it defaults to templates
if unset.
Layout templates¶
Layouts can be used to reduce boilerplate html when creating templates by encapsulating your templates.
To begin, let's start by creating a new layouts
folder with a base.html
layout file inside of our templates
directory. You can configure the name of your layouts folder in your project configuration, although it must always reside inside of your templates folder.
/project/
/templates/
/deep/
/nested/
/index.html
/layouts/
base.html
main.go
go.mod
A layout contains all the html that you want to reuse. Therefore, we first want to extract all the boilerplate html out of our templates and place it into our base.html
and update our index.html
accordingly.
Here is what our index.html
looks like, after refactoring:
<!-- /templates/deep/nested/index.html -->
{{template "layouts/base.html" .}}
{{define "title"}}
Hello World
{{end}}
{{define "content"}}
<main>
<h1>Huzzah! It works!</h1>
<p>
This is an example text.
</p>
</main>
{{end}}
Ok, let's look at what we did step by step:
- We moved all the html we want to reuse into the
base.html
layout. - We defined the layout our template will be inserted into via the
{{template "layouts/base.html" .}}
action. (The dot after the path hands the data to the specified layout when everything is being rendered) - We defined our template blocks via the
{{define "<block-name>"}}
action and closed said definition with the{{end}}
action.
Next, let's look at our layout file:
<!-- /templates/layouts/base.html -->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{template "title" .}}</title>
</head>
<body>
{{template "content" .}}
</body>
</html>
As you can see, this is where most of the html from index.html
has ended up. You may also have notice that the previously defined template blocks have been called upon at there corresponding positions.
If you were to now render index.html
you would recieve an html page like the one we started out with.
Congratulations! You have understood the basic concept of layouts, but that's not all!
You can make use of layouts and templates to create fragments which can then be called upon dynamically, like in this example:
{{range $i, $p := .Products}}
{{if le $i 0}}
{{template "deep/otherNest/noProducts.html" $p}}
{{end}}
<div class="row">
{{template "deep/otherNest/product.html" $p}}
</div>
{{end}}
Configuration¶
Within your config.yml
you can define the paths for your template and layout directory.
# /config/config.yml
gotemplates:
engine:
templates:
basepath: "templates", # template directory
layout:
dir: "layouts", # layout directory within the template directory
Static assets¶
You can use Flamingo’s built-in static file handler to automatically serve necessary static assets from your asset folder.
You can set it up by adding a route to your urls.go
file and setting the name
param to the name of your asset folder.
In the following example, our assets lie in the asset
folder:
// /polls/urls.go
func (u *urls) Routes(registry *web.RouterRegistry) {
// ...
registry.MustRoute("/asset/*name", `flamingo.static.file(name, dir?="asset")`)
}