Architecture Portfolio JBake - Vision et Use Cases
Опубликовано 15 January 2026
Архитектурное видение
руководящий принцип
Архитектура основана на принципе разделения ответственности :
-
Содержание : структурированные файлы AsciiDoc с богатыми метаданными
-
Презентация : повторно используемые шаблоны Thymeleaf
-
Данные: модель автоматически извлечённая JBake из атрибутов AsciiDoc
-
Style : Bootstrap 5 для визуальной согласованности
Стратегический выбор: AsciiDoc для портфолио
| Критерий | Преимущество |
|---|---|
Согласованность |
Тот же формат, что и у статей в блоге |
Метаданные |
Структурированные и расширяемые атрибуты ( |
поддерживаемость |
Простой текстовый редактор, совместимый с Git |
Гибкость |
Может содержать богатый контент (таблицы, код, изображения) |
Шаблонизация |
JBake автоматически извлекает атрибуты для Thymeleaf |
Модель данных
Каждый проект-портфолио — это документ AsciiDoc с :
-
Метаданные заголовка : структурированная информация (клиент, продолжительность, технологии и т.д.)
-
Тело документа : описание повествования, проблемы, решения, результаты
-
Пользовательские атрибуты : с префиксом`project-*`для автоматического извлечения
@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
class ProjetAsciiDoc {
+titre: String
+jbake-type: "project"
+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 "Éditeur\nTexte" as editor participant "Fichier\nAsciiDoc" as file participant "JBake\nEngine" as jbake participant "Site\nStatique" 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 "Système\nFichiers" as fs participant "JBake\nEngine" as jbake participant "Site\nStatique" 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
Альтернативная стратегия: архивирование
Вместо постоянного удаления, возможность создать папку`content/portfolio/archive/`:
-
Переместить файл вместо его удаления
-
Позволяет легко восстановить
-
Сделай историю Git более ясной
Очистка ресурсов
-
Проверить осиротевшие изображения в`assets/img/portfolio/`
-
Удалить изображения, не используемые другими проектами
-
Очистить кэш JBake, чтобы избежать фантомных ссылок
UC3 : Установить в неопубликованный (черновик)
Номинальный поток
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "Fichier\nAsciiDoc" as file participant "JBake\nEngine" as jbake participant "Site\nStatique" 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 "Templates Thymeleaf" {
component [index.html] as index
component [portfolio.html] as portfolio
component [project.html] as project
package "Partials" {
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 "Données JBake" {
database "published_projects" as data
database "content (projet)" 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: Acme Corp") 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`)
-
Шаблоны : функциональное имя (пример:`project-card.html`,
tech-badge.html)
Рабочий процесс публикации
Конвейер разработки
@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
class ProjetAsciiDoc {
+titre: String
+jbake-type: "project"
+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-*`(Empty output)
-
project-awards: Награды и признания -
project-testimonial: Цитата клиента -
`project-team-size`Размер команды
-
project-budget-range: Бюджетный диапазон
Эти атрибуты автоматически становятся доступными в шаблонах без изменения движка JBake.
Расширенная категоризация
@startuml
skinparam backgroundColor #FEFEFE
object Projet {
project-category = "web"
project-subcategory = "ecommerce"
project-industry = "retail"
project-complexity = "high"
}
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 : полное отслеживание изменений
Управление контентом
-
Статус draft по умолчанию : публиковать только когда готов
-
Обзор перед публикацией : проверка качества и конфиденциальности
-
Полные метаданные : заполнить все соответствующие поля
-
Богатый нарративный контент : не ограничивайтесь метаданными
Производительность
-
Оптимизировать изображения : сжатие перед коммитом
-
Пагинация при необходимости : если >20 проектов
-
Lazy loading : изображения галерей, загружаемые по требованию
-
Кеш браузера : подходящие заголовки для assets
Заключение
Эта архитектура позволяет :
-
Простота использования : добавить проект = создать текстовый файл
-
Гибкость : расширяется за счёт новых атрибутов
-
Поддерживаемость : разделение содержимого и представления
-
Трассируемость : полное версионирование Git
-
Автоматизация : возможна непрерывная сборка и развертывание
Выбор AsciiDoc обеспечивает согласованность с остальной частью сайта, одновременно предоставляя богатство метаданных, необходимое для профессионального портфолио.