Template Engine
Template di GoIgniter menggunakan package html/template bawaan Go. Sintaksnya berbeda dari PHP, tapi konsepnya sama - menampilkan data dinamis dalam HTML.
Setup Template
Section titled “Setup Template”Di main.go, load templates dari folder views:
func main() { app := core.New()
// Load templates // Parameter kedua: true = reload setiap request (development) // false = cache templates (production) err := app.LoadTemplates("./application/views", true) if err != nil { log.Fatal(err) }
app.AutoRoute() app.Run(":8080")}Struktur folder views:
application/views/├── welcome.html├── products/│ ├── index.html│ ├── show.html│ └── create.html└── admin/ ├── layout.html └── dashboard.htmlSintaks Dasar
Section titled “Sintaks Dasar”Perbandingan PHP dengan Go template:
<h1><?= $title ?></h1><p>Selamat datang, <?= $user['name'] ?>!</p>
<?php if ($is_admin): ?> <a href="/admin">Admin Panel</a><?php endif; ?>
<ul><?php foreach ($products as $product): ?> <li><?= $product['name'] ?> - Rp <?= $product['price'] ?></li><?php endforeach; ?></ul><h1>{{.Title}}</h1><p>Selamat datang, {{.User.Name}}!</p>
{{if .IsAdmin}} <a href="/admin">Admin Panel</a>{{end}}
<ul>{{range .Products}} <li>{{.Name}} - Rp {{.Price}}</li>{{end}}</ul>Perbedaan utama:
- Variabel diawali dengan
.(dot) - Tidak ada
$,<?php ?>, atau; - Block diakhiri dengan
{{end}}, bukanendif/endforeach
Passing Data ke View
Section titled “Passing Data ke View”Dari controller, kirim data dengan core.Map:
func (w *Welcome) Index() { w.Ctx.View("welcome", core.Map{ "Title": "Selamat Datang", "User": user, "IsAdmin": true, "Products": products, })}Di template, akses dengan .NamaKey:
<h1>{{.Title}}</h1>Kondisional
Section titled “Kondisional”If-Else
Section titled “If-Else”{{if .IsLoggedIn}} <p>Halo, {{.Username}}!</p> <a href="/logout">Logout</a>{{else}} <a href="/login">Login</a>{{end}}If-Else If-Else
Section titled “If-Else If-Else”{{if eq .Role "admin"}} <span class="badge">Admin</span>{{else if eq .Role "editor"}} <span class="badge">Editor</span>{{else}} <span class="badge">User</span>{{end}}Operator Perbandingan
Section titled “Operator Perbandingan”{{if eq .Status "active"}} <!-- sama dengan -->{{if ne .Status "deleted"}} <!-- tidak sama dengan -->{{if lt .Count 10}} <!-- kurang dari -->{{if le .Count 10}} <!-- kurang dari atau sama dengan -->{{if gt .Count 0}} <!-- lebih dari -->{{if ge .Count 1}} <!-- lebih dari atau sama dengan -->Logical Operators
Section titled “Logical Operators”{{if and .IsLoggedIn .IsAdmin}} <!-- Login DAN admin -->{{end}}
{{if or .IsAdmin .IsEditor}} <!-- Admin ATAU editor -->{{end}}
{{if not .IsDeleted}} <!-- Tidak deleted -->{{end}}Looping
Section titled “Looping”Range untuk Slice/Array
Section titled “Range untuk Slice/Array”<ul>{{range .Products}} <li>{{.Name}} - {{.Price}}</li>{{end}}</ul>Range dengan Index
Section titled “Range dengan Index”<ul>{{range $index, $product := .Products}} <li>{{$index}}. {{$product.Name}}</li>{{end}}</ul>Range dengan Else (untuk empty)
Section titled “Range dengan Else (untuk empty)”{{range .Products}} <li>{{.Name}}</li>{{else}} <li>Tidak ada produk.</li>{{end}}Template Functions Bawaan
Section titled “Template Functions Bawaan”GoIgniter menyediakan beberapa fungsi template:
<!-- Huruf besar -->{{upper .Name}}<!-- Output: JOHN DOE -->
<!-- Huruf kecil -->{{lower .Name}}<!-- Output: john doe -->
<!-- Title case -->{{title .Name}}<!-- Output: John Doe -->
<!-- Trim whitespace -->{{trim .Description}}
<!-- Render HTML tanpa escape -->{{safe .HtmlContent}}
<!-- Cek apakah string mengandung substring -->{{if contains .Email "@gmail.com"}} Gmail user{{end}}
<!-- Replace string -->{{replace .Text "foo" "bar"}}
<!-- Split string -->{{range split .Tags ","}} <span>{{.}}</span>{{end}}
<!-- Join slice -->{{join .Tags ", "}}Custom Template Functions
Section titled “Custom Template Functions”Tambahkan fungsi custom saat load templates:
import "html/template"
func main() { app := core.New()
funcs := template.FuncMap{ // Format rupiah "rupiah": func(n int) string { return fmt.Sprintf("Rp %d", n) },
// Format tanggal "formatDate": func(t time.Time) string { return t.Format("02 Jan 2006") },
// Cek apakah slice kosong "empty": func(s any) bool { return reflect.ValueOf(s).Len() == 0 }, }
app.LoadTemplatesWithFuncs("./views", true, funcs)
app.Run(":8080")}Penggunaan di template:
<p>Harga: {{rupiah .Price}}</p><!-- Output: Harga: Rp 150000 -->
<p>Tanggal: {{formatDate .CreatedAt}}</p><!-- Output: Tanggal: 13 Jan 2026 -->
{{if empty .Products}} <p>Tidak ada produk.</p>{{end}}Tips Migrasi dari PHP
Section titled “Tips Migrasi dari PHP”Tabel konversi sintaks PHP ke Go template:
| PHP | Go Template | Keterangan |
|---|---|---|
<?= $var ?> | {{.Var}} | Tampilkan variabel |
<?= $arr['key'] ?> | {{.Arr.Key}} | Akses map/struct |
<?= $arr[0] ?> | {{index .Arr 0}} | Akses array by index |
<?php if($x): ?> | {{if .X}} | Kondisional |
<?php else: ?> | {{else}} | Else |
<?php endif; ?> | {{end}} | Tutup block |
<?php foreach($items as $item): ?> | {{range .Items}} | Loop |
<?php endforeach; ?> | {{end}} | Tutup loop |
<?= htmlspecialchars($x) ?> | {{.X}} | Auto-escaped |
<?= $x ?> (raw HTML) | {{safe .X}} | Tanpa escape |
Catatan Penting
Section titled “Catatan Penting”-
Auto-escape - Semua output di-escape secara otomatis. Untuk render HTML mentah, gunakan
{{safe .Html}}. -
Case-sensitive -
.Titleberbeda dengan.title. Field harus diawali huruf kapital agar bisa diakses dari template (exported field). -
Nil handling - Jika variabel nil, template tidak error tapi tidak menampilkan apa-apa. Gunakan
{{if .Var}}untuk cek.
Multi-Layout (CI3 Style)
Section titled “Multi-Layout (CI3 Style)”GoIgniter mendukung composing views seperti CodeIgniter 3. Ada dua cara:
Cara 1: Multiple View Calls
Section titled “Cara 1: Multiple View Calls”Seperti CI3, kamu bisa panggil View() berkali-kali dan output akan di-append:
func (c *Page) About() { data := core.Map{"Title": "About Us"}
c.Ctx.View("partials/header", data) c.Ctx.View("pages/about", data) c.Ctx.View("partials/footer", data)}Cara 2: Render ke String + Compose
Section titled “Cara 2: Render ke String + Compose”Gunakan Render() untuk render template ke string, lalu pass ke layout:
func (d *Dashboard) Index() { // Render partials ke string sidebar, _ := d.Ctx.Render("admin/partials/sidebar", core.Map{}) content, _ := d.Ctx.Render("admin/pages/dashboard", core.Map{ "Title": "Dashboard", })
// Output layout dengan partials d.Ctx.View("admin/layouts/main", core.Map{ "Title": "Dashboard", "Sidebar": sidebar, "Content": content, })}Di template layout, gunakan safe untuk output HTML string:
<!DOCTYPE html><html><head><title>{{.Title}}</title></head><body> <nav>{{.Sidebar | safe}}</nav> <main>{{.Content | safe}}</main></body></html>Struktur Folder Views yang Direkomendasikan
Section titled “Struktur Folder Views yang Direkomendasikan”views/├── layouts/│ ├── main.html <!-- Layout utama -->│ └── admin.html <!-- Layout admin -->├── partials/│ ├── header.html│ ├── footer.html│ └── sidebar.html└── pages/ ├── home.html ├── about.html └── admin/ └── dashboard.htmlPerbandingan dengan CI3
Section titled “Perbandingan dengan CI3”// CI3: views dengan parameter TRUE untuk return string$header = $this->load->view('header', $data, TRUE);$content = $this->load->view('content', $data, TRUE);$this->load->view('layout', array( 'header' => $header, 'content' => $content));// GoIgniter: Render() untuk return stringheader, _ := c.Ctx.Render("header", data)content, _ := c.Ctx.Render("content", data)c.Ctx.View("layout", core.Map{ "Header": header, "Content": content,})Selamat! Kamu sudah menguasai dasar-dasar GoIgniter. Untuk contoh aplikasi lengkap, lihat folder examples/ di repository.