Skip to content

Template Engine

Goigniter uses Go’s html/template for rendering HTML. Templates are HTML files with embedded action tags.

type Welcome struct {
core.Controller
}
func (w *Welcome) Index() {
w.Ctx.View("welcome", core.Map{
"Title": "Welcome",
})
}

This renders application/views/welcome.html.

Templates are loaded from the application/views/ directory. Subdirectories are supported:

application/views/
├── welcome.html
├── products/
│ ├── index.html
│ └── detail.html
└── admin/
└── dashboard.html

Render by path:

w.Ctx.View("products/index", core.Map{})
w.Ctx.View("admin/dashboard", core.Map{})

Go templates use {{ }} for actions:

application/views/welcome.html
<!DOCTYPE html>
<html>
<head>
<title>{{ .Title }}</title>
</head>
<body>
<h1>{{ .Title }}</h1>
<p>Welcome to Goigniter!</p>
</body>
</html>
<h1>{{ .Title }}</h1>
<p>{{ .User.Name }}</p>
<p>{{ .Count }}</p>
<ul>
{{ range .Products }}
<li>{{ .Name }} - {{ .Price }}</li>
{{ end }}
</ul>
{{ if .IsLoggedIn }}
<p>Welcome back, {{ .User.Name }}!</p>
{{ else }}
<a href="/login">Login</a>
{{ end }}

Define a layout with {{template}}:

application/views/layouts/main.html
<!DOCTYPE html>
<html>
<head>
<title>{{ .Title }} - My App</title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<header>
<h1>My App</h1>
<nav>
<a href="/">Home</a>
<a href="/products">Products</a>
</nav>
</header>
<main>
{{template "content" .}}
</main>
<footer>
<p>&copy; 2025 My App</p>
</footer>
</body>
</html>

Content template that uses the layout:

application/views/products/index.html
{{template "layouts/main" .}}
{{define "content"}}
<h2>Products</h2>
<ul>
{{range .Products}}
<li>{{.Name}} - {{.Price}}</li>
{{end}}
</ul>
{{end}}

Generates a public URL:

<link rel="stylesheet" href='{{ helper "base_url" "/static/css/style.css" }}'>
<!-- Output: http://localhost:8080/static/css/style.css -->

Generates a route URL:

<a href='{{ helper "site_url" "/products/detail/5" }}'>Detail</a>
<!-- Output: http://localhost:8080/products/detail/5 -->

Generates a URL for static assets:

<img src='{{ helper "asset_url" "/images/logo.png" }}'>

Returns “active” if the current route matches:

<a href="/" class='{{ helper "is_active" "/" "active" }}'>Home</a>
<a href="/products" class='{{ helper "is_active" "/products" "active" }}'>Products</a>

Truncates text to a specified length:

<p>{{ helper "excerpt" .Description 100 }}</p>

Formats a time value:

<p>{{ helper "date" .CreatedAt "2006-01-02" }}</p>

Converts newlines to <br> tags:

<p>{{ helper "nl2br" .Description }}</p>
func (p *Product) Index() {
products := getProducts()
p.Ctx.JSON(200, core.Map{
"success": true,
"data": products,
})
}
func (w *Welcome) Health() {
w.Ctx.String(200, "OK")
}

Next: Database for connecting to SQLite and MySQL.