建築的ビジョン

指導原理

アーキテクチャは、*関心の分離*という原則に基づいています :

  • Contenu : 構造化されたAsciiDocファイル(メタデータが豊富)

  • プレゼンテーション : テンプレート Thymeleaf 再利用可能

  • データ : JBake によって AsciiDoc の属性から自動抽出されたモデル

  • Style : ビジュアルの一貫性のための Bootstrap 5

戦略的な選択 : ポートフォリオ用のAsciiDoc

なぜ AsciiDoc ですか?

基準 利点

整合性

ブログ記事と同じフォーマット

メタデータ

構造化および拡張可能な属性 (project-*)

保守性

シンプルなテキスト編集、Gitでバージョン管理可能

�柔軟性

�豊富なコンテンツ(表、コード、画像)を含むことがあります

テンプレーティング

JBakeは自動的にThymeleafの属性を抽出します

データモデル

各ポートフォリオプロジェクトはAsciiDocドキュメントです:

  • ヘッダーのメタデータ : 構造化された情報 (クライアント, 期間, テクノロジー, など)

  • ドキュメント本文 : ナラティブな説明, 課題, 解決策, 結果

  • カスタム属性 : プレフィックス付き`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 "編集者
テキスト" as editor
participant "ファイル
AsciiDoc" as file
participant "JBake\nエンジン" 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 "サイト\n静的" 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

典型的な使用例

  • 作成中のプロジェクト : ドラフトで作成し、準備ができたら公開する

  • Projet confidentiel temporairement : 顧客の合意が得られるまでドラフト状態に保つ

  • 主要アップデート : ドラフトに切り替え、編集し、再公開

  • 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, リアクト") 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)

  • テンプレート : 機能的な名前 (例:`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

環境

環境 使用 受け入れられたステータス

ローカル

開発とプレビュー

下書き, 公開済み

ステージング

本番前検証

publishedのみ

生産

公共サイト

公開済みのみ

拡張性

新しい属性の追加

データモデルを充実させるには、単純にプレフィックス付きの新しい属性を追加`project-*`:

  • `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

ベストプラクティス

ファイルの整理

  • 1 ファイル = 1 プロジェクト : 複数のプロジェクトを混ぜないでください

  • 専用フォルダ内の画像assets/img/portfolio/nom-projet/

  • 一貫した命名規則 : 検索と保守を容易にする

  • Versioning Git : 変更の完全な追跡

コンテンツ管理

  • デフォルトの下書きステータス : 公開するのは準備ができたときだけ

  • 公開前レビュー : 品質と機密性の確認

  • 完全なメタデータ : すべての関連フィールドを入力してください

  • 豊かなナラティブコンテンツ : メタデータに限定しない

パフォーマンス

  • 画像を最適化 : コミット前の圧縮

  • 必要に応じたページネーション : 20プロジェクト以上の場合

  • Lazy loading : ギャラリーの画像は必要に応じて読み込まれます

  • ブラウザキャッシュ : アセット用の適切なヘッダー

結論

このアーキテクチャは次のことを許可します :

  • 使いやすさ : プロジェクトを追加 = テキストファイルを作成

  • 柔軟性 : 新しい属性を通じて拡張可能

  • 保守性 : コンテンツとプレゼンテーションの分離

  • トレーサビリティ : Gitの完全なバージョン管理

  • 自動化 : ビルドとデプロイの継続的な可能性

AsciiDocの選択は、サイトの他の部分との一貫性を保ちながら、プロフェッショナルなポートフォリオに必要なメタデータの豊かさを提供します。

関連記事