11
Katalog Halaman dan Ekstensi
Setiap halaman demo Mazer adalah satu berkas .html di src/ yang meng-extends layout master, lalu menaruh pustaka pihak ketiga di {% block styles %} dan {% block js %}. Pustaka itu dibaca dari assets/extensions, sedangkan kode inisialisasi per halaman dibaca dari assets/static/js/pages. Halaman ini memetakan halaman demo ke dua direktori tersebut.
Kedua direktori itu bukan hasil tulisan tangan. modulesToCopy di vite.config.js:45-861 mendaftar modul npm yang disalin ke dest: 'assets/extensions' dengan rename: moduleName, sehingga node_modules/apexcharts/dist menjadi assets/extensions/apexcharts. Sementara itu seluruh isi src/assets/static disalin ke assets oleh target viteStaticCopy di vite.config.js:1162, sehingga src/assets/static/js/pages/quill.js tampil sebagai assets/static/js/pages/quill.js saat halaman berjalan.
graph TD
npm["node_modules (module)"] --> copy["copyModules, dest: assets/extensions"]
static["src/assets/static"] --> staticCopy["viteStaticCopy, dest: assets"]
copy --> ext["assets/extensions (nama modul)"]
staticCopy --> pages["assets/static/js/pages"]
ext --> blockJs["blok js dan styles di halaman demo"]
pages --> blockJs
blockJs --> runtime["halaman HTML hasil build"]
style npm fill:#336791,color:#fff
style ext fill:#8b5cf6,color:#fff
style pages fill:#8b5cf6,color:#fff
style copy fill:#f59e0b,color:#000
style staticCopy fill:#f59e0b,color:#000
style runtime fill:#2d7d46,color:#fff
%% fig: Jalur modul npm dan aset statis menjadi sumber blok js halaman
%% desc: Modul npm disalin ke assets/extensions, aset statis disalin ke assets/static, lalu keduanya dirujuk dari blok js dan styles tiap halaman demo.Peta halaman ke ekstensi dan skrip
Tabel berikut disusun dari blok styles dan js pada tiap berkas halaman. Kolom ekstensi memuat path relatif terhadap assets/extensions; kolom skrip memuat nama berkas di assets/static/js/pages.
| Halaman demo | Ekstensi di assets/extensions | Skrip di assets/static/js/pages |
|---|---|---|
ui-chart-apexcharts.html | dayjs/dayjs.min.js, apexcharts/apexcharts.min.js | ui-apexchart.js |
table-datatable.html | simple-datatables/umd/simple-datatables.js | simple-datatables.js |
table-datatable-jquery.html | jquery/jquery.min.js, datatables.net/js/jquery.dataTables.min.js, datatables.net-bs5/js/dataTables.bootstrap5.min.js | datatables.js |
form-editor-quill.html | quill/quill.snow.css, quill/quill.bubble.css, quill/quill.min.js | quill.js |
extra-component-glightbox.html | tidak memakai assets/extensions; GLightbox dimuat dari CDN jsdelivr | component-glightbox.js |
Baris pertama tabel berasal dari src/ui-chart-apexcharts.html:85-893, baris kedua dari src/table-datatable.html:285-2904, baris ketiga dari src/table-datatable-jquery.html:553-562, dan baris keempat dari src/form-editor-quill.html:71-78. Halaman-halaman itu sendiri terdaftar di src/sidebar-items.json sebagai Datatable dan Datatable (jQuery) pada grup Datatables (src/sidebar-items.json:234-253), dan pola yang sama berlaku untuk halaman widget seperti ui-widgets-todolist.html yang terdaftar di grup Widgets (src/sidebar-items.json:259-275).
Satu skrip halaman, satu jenis inisialisasi
Skrip di assets/static/js/pages selalu berupa kode yang menyiapkan satu pustaka pada elemen DOM yang sudah disediakan halaman. ui-apexchart.js membuat lima instance ApexCharts yang masing-masing diikat ke selektor #bar, #line, #candle, #radialGradient, dan #area, lalu memanggil render() pada tiap instance (src/assets/static/js/pages/ui-apexchart.js:508-5219). simple-datatables.js membuat new simpleDatatables.DataTable(document.getElementById("table1")) lalu menambal markup hasil render dengan kelas Bootstrap 5 lewat adaptPageDropdown dan adaptPagination (src/assets/static/js/pages/simple-datatables.js:1-5210). datatables.js mengikat #table1 dan #table2 dengan DataTable() jQuery, menambah pagination-primary pada setiap draw (src/assets/static/js/pages/datatables.js:1-2511).
graph LR
area["#area, #line, #bar, #candle, #radialGradient"] --> apex["ui-apexchart.js"]
apex --> apexInit["new ApexCharts, lalu render()"]
t1["#table1 di table-datatable.html"] --> sd["simple-datatables.js"]
sd --> sdInit["new simpleDatatables.DataTable"]
t12["#table1 dan #table2 di table-datatable-jquery.html"] --> dt["datatables.js"]
dt --> dtInit["$(...).DataTable dengan pagingType simple"]
style apex fill:#8b5cf6,color:#fff
style sd fill:#8b5cf6,color:#fff
style dt fill:#8b5cf6,color:#fff
style apexInit fill:#2d7d46,color:#fff
style sdInit fill:#2d7d46,color:#fff
style dtInit fill:#2d7d46,color:#fff
%% fig: Ikatan selektor DOM ke skrip inisialisasi per halaman
%% desc: Tiap id kontainer pada halaman demo diikat oleh satu skrip di assets/static/js/pages yang membangun instance pustaka terkait.Pola ini menjelaskan mengapa nama berkas skrip tidak selalu sama dengan nama halaman. Halaman table-datatable.html memakai simple-datatables.js, sedangkan table-datatable-jquery.html memakai datatables.js; keduanya mengikat id yang sama, #table1, tetapi dengan pustaka berbeda (src/table-datatable.html:285-2904 dan src/table-datatable-jquery.html:553-5625). Begitu pula extra-component-glightbox.html memanggil component-glightbox.js, tanpa awalan extra- (src/extra-component-glightbox.html:262-26912). Berkas itu sendiri memanggil GLightbox() untuk galeri utama dan GLightbox({...}) untuk varian dengan deskripsi (src/assets/static/js/pages/component-glightbox.js:114-11513).
⚠️
extra-component-glightbox.htmltidak mengambil apa pun dariassets/extensions. Berkas CSS dan JS-nya dimuat langsung daricdn.jsdelivr.net(src/extra-component-glightbox.html:262-26912), sehingga halaman itu gagal menampilkan lightbox saat build dijalankan tanpa jaringan. Halaman lain aman karena seluruh dependensinya ikut tersalin kedist.
Untuk memahami bagaimana {% block js %} di halaman demo digabung dengan layout, lihat Sistem Layout dan Blok Nunjucks. Untuk perintah build yang menghasilkan dist/assets/extensions, lihat Alur Build Vite dan Nunjucks.