Arsitektur Portofolio JBake - Vision dan Kasus Penggunaan
Diterbitkan 15 January 2026
Visi Arkitektonik
Prinsip pedoman
Arsitektur didasarkan pada prinsip pemisahan perhatian :
-
Konten : file AsciiDoc terstruktur dengan metadata kaya
-
Presentasi : templates Thymeleaf yang dapat digunakan kembali
-
Data : model diekstrak otomatis oleh JBake dari atribut AsciiDoc
-
Gaya : Bootstrap 5 untuk konsistensi visual
Pilihan strategis : AsciiDoc untuk portofolio
| kriteria | keuntungan |
|---|---|
Konsistensi |
Format yang sama dengan artikel blog |
metadata |
Atribut terstruktur dan dapat diperluas`project-*`) |
Kemudahan pemeliharaan |
Pengeditan teks sederhana, dapat di-versi dengan Git |
fleksibilitas |
Mungkin mengandung konten kaya (tabel, kode, gambar) |
pembuatan template |
JBake mengekstrak secara otomatis atribut untuk Thymeleaf |
Model data
Setiap proyek portofolio adalah dokumen AsciiDoc dengan :
-
Metadata header : informasi terstruktur (klien, durasi, teknologi, dll)
-
Badan dokumen : deskripsi naratif, tantangan, solusi, hasil
-
Atribut kustom : berawalan`project-*`untuk ekstraksi otomatis
@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
class ProjetAsciiDoc {
+titre: String
+jbake-type: "proyek"
+jbake-status: published|draft
+jbake-date: Date
+jbake-tags: List<String>
--
+project-category: String
+project-client: String
+project-duration: String
+project-role: String
+project-thumbnail: String
+project-gallery: List<String>
+project-tech-stack: String
+project-highlights: List<String>
+project-demo-url: String
+project-github-url: String
--
+body: HTML (converti)
}
class JBakeEngine {
+parse(asciidoc)
+extractMetadata()
+convertToHTML()
}
class ThymeleafTemplate {
+portfolio.html
+project.html
+partials/project-card.html
}
class PortfolioPage {
+published_projects: List
+filtres: categories
}
ProjetAsciiDoc --> JBakeEngine : parse
JBakeEngine --> ThymeleafTemplate : fournit données
ThymeleafTemplate --> PortfolioPage : génère
@enduml
Use Cases Rinci
UC1 : Menambahkan sebuah elemen ke dalam portofolio
Aliran nominal
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "Editor Teks" as editor participant "File AsciiDoc" as file participant "JBake\nmesin" as jbake participant "Situs\nStatis" as site dev -> editor : Créer nouveau fichier activate editor editor -> file : portfolio/nouveau-projet.adoc activate file dev -> editor : Rédiger en-tête avec métadonnées\n(titre, type=project, status=published,\nattributs project-*) dev -> editor : Rédiger contenu narratif\n(contexte, défis, solutions) dev -> editor : Ajouter images dans assets/img/portfolio/ editor -> file : Sauvegarder deactivate editor dev -> jbake : Lancer build (jbake -b) activate jbake jbake -> file : Lire et parser jbake -> jbake : Extraire métadonnées jbake -> jbake : Convertir AsciiDoc → HTML jbake -> jbake : Appliquer template project.html jbake -> jbake : Ajouter à la liste portfolio.html jbake -> site : Générer pages statiques deactivate jbake dev -> site : Vérifier résultat activate site site --> dev : Afficher projet deactivate site @enduml
Template file yang akan dibuat
Pengembang membuat`content/portfolio/nom-projet.adoc`dengan struktur yang terstandar :
-
Header dengan semua atribut yang diperlukan
-
Sections terstandar (Konteks, Tantangan, Solusi, Hasil)
-
Penamaan gambar yang konsisten
Poin validasi
-
Atribut yang diperlukan ada (
jbake-type,jbake-status,project-thumbnail) -
Gambar yang dirujuk ada di`assets/img/portfolio/`
-
Build JBake berhasil tanpa kesalahan
-
Proyek muncul di halaman portofolio
-
Halaman individual proyek ditampilkan dengan benar
UC2 : Menghapus sebuah elemen dari portofolio
fluks nominal
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "Sistem File" as fs participant "JBake Engine" as jbake participant "Situs\nStatis" as site database "Cache\nJBake" as cache dev -> fs : Supprimer portfolio/projet-ancien.adoc activate fs fs --> dev : Fichier supprimé deactivate fs dev -> fs : (Optionnel) Supprimer images associées\nassets/img/portfolio/projet-ancien-* activate fs fs --> dev : Images supprimées deactivate fs dev -> cache : Nettoyer cache JBake activate cache cache --> dev : Cache vidé deactivate cache dev -> jbake : Rebuild complet (jbake -b) activate jbake jbake -> jbake : Scanner content/portfolio/ jbake -> jbake : Projet absent → non généré jbake -> jbake : Régénérer portfolio.html\n(sans le projet supprimé) jbake -> site : Déployer nouveau build deactivate jbake dev -> site : Vérifier activate site site --> dev : Projet absent de la liste deactivate site @enduml
Strategi alternatif: pengarsipan
Alih-alih menghapus secara permanen, ada kemungkinan untuk membuat folder`content/portfolio/archive/`(Empty output)
-
Pindahkan file alih-alih menghapusnya
-
Memudahkan pemulihan
-
Jaga riwayat Git lebih jelas
Pembersihan sumber daya
-
Memeriksa gambar yatim di`assets/img/portfolio/`
-
Hapus gambar yang tidak dirujuk oleh proyek lain
-
Membersihkan cache JBake untuk menghindari referensi hantu
UC3 : Menetapkan sebagai tidak dipublikasikan (draft)
Fluks nominal
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "File AsciiDoc" as file participant "JBake\nMesin" as jbake participant "Site Statis" as site dev -> file : Ouvrir portfolio/projet.adoc activate file dev -> file : Modifier attribut\n:jbake-status: published\n↓\n:jbake-status: draft file --> dev : Sauvegardé deactivate file dev -> jbake : Rebuild (jbake -b) activate jbake jbake -> file : Parser le fichier jbake -> jbake : Détecter status=draft jbake -> jbake : Exclure de published_projects jbake -> jbake : Ne pas créer page publique note right Le projet existe toujours mais n'est pas publié end note jbake -> site : Générer site (sans ce projet) deactivate jbake dev -> site : Vérifier portfolio activate site site --> dev : Projet absent de la liste publique deactivate site @enduml
status yang mungkin
@startuml skinparam backgroundColor #FEFEFE [*] --> Draft : Création initiale Draft --> Published : Validation et publication Published --> Draft : Retrait temporaire Draft --> Archived : Projet abandonné Published --> Archived : Projet obsolète Archived --> [*] : Suppression définitive Published --> Published : Mises à jour note right of Draft :jbake-status: draft Non visible publiquement Utile pour projets en cours end note note right of Published :jbake-status: published Visible sur le portfolio Indexé par JBake end note note right of Archived Déplacé dans archive/ ou jbake-status: archived Non publié mais conservé end note @enduml
Kasus penggunaan tipikal
-
Proyek yang sedang dalam proses penulisan : membuat sebagai draft, publikasikan ketika sudah selesai
-
Proyek rahasia sementara : beralih ke draft sampai persetujuan klien
-
Pembaruan besar : beralih ke draft, mengedit, menerbitkan kembali
-
A/B testing : duplikasi dalam draft, uji, terbitkan versi terbaik
Arsitektur Templating
Strategi template yang dapat digunakan kembali
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Template Thymeleaf" {
component [index.html] as index
component [portfolio.html] as portfolio
component [project.html] as project
package "parsial" {
component [header.html] as header
component [footer.html] as footer
component [project-card.html] as card
component [tech-badge.html] as badge
component [gallery.html] as gallery
}
}
package "Data JBake" {
database "proyek_dipublikasikan" as data
database "(proyek)" as content
}
index --> header
index --> footer
portfolio --> header
portfolio --> footer
portfolio --> card
data --> portfolio : itération
project --> header
project --> footer
project --> badge
project --> gallery
content --> project : projet individuel
note right of card
Fragment réutilisable
pour afficher une carte
de projet avec :
- thumbnail
- titre
- tags
- highlights
end note
@enduml
Pola ekstraksi data
JBake secara otomatis mengubah atribut AsciiDoc menjadi properti yang dapat diakses di Thymeleaf :
@startuml
skinparam backgroundColor #FEFEFE
rectangle "Dokumen AsciiDoc" {
(":project-client: Acme Corp") as attr1
(":project-duration: 6 bulan") as attr2
(":project-tags: java, react") as attr3
}
rectangle "Model JBake" {
(content['project-client']) as prop1
(content['project-duration']) as prop2
(content.tags) as prop3
}
rectangle "Template Thymeleaf" {
(th:text="${project['project-client']}") as tmpl1
(th:text="${project['project-duration']}") as tmpl2
(th:each="tag : ${project.tags}") as tmpl3
}
attr1 --> prop1 : parsing
attr2 --> prop2 : parsing
attr3 --> prop3 : parsing
prop1 --> tmpl1 : binding
prop2 --> tmpl2 : binding
prop3 --> tmpl3 : binding
@enduml
Konvensi penamaan
-
Atribut proyek : awalan`project-*` (ex:
project-client,project-tech-stack) -
Berkas : kebab-case (ex:`ecommerce-platform.adoc`)
-
Images : awalan nama-proyek (contoh:`ecommerce-platform-thumb.jpg`)
-
Templates : nama fungsional (contoh:`project-card.html`,
tech-badge.html)
Alur Kerja Publikasi
Alur pengembangan
@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
class ProjetAsciiDoc {
+titre: String
+jbake-type: "proyek"
+jbake-status: published|draft
+jbake-date: Date
+jbake-tags: List<String>
__
+project-category: String
+project-client: String
+project-duration: String
+project-role: String
+project-thumbnail: String
+project-gallery: List<String>
+project-tech-stack: String
+project-highlights: List<String>
+project-demo-url: String
+project-github-url: String
__
+body: HTML (converti)
}
class JBakeEngine {
+parse(asciidoc)
+extractMetadata()
+convertToHTML()
}
class ThymeleafTemplate {
+portfolio.html
+project.html
+partials/project-card.html
}
class PortfolioPage {
+published_projects: List
+filtres: categories
}
ProjetAsciiDoc --> JBakeEngine : parse
JBakeEngine --> ThymeleafTemplate : fournit données
ThymeleafTemplate --> PortfolioPage : génère
@enduml
lingkungan
| Lingkungan | Penggunaan | Status diterima |
|---|---|---|
lokal |
Pengembangan dan pratinjau |
draft, diterbitkan |
penataan |
Validasi pra-produksi |
diterbitkan hanya |
Produksi |
Situs publik |
diterbitkan hanya |
ekstensibilitas
Penambahan atribut baru
Untuk memperkaya model data, cukup menambahkan atribut baru yang diawali`project-*`:
-
`project-awards`Harga dan Penghargaan
-
project-testimonial: Kutipan klien -
project-team-size: Ukuran tim -
project-budget-range: jangka anggaran
Atribut-atribut ini secara otomatis tersedia di dalam template tanpa modifikasi mesin JBake.
Kategorisasi lanjutan
@startuml
skinparam backgroundColor #FEFEFE
object Projet {
project-category = "web"
project-subcategory = "perdagangan elektronik"
project-industry = "ritel"
project-complexity = "tinggi"
}
object Taxonomie {
categories : [web, mobile, data, devops]
subcategories : Map<category, List>
industries : [retail, finance, healthcare, ...]
complexities : [low, medium, high]
}
Projet --> Taxonomie : classifié selon
note right of Taxonomie
Permet filtrage multi-critères
dans le template portfolio.html
via JavaScript ou côté serveur
end note
@enduml
Praktik Baik
Organisasi file
-
Satu file = satu proyek : hindari mencampurkan beberapa proyek
-
Gambar di folder khusus :`assets/img/portfolio/nom-projet/`
-
Nomenklatur konsisten : memudahkan pencarian dan pemeliharaan
-
Versioning Git : pelacakan lengkap perubahan
Manajemen konten
-
Status draft secara default : hanya menerbitkan ketika siap
-
Tinjauan sebelum publikasi : validasi kualitas dan kerahasiaan
-
Metadata lengkap : mengisi semua kolom yang relevan
-
Konten naratif kaya: tidak membatasi diri pada metadata
kinerja
-
Mengoptimalkan gambar : kompresi sebelum commit
-
Pagination yang diperlukan : jika >20 proyek
-
Lazy loading : gambar galeri yang dimuat saat diperlukan
-
Cache peramban : header yang sesuai untuk aset
Kesimpulan
Arsitektur ini memungkinkan:
-
Kemudahan penggunaan : menambahkan proyek = membuat file teks
-
Kefleksibilitas : dapat diperluas melalui atribut baru
-
Kemudahan pemeliharaan : pemisahan konten/presentasi
-
pelacakan : versioning Git lengkap
-
Otomatisasi : pembangunan dan penyebaran kontinu mungkin
Pemilihan AsciiDoc menjamin konsistensi dengan sisanya situs sambil memberikan kekayaan metadata yang diperlukan untuk portofolio profesional.