5
Sistem Layout dan Blok Nunjucks
Mazer merangkai setiap halaman dengan Nunjucks. Berkas di src/ berperan sebagai template anak, memilih satu layout induk lewat {% extends %}, lalu mengisi blok yang disediakan induk. Variabel global seperti sidebarItems, horizontalMenuItems, dan isDev disuntikkan plugin untuk setiap nama berkas HTML oleh getVariables (vite.config.js:28-401). Bentuk minimal pola ini terlihat di src/layout-default.html: {% set title %}, {% set filename %}, satu {% extends 'src/layouts/master.html' %}, lalu satu {% block content %} (src/layout-default.html:1-52).
Pewarisan antar layout
Enam layout di src/layouts/ berdiri sendiri; tidak ada layout yang meng-extends layout lain. master.html menyertakan sidebar dan footer sekaligus di dalam div#app (src/layouts/master.html:17-313). horizontal.html memakai kerangka berbeda: sidebar tidak dipanggil lewat include, dan konten berada di dalam div#main.layout-horizontal (src/layouts/horizontal.html:19-204).
graph TD
master["master.html"]
horizontal["horizontal.html"]
vnavbar["vertical-navbar.html"]
vone["vertical-1-column.html"]
auth["auth.html"]
error["error.html"]
sidebar["sidebar.html"]
footer["partials/footer.html"]
idx["index.html"]
ldef["layout-default.html"]
lhor["layout-horizontal.html"]
lvnav["layout-vertical-navbar.html"]
lvone["layout-vertical-1-column.html"]
login["auth-login.html"]
e404["error-404.html"]
idx --> master
ldef --> master
lhor --> horizontal
lvnav --> vnavbar
lvone --> vone
login --> auth
e404 --> error
master --> sidebar
master --> footer
vnavbar --> sidebar
vnavbar --> footer
style master fill:#f59e0b,color:#000
style horizontal fill:#f59e0b,color:#000
style vnavbar fill:#f59e0b,color:#000
style vone fill:#f59e0b,color:#000
style auth fill:#f59e0b,color:#000
style error fill:#f59e0b,color:#000
style sidebar fill:#2d7d46,color:#fff
style footer fill:#2d7d46,color:#fff
style idx fill:#8b5cf6,color:#fff
style ldef fill:#8b5cf6,color:#fff
style lhor fill:#8b5cf6,color:#fff
style lvnav fill:#8b5cf6,color:#fff
style lvone fill:#8b5cf6,color:#fff
style login fill:#8b5cf6,color:#fff
style e404 fill:#8b5cf6,color:#fff
%% fig: Pohon pewarisan layout dan partial
%% desc: Tujuh halaman contoh menunjuk induknya masing-masing, sedangkan master dan vertical-navbar memanggil partial sidebar dan footer lewat include.Peta di atas berasal dari baris {% extends %} di tiap halaman. src/index.html mendeklarasikan title, filename, extends, lalu mengisi block styles dan block content (src/index.html:1-105). Tabel berikut memuat pasangan yang dibaca langsung dari berkas.
| Layout induk | Halaman anak | Bukti baris extends |
|---|---|---|
src/layouts/master.html | src/index.html | src/index.html:1-105 |
src/layouts/master.html | src/layout-default.html | src/layout-default.html:1-52 |
src/layouts/horizontal.html | src/layout-horizontal.html | src/layout-horizontal.html:4-86 |
src/layouts/vertical-navbar.html | src/layout-vertical-navbar.html | src/layout-vertical-navbar.html:1-57 |
src/layouts/vertical-1-column.html | src/layout-vertical-1-column.html | src/layout-vertical-1-column.html:1-38 |
src/layouts/auth.html | src/auth-login.html | src/auth-login.html:1-49 |
src/layouts/error.html | src/error-404.html | src/error-404.html:1-310 |
src/layout-horizontal.html menaruh {% block styles %} sebelum {% extends %}, sehingga urutan deklarasi di template anak tidak harus mengikuti urutan induk (src/layout-horizontal.html:4-86).
Blok yang disediakan master.html
master.html mendefinisikan empat titik render. Dua di antaranya berada di <head>, satu membungkus isi halaman, dan satu menampung script halaman (src/layouts/master.html:1-4411).
| Blok | Titik render | Isi yang lazim |
|---|---|---|
stylesfirst | baris 8, sebelum assets/scss/app.scss (src/layouts/master.html:8-1312) | stylesheet yang harus dimuat paling awal |
styles | baris 13, setelah stylesheet tema (src/layouts/master.html:8-1312) | stylesheet tambahan per halaman |
content | baris 28, di dalam div#main (src/layouts/master.html:28-2913) | seluruh markup halaman |
js | baris 41, setelah app.js (src/layouts/master.html:32-4114) | script extension dan script halaman |
Hanya src/form-element-select.html yang mengisi stylesfirst di repository ini: blok itu memuat choices.css, dan blok js memuat choices.js beserta form-element-select.js (src/form-element-select.html:269-27515). Pemakaian js yang lebih umum terlihat di src/ui-chart-chartjs.html, yang memuat chart.umd.js dan ui-chartjs.js (src/ui-chart-chartjs.html:50-5316).
horizontal.html dan vertical-navbar.html mendefinisikan ulang ketiga blok <head> maupun stylesfirst, sehingga halaman anak pada kedua induk itu dapat mengisi blok yang sama (src/layouts/horizontal.html:8-1317). Satu perbedaan urutan: vertical-navbar.html menaruh {% block styles %} sebelum dua tautan favicon (src/layouts/vertical-navbar.html:8-1418).
Urutan render di dalam master.html
graph TD
init["initTheme.js"] --> app["div#app"]
app --> sidebar["include src/layouts/sidebar.html"]
app --> main["div#main"]
main --> burger["header .burger-btn"]
main --> content["block content"]
main --> footer["include ../partials/footer.html"]
app --> dark["components/dark.js"]
dark --> ps["perfect-scrollbar.min.js"]
ps --> appjs["app.js"]
appjs --> js["block js"]
style init fill:#f59e0b,color:#000
style app fill:#f59e0b,color:#000
style sidebar fill:#2d7d46,color:#fff
style footer fill:#2d7d46,color:#fff
style main fill:#8b5cf6,color:#fff
style burger fill:#8b5cf6,color:#fff
style content fill:#8b5cf6,color:#fff
style js fill:#8b5cf6,color:#fff
style dark fill:#336791,color:#fff
style ps fill:#336791,color:#fff
style appjs fill:#336791,color:#fff
%% fig: Urutan render body master.html
%% desc: initTheme.js jalan sebelum div#app, sidebar dan footer masuk lewat include, lalu script tema dan app.js dimuat sebelum block js.initTheme.js dimuat sebelum div#app supaya kelas tema sudah ada saat markup dirender (src/layouts/master.html:17-313). Sidebar di dalam div#app adalah hasil include "src/layouts/sidebar.html", yang mengulang sidebarItems dan menandai item aktif dengan filename|startsWith(sidebarItem.key) (src/layouts/sidebar.html:40-7419). Footer dipanggil sebagai include '../partials/footer.html', satu fragmen <footer> berisi teks hak cipta (src/partials/footer.html:1-1120). Setelah app.js, blok js menjadi tempat terakhir halaman menambah script (src/layouts/master.html:32-4114).
Berkas app.js yang dimuat bergantung pada isDev: assets/js/app.js dengan type="module" saat development, assets/compiled/js/app.js saat build (src/layouts/master.html:35-3921). Variabel itu diisi dari mode === 'development' di konfigurasi Vite (vite.config.js:28-401). Rincian siklus build ada di Alur Build Vite dan Nunjucks.
Perbedaan kerangka antar layout
| Layout | Titik render content | Footer | Script tambahan |
|---|---|---|---|
master.html | di dalam div#main (src/layouts/master.html:28-2913) | include ../partials/footer.html | dark.js, perfect-scrollbar |
horizontal.html | di dalam div.content-wrapper.container (src/layouts/horizontal.html:104-10622) | ditulis langsung di berkas | dark.js, horizontal-layout.js, perfect-scrollbar (src/layouts/horizontal.html:123-13123) |
vertical-navbar.html | di dalam div#main-content (src/layouts/vertical-navbar.html:121-12424) | include ../partials/footer.html | dark.js, perfect-scrollbar (src/layouts/vertical-navbar.html:127-13425) |
vertical-1-column.html | langsung di body (src/layouts/vertical-1-column.html:24-2926) | tidak ada | hanya app.js |
auth.html | di dalam div#auth (src/layouts/auth.html:17-1927) | tidak ada | tidak ada |
error.html | di dalam div#error (src/layouts/error.html:16-1828) | tidak ada | tidak ada |
horizontal.html juga menyusun navbar dari horizontalMenuItems, dengan maxSubmenuItemY = 8 sebagai pembatas jumlah item per grup submenu (src/layouts/horizontal.html:56-9729). Struktur data kedua menu itu dibahas di Data Navigasi Sidebar dan Menu Horizontal.
Layout minimal tanpa sidebar
auth.html dan error.html hanya menyediakan block content, sehingga halaman anak seperti src/auth-login.html dan src/error-404.html hanya mengisi satu blok itu (src/auth-login.html:1-49). Keduanya juga memuat stylesheet halaman khusus: pages/auth.scss (src/layouts/auth.html:17-1927) dan pages/error.scss (src/layouts/error.html:8-1130).
⚠️
error.htmltidak memuatassets/scss/themes/dark/app-dark.scss, hanyaapp.scssdanpages/error.scss. Halaman error karena itu tidak mengikuti tema gelap yang dimuat halaman ber-master.html(src/layouts/error.html:8-1130).
vertical-1-column.html berada di tengah: ia menyediakan block content dan tidak memanggil sidebar maupun footer, tetapi tetap memuat initTheme.js dan app.js (src/layouts/vertical-1-column.html:24-2926). Karena tombol tema berada di sidebar.html, halaman dengan layout ini tidak memiliki kontrol tema di dalam markup-nya (src/layouts/sidebar.html:40-7419). Mekanisme tema itu sendiri dijelaskan di Mode Gelap dan Persistensi Tema.