Templating adalah salah satu aspek paling powerful dalam Hugo yang memungkinkan Anda untuk membuat tampilan website yang fleksibel dan dapat digunakan kembali. Dalam tutorial ini, kita akan membahas secara mendalam tentang sistem templating Hugo, mulai dari konsep dasar layouts dan templates hingga penggunaan partials dan block system yang lebih advanced. Pemahaman yang solid tentang templating akan memungkinkan Anda untuk membangun website Hugo yang modular, mudah dipelihara, dan profesional.
Hugo menggunakan Go templates sebagai engine templating-nya, yang merupakan implementasi dari package text/template standar Go dengan tambahan fungsi khusus Hugo. Go templates menggunakan sintaksis kurung kurawal ganda {{ }} untuk menyisipkan logika templating ke dalam HTML. Meskipun terlihat sederhana, sistem ini sangat powerful dan memungkinkan pembuatan template yang kompleks dengan kode yang bersih dan readable.
Arsitektur Folder Layout di Hugo
Sebelum mempelajari detail templating, penting untuk memahami struktur folder yang digunakan Hugo untuk mengorganisir template-template-nya. Hugo memiliki konvensi folder yang jelas untuk layouts, yang memudahkan pengembang dalam mengorganisir dan menemukan template yang tepat.
Struktur Dasar Layouts
Folder layouts di root proyek Hugo adalah lokasi utama untuk menyimpan semua template. Didalamnya, Hugo menggunakan struktur subfolder yang mengikuti jenis konten dan jenis halaman. Folder _default berisi template-template default yang akan digunakan jika tidak ada template khusus untuk jenis konten tertentu. Template di folder ini mencakup baseof.html sebagai template induk untuk semua halaman, list.html untuk halaman daftar seperti homepage dan halaman kategori, single.html untuk halaman konten individual seperti artikel blog, dan sitemap.xml untuk generate sitemap.
layouts/
βββ _default/
β βββ baseof.html
β βββ list.html
β βββ single.html
β βββ sitemap.xml
βββ index.html
βββ 404.html
βββ partials/
βββ header.html
βββ footer.html
βββ navigation.html
Selain _default, Anda juga dapat membuat folder khusus untuk jenis konten tertentu. Misalnya, jika Anda memiliki section blog, Anda dapat membuat folder layouts/blog/ yang berisi template khusus untuk section tersebut. Hugo akan mencari template di folder khusus terlebih dahulu sebelum menggunakan template default dari _default.
Urutan Pencarian Template
Hugo memiliki urutan pencarian template yang deterministik, yang memudahkan Anda untuk memahami template mana yang akan digunakan untuk halaman tertentu. Untuk halaman single (artikel blog), Hugo akan mencari template dengan urutan: layouts/{section}/{kind}.html, layouts/{section}/{slug}.html, layouts/{section}/{format}.html, layouts/_default/{kind}.html, dan layouts/_default/{format}.html. Pemahaman tentang urutan ini penting agar Anda dapat mengorganisir template dengan efisien dan menghindari konflik.
Template Baseof: Fondasi Seluruh Halaman
Template baseof.html adalah template induk yang menjadi fondasi untuk semua halaman di website Hugo. Di sinilah struktur HTML dasar didefinisikan, termasuk DOCTYPE, head section, dan body structure. Template ini menggunakan block system Hugo untuk mendefinisikan area-area yang dapat dioverride oleh template child.
Berikut adalah contoh implementasi template baseof.html yang lengkap dan SEO-friendly:
<!DOCTYPE html> <html lang="{{ .Site.LanguageCode }}"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> {{ partial "head.html" . }} </head> <body class="{{ .Kind }}{{ if .IsHome }} home{{ end }}"> {{ block "header" . }} {{ partial "header.html" . }} {{ end }}<main class="container mx-auto px-4 py-8"> {{ block "main" . }}{{ end }} </main> {{ block "footer" . }} {{ partial "footer.html" . }} {{ end }} {{ partial "scripts.html" . }}</body>
</html>Perhatikan penggunaan
{{ block "nama" . }}yang mendefinisikan area yang dapat diisi oleh template child. Variabel titik (.) yang passed ke block memungkinkan akses ke semua data halaman. Block “header”, “main”, dan “footer” adalah block standar yang umum digunakan, namun Anda dapat mendefinisikan block custom sesuai kebutuhan.Template Single: Menampilkan Konten Individual
Template
single.htmldigunakan untuk menampilkan halaman konten individual, seperti artikel blog, halaman statis, atau jenis konten custom lainnya. Template ini menerima data dari halaman yang sedang ditampilkan dan dapat mengakses semua field dari frontmatter serta kontenζ£ζ.Struktur Dasar Template Single
Berikut adalah contoh template
single.htmlyang mengimplementasikan best practices untuk SEO dan user experience:{{ define "main" }} <article class="prose lg:prose-xl mx-auto"> <header class="mb-8"> <h1 class="text-4xl font-bold mb-2">{{ .Title }}</h1> <div class="text-gray-600 flex items-center gap-4"> <time datetime="{{ .Date.Format "2006-01-02" }}"> {{ .Date.Format "2 January 2006" }} </time> {{ with .Params.categories }} <span class="mx-2">β’</span> <div class="flex gap-2"> {{ range . }} <a href="{{ "/categories/" | relLangURL }}{{ . | urlize }}" class="text-blue-600 hover:underline"> {{ . }} </a> {{ end }} </div> {{ end }} </div> {{ if .Params.image }} <img src="{{ .Params.image }}" alt="{{ .Title }}" class="w-full h-64 object-cover rounded-lg mt-6"> {{ end }} </header><div class="content"> {{ .Content }} </div> <footer class="mt-12 pt-8 border-t"> {{ partial "author.html" . }} {{ partial "share-buttons.html" . }} </footer></article>
{{ end }}Template ini menggunakan beberapa fitur penting Hugo.
{{ .Title }}mengambil judul dari frontmatter halaman.{{ .Content }}merender konten markdown menjadi HTML.{{ .Params.field }}mengakses field custom di frontmatter.withconditionals digunakan untuk memeriksa keberadaan data sebelum merendernya, menghindari error saat data tidak tersedia.Mengakses Data dari Frontmatter
Frontmatter adalah metadata yang didefinisikan di awal setiap file konten dalam format YAML, TOML, atau JSON. Template Hugo dapat mengakses semua field frontmatter melalui
.Paramsobject. Berikut adalah contoh frontmatter dan cara mengaksesnya di template:--- title: "Tutorial Hugo untuk Pemula" date: 2026-02-03T09:00:00.000Z lastmod: 2026-02-03T09:00:00.000Z draft: false image: /img/hugo/tutorial.webp description: "Panduan lengkap belajar Hugo untuk pemula" categories: - Hugo - Web Development tags: - tutorial - beginners author: name: "John Doe" email: "[email protected]" ---Di template, Anda dapat mengakses field-field ini dengan
.Params.title,.Params.categories,.Params.author.name, dan sebagainya. Untuk field standar seperti title, date, dan draft, Anda juga dapat mengakses langsung dengan.Title,.Date, dan.Draft.Template List: Menampilkan Kumpulan Konten
Template
list.htmldigunakan untuk menampilkan kumpulan konten, seperti homepage, halaman section, halaman kategori, atau halaman tag. Template ini memiliki akses ke objek page collection yang memungkinkan iterasi dan menampilkan daftar halaman.Homepage (index.html)
Homepage adalah halaman utama website dan biasanya menampilkan daftar konten terbaru atau featured content. Berikut contoh implementasi:
{{ define "main" }} <section class="hero mb-12"> <h1 class="text-5xl font-bold mb-4">{{ .Title }}</h1> {{ with .Description }} <p class="text-xl text-gray-600">{{ . }}</p> {{ end }} </section><section class="featured-posts mb-12"> <h2 class="text-3xl font-bold mb-6">Artikel Terbaru</h2> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> {{ range first 6 (where .Site.RegularPages "Section" "notes") }} {{ partial "post-card.html" . }} {{ end }} </div> </section>
{{ end }}
Halaman Section dan Kategori
Untuk halaman section atau kategori, Anda dapat menggunakan template
list.htmldi folder yang sesuai. Misalnya, untuk sectionblog, buatlayouts/blog/list.html. Template ini dapat difilter berdasarkan section:{{ define "main" }} <header class="mb-8"> <h1 class="text-4xl font-bold">{{ .Title }}</h1> {{ with .Description }} <p class="text-gray-600 mt-2">{{ . }}</p> {{ end }} </header><div class="posts-grid"> {{ range .Paginator.Pages }} {{ partial "post-card.html" . }} {{ end }} </div>
{{ template "_internal/pagination.html" . }} {{ end }}
.Paginator.Pagesmenyediakan halaman-halaman yang sudah dipaginasi, dan template pagination default dapat ditambahkan dengan{{ template "_internal/pagination.html" . }}.Partials: Komponen Template yang Dapat Digunakan Kembali
Partials adalah template fragment yang dapat diinclude ke dalam template lain. Mereka sangat berguna untuk komponen yang digunakan berulang-ulang di seluruh website, seperti header, footer, navigation, dan widget-sidebar. Partials disimpan di folder
layouts/partials/dan dipanggil dengan fungsipartial.Membuat Partial Header
{{/* layouts/partials/header.html */}} <header class="site-header"> <nav class="navbar"> <a href="/" class="logo"> <img src="{{ .Site.Params.logo }}" alt="{{ .Site.Title }}"> </a><ul class="nav-menu"> {{ range .Site.Menus.main }} <li class="nav-item"> <a href="{{ .URL }}" class="nav-link{{ if $.IsMenuCurrent "main" . }} active{{ end }}"> {{ .Name }} </a> </li> {{ end }} </ul><div class="nav-actions">
{{ partial "search-form.html" . }}
{{ partial "theme-toggle.html" . }}
</div>
</nav>
</header>Memanggil Partial dari Template
Untuk menggunakan partial di template lain, gunakan fungsi
partial:{{ partial "header.html" . }}Titik (
.) di akhir adalah context yang passed ke partial, memungkinkan partial mengakses semua data halaman yang memanggilnya. Ini sangat penting karena memungkinkan partial untuk menjadi dinamis berdasarkan halaman yang sedang ditampilkan.Best Practices untuk Partials
Beberapa best practices dalam menggunakan partials: pertama, gunakan naming convention yang konsisten seperti
component-name.html. Kedua, pertahankan partial tetap kecil dan focused pada satu tanggung jawab. Ketiga, gunakan parameter untuk membuat partial yang fleksibel. Keempat, organize partials dalam subfolder berdasarkan fungsi untuk proyek besar.Fungsi dan Method Hugo Templates
Hugo menyediakan banyak fungsi dan method yang powerful untuk memanipulasi data dan logika di template. Pemahaman tentang fungsi-fungsi ini akan membuat template Anda lebih powerful dan efisien.
Fungsi Iterasi dan Conditionally
{{ range $index, $element := .Site.RegularPages }} <article class="post-{{ add $index 1 }}"> <h2>{{ $element.Title }}</h2> </article> {{ end }}{{ if and (.Params.featured) (gt (len .Params.tags) 0) }} <div class="featured-badge">Featured</div> {{ else if eq .Params.status "draft" }} <span class="draft-badge">Draft</span> {{ end }}
Fungsi String Manipulation
{{ .Title | truncate 50 "..." }} {{ .Content | plainify | truncate 200 }} {{ .Params.tags | intersect (slice "tutorial" "hugo") }} {{ range .Params.categories | first 3 }} <span class="category">{{ . }}</span> {{ end }}Fungsi URL dan Path
{{ .Permalink }} {{ .RelPermalink }} {{ .URL | absLangURL }} {{ "images/logo.png" | relURL }} {{ "assets/css/style.css" | resources.Get | minify | fingerprint }}Kesimpulan
Sistem templating Hugo adalah sistem yang powerful namun membutuhkan waktu untuk dipahami secara mendalam. Dalam tutorial ini, kita telah membahas fondasi penting mulai dari struktur folder layouts, template baseof sebagai fondasi halaman, template single untuk konten individual, template list untuk kumpulan konten, hingga penggunaan partials untuk komponen reusable. Dengan pemahaman ini, Anda sudah memiliki fondasi yang kuat untuk membangun website Hugo yang profesional dan mudah dipelihara.
Latihan terus-menerus dan eksplorasi template-template dari tema-tema open source akan membantu Anda semakin mahir dalam Hugo templating. Jangan takut untuk bereksperimen dengan fitur-fitur advanced seperti template hooks, render hooks, dan custom output formats saat Anda sudah nyaman dengan dasar-dasarnya.
Ditulis oleh
Hendra Wijaya