건축 비전

주도 원칙

아키텍처는 관심사의 분리 원리에 기반을 두고 있습니다 :

  • Contenu : 풍부한 메타데이터가 포함된 구조화된 AsciiDoc 파일

  • 소개 : 재사용 가능한 Thymeleaf 템플릿

  • 데이터 : JBake에 의해 AsciiDoc 속성에서 자동으로 추출된 모델

  • 스타일 : Bootstrap 5를 시각적 일관성을 위해

전략적 선택 : 포트폴리오를 위한 AsciiDoc

Table 1. 왜 아스키독?
기준 장점

일관성

블로그 글과 같은 형식

메타데이터

구조화된 및 확장 가능한 속성 (project-*)

유지보수성

간단한 텍스트 편집, Git 버전 관리 가능

유연성

풍부한 콘텐츠(표, 코드, 이미지)를 포함할 수 있습니다.

템플릿화

JBake은 Thymeleaf용 속성을 자동으로 추출합니다.

데이터 모델

각 포트폴리오 프로젝트는 다음과 같은 AsciiDoc 문서입니다:

  • 헤더 메타데이터 : 구조화된 정보(클라이언트, 기간, 기술 등)

  • 문서 본문 : 서술적 설명, 도전 과제, 해결책, 결과

  • s용자 정의 속성 : 접두사가 된`project-*`자동 추출을 위해

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false

class ProjetAsciiDoc {
  +titre: String
  +jbake-type: "프로젝트"
  +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

상세한 사용 사례

UC1 : 포트폴리오에 항목 추가

정상 흐름

@startuml
skinparam backgroundColor #FEFEFE
actor Développeur as dev
participant "편집기\n텍스트" as editor
participant "파일
AsciiDoc" as file
participant "JBake
엔진" as jbake
participant "사이트
정적" 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

생성할 파일의 템플릿

개발자는 만든다`content/portfolio/nom-projet.adoc`표준화된 구조와 함께 :

  • 필수 속성을 모두 갖춘 헤더

  • 표준화된 섹션 (컨텍스트, 도전, 솔루션, 결과)

  • 일관된 이미지 명명법

검증 포인트

  • 필수 속성이 존재합니다 (jbake-type, jbake-status, project-thumbnail)

  • 참조된 이미지는 에 존재합니다.assets/img/portfolio/

  • JBake 빌드가 오류 없이 성공합니다

  • 포트폴리오 페이지에 프로젝트가 나타납니다

  • 개별 프로젝트 페이지가 올바르게 표시됩니다

UC2 : 포트폴리오에서 항목 삭제

명목 플럭스

@startuml
skinparam backgroundColor #FEFEFE
actor Développeur as dev
participant "시스템
파일" as fs
participant "JBake
엔진" as jbake
participant "사이트
정적" as site
database "캐시
JBake" 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

대체 전략: 아카이빙

영구적으로 삭제하는 대신, 폴더를 만들 수 있는 가능성`content/portfolio/archive/`:

  • 파일을 삭제하는 대신 이동하세요

  • 쉽게 복원할 수 있습니다

  • Git 기록을 더 명확하게 유지합니다

리소스 정리

  • 고아 이미지 확인`assets/img/portfolio/`

  • 다른 프로젝트에 참조되지 않은 이미지 삭제

  • JBake 캐시를 정리하여 유령 참조를 방지하기

UC3 : 비공개(초안)로 설정

명목 흐름

@startuml
skinparam backgroundColor #FEFEFE
actor Développeur as dev
participant "파일\nAsciiDoc" as file
participant "JBake\n엔진" as jbake
participant "정적
사이트" 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

가능한 상태

@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

일반적인 사용 사례

  • 작성 중인 프로젝트 : 드래프트로 만들고, 준비가 되면 게시

  • 임시 기밀 프로젝트 : 클라이언트 승인 동안 초안으로 전환

  • 주요 업데이트 : 초안으로 전환, 수정, 다시 게시

  • A/B testing : 초안으로 복제해서 테스트하고, 가장 좋은 버전 공개

템플릿 아키텍처

재사용 가능한 템플릿 전략

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Thymeleaf 템플릿" {
  component [index.html] as index
  component [portfolio.html] as portfolio
  component [project.html] as project

  package "부분들" {
    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 "데이터 JBake" {
  database "게시된 프로젝트" as data
  database "내용 (프로젝트)" 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

데이터 추출 패턴

JBake은 AsciiDoc 속성을 자동으로 Thymeleaf에서 접근 가능한 속성으로 변환합니다 :

@startuml
skinparam backgroundColor #FEFEFE

rectangle "문서 AsciiDoc" {
  (":project-client: 애크미 코퍼레이션") as attr1
  (":project-duration: 6개월") as attr2
  (":project-tags: java, react") as attr3
}

rectangle "JBake 모델" {
  (content['project-client']) as prop1
  (content['project-duration']) as prop2
  (content.tags) as prop3
}

rectangle "템플릿 Thymeleaf" {
  (th:text="${project['project-client']}") as tmpl1
  (th:text="${project['project-duration']}") as tmpl2
  (th:each="태그 : ${project.tags}") as tmpl3
}

attr1 --> prop1 : parsing
attr2 --> prop2 : parsing
attr3 --> prop3 : parsing

prop1 --> tmpl1 : binding
prop2 --> tmpl2 : binding
prop3 --> tmpl3 : binding
@enduml

명명 규칙

  • 프로젝트 속성 : 접두사`project-*` (ex: project-client, project-tech-stack)

  • 파일 : kebab-case (예:`ecommerce-platform.adoc`)

  • Images : 프로젝트 이름 접두사 (예:`ecommerce-platform-thumb.jpg`)

  • Templates : 기능적 이름 (예:`project-card.html`, tech-badge.html)

출판 워크플로우

개발 파이프라인

@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false

class ProjetAsciiDoc {
  +titre: String
  +jbake-type: "프로젝트"
  +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

환경

환경 사용 수락된 상태

로컬

개발 및 미리보기

초안, 게시됨

스테이징

사전 제작 검증

게시된 것만

생산

공공 사이트

단독으로 게시됨

확장성

새로운 속성 추가

데이터 모델을 풍부하게 하기 위해, 단순히 새로운 접두사가 붙은 속성을 추가하면 됩니다.project-*[No output]

  • project-awards: 수상 및 인정

  • `project-testimonial`고객 인용

  • `project-team-size`팀 규모

  • project-budget-range: 예산 범위

이러한 속성은 JBake 엔진을 수정하지 않고도 템플릿에서 자동으로 사용할 수 있게 됩니다.

고급 분류

@startuml
skinparam backgroundColor #FEFEFE

object Projet {
  project-category = "웹"
  project-subcategory = "전자상거래"
  project-industry = "소매"
  project-complexity = "높은"
}

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

모범 사례

파일 구성

  • 파일 하나 = 프로젝트 하나 : 여러 프로젝트를 섞지 않도록 피하다

  • 전용 폴더의 이미지 :`assets/img/portfolio/nom-projet/`

  • 일관된 명명법 : 검색과 유지보수가 쉬워집니다

  • Versioning Git : 수정된 사항의 완전한 추적

콘텐츠 관리

  • 기본 초안 상태 : 준비됐을 때만 게시

  • 출판 전 검토 : 품질 및 기밀성 검증

  • 완전한 메타데이터 : 모든 관련 필드를 채우세요

  • 풍부한 서사 내용 : 메타데이터에만 국한되지 마라

성능

  • 이미지 최적화 : 커밋 전 압축

  • 필요한 경우 페이지네이션 : 프로젝트가 20개 이상이면

  • Lazy loading : 갤러리 이미지 필요 시 로드

  • 브라우저 캐시 : 자산에 대한 적절한 헤더

결론

이 아키텍처는 다음을 허용합니다 :

  • 간편함 : 프로젝트 추가 = 텍스트 파일 만들기

  • 유연성 : 새로운 속성을 통해 확장 가능

  • 유지보수성 : 내용과 표현의 분리

  • 추적성 : 완전한 Git 버전 관리

  • Automatisation : 빌드 및 연속적인 배포가 가능

AsciiDoc 선택은 사이트의 나머지와 일관성을 유지하면서 전문 포트폴리오에 필요한 풍부한 메타데이터를 제공한다.

관련 기사