Portafolio de Arquitectura JBake - Visión y Casos de Uso
Publicado el 15 January 2026
Visión Arquitectónica
Principio director
La arquitectura se basa en el principio de separación de preocupaciones :
-
Contenido : archivos AsciiDoc estructurados con metadatos ricos
-
Presentación : plantillas Thymeleaf reutilizables
-
Datos : modelo extraído automáticamente por JBake desde los atributos AsciiDoc
-
Estilo: Bootstrap 5 para la coherencia visual
Elección estratégica: AsciiDoc para el portafolio
| Criterio | Ventaja |
|---|---|
Coherencia |
Mismo formato que los artículos de blog |
Metadatos |
Atributos estructurados y extensibles ( |
mantenibilidad |
Edición simple en texto, versionable Git |
Flexibilidad |
Puede contener contenido rico (tablas, código, imágenes) |
Plantillado |
JBake extrae automáticamente los atributos para Thymeleaf |
Modelo de datos
Cada proyecto portfolio es un documento AsciiDoc:
-
Metadatos de encabezado : información estructurada (cliente, duración, tecnologías, etc.)
-
Cuerpo del documento : descripción narrativa, desafíos, soluciones, resultados
-
Atributos personalizados : prefijados`project-*`para la extracción automática
@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
class ProjetAsciiDoc {
+titre: String
+jbake-type: "proyecto"
+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 : analizar
JBakeEngine --> ThymeleafTemplate : proporciona datos
ThymeleafTemplate --> PortfolioPage : genera
@enduml
Casos de uso detallados
UC1 : Añadir un elemento al portafolio
Flujo nominal
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "Editor\nTexto" as editor participant "Archivo\nAsciiDoc" as file participant "JBake\nMotor" as jbake participant "Sitio\nEstático" as site dev -> editor : Crear nuevo archivo activate editor editor -> file : portfolio/nouveau-projet.adoc activate file dev -> editor : Redactar encabezado con metadatos\n(título, type=project, status=published,\natributos project-*) dev -> editor : Redactar contenido narrativo\n(contexto, desafíos, soluciones) dev -> editor : Agregar imágenes en assets/img/portfolio/ editor -> file : Guardar deactivate editor dev -> jbake : Ejecutar build (jbake -b) activate jbake jbake -> file : Leer y analizar jbake -> jbake : Extraer metadatos jbake -> jbake : Convertir AsciiDoc → HTML jbake -> jbake : Aplicar plantilla project.html jbake -> jbake : Añadir a la lista portfolio.html jbake -> site : Generar páginas estáticas deactivate jbake dev -> site : Verificar resultado activate site site --> dev : Mostrar proyecto deactivate site @enduml
Plantilla del archivo a crear
El desarrollador crea`content/portfolio/nom-projet.adoc`con una estructura estandarizada:
-
Encabezado con todos los atributos requeridos
-
Secciones normalizadas (Contexto, Desafíos, Soluciones, Resultados)
-
Nomenclatura coherente de las imágenes
Puntos de validación
-
Los atributos obligatorios están presentes(
jbake-type,jbake-status,project-thumbnail) -
Las imágenes referenciadas existen en`assets/img/portfolio/`
-
La compilación de JBake se ejecuta sin errores
-
El proyecto aparece en la página portfolio
-
La página individual del proyecto se muestra correctamente
UC2 : Eliminar un elemento del portafolio
Flujo nominal
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "Sistema\nArchivos" as fs participant "JBake\nMotor" as jbake participant "Sitio\nEstático" as site database "Caché\nJBake" as cache dev -> fs : Eliminar portfolio/projet-ancien.adoc activate fs fs --> dev : Archivo eliminado deactivate fs dev -> fs : (Opcional) Eliminar imágenes asociadas\nassets/img/portfolio/projet-ancien-* activate fs fs --> dev : Imágenes eliminadas deactivate fs dev -> cache : Limpiar caché JBake activate cache cache --> dev : Caché vaciado deactivate cache dev -> jbake : Reconstrucción completa (jbake -b) activate jbake jbake -> jbake : Escanear content/portfolio/ jbake -> jbake : Proyecto ausente → no generado jbake -> jbake : Regenerar portfolio.html\n(sin el proyecto eliminado) jbake -> site : Desplegar nuevo build deactivate jbake dev -> site : Verificar activate site site --> dev : Proyecto ausente de la lista deactivate site @enduml
Estrategia alternativa: archivado
En lugar de eliminar definitivamente, posibilidad de crear una carpeta`content/portfolio/archive/`:
-
Mover el archivo en lugar de eliminarlo
-
Permite restaurar fácilmente
-
Mantén el historial de Git más claro
Limpieza de recursos
-
Comprobar las imágenes huérfanas en`assets/img/portfolio/`
-
Eliminar las imágenes no referenciadas por otros proyectos
-
Limpiar el caché de JBake para evitar referencias fantasma
UC3: Establecer como no publicado (borrador)
flujo nominal
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "Archivo\nAsciiDoc" as file participant "JBake\nMotor" as jbake participant "Sitio\nEstático" as site dev -> file : Abrir portfolio/projet.adoc activate file dev -> file : Modificar atributo\n:jbake-status: published\n↓\n:jbake-status: draft file --> dev : Guardado deactivate file dev -> jbake : Reconstruir (jbake -b) activate jbake jbake -> file : Parsear el archivo jbake -> jbake : Detectar status=draft jbake -> jbake : Excluir de published_projects jbake -> jbake : No crear página pública note right El proyecto sigue existiendo pero no está publicado end note jbake -> site : Generar sitio (sin este proyecto) deactivate jbake dev -> site : Verificar portafolio activate site site --> dev : Proyecto ausente de la lista pública deactivate site @enduml
Estados posibles
@startuml skinparam backgroundColor #FEFEFE [*] --> Draft : Création initiale Draft --> Published : Validación y publicación Published --> Draft : Retiro temporal Draft --> Archived : Proyecto abandonado Published --> Archived : Proyecto obsoleto Archived --> [*] : Eliminación definitiva Published --> Published : Actualizaciones note right of Draft :jbake-status: borrador No visible públicamente Útil para proyectos en curso end note note right of Published :jbake-status: publicado Visible en el portafolio Indexado por JBake end note note right of Archived Movido a archive/ o jbake-status: archivado No publicado pero conservado end note @enduml
Casos de uso típicos
-
Proyecto en curso de redacción : crear en borrador, publicar cuando esté listo
-
Proyecto confidencial temporalmente : pasar a borrador mientras se llega al acuerdo con el cliente
-
Actualización importante: pasar a borrador, modificar, republicar
-
A/B testing : duplicar en borrador, probar, publicar la mejor versión
Arquitectura de plantillas
Estrategia de plantillas reutilizables
@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 "Datos JBake" {
database "published_projects" as data
database "content (proyecto)" as content
}
index --> header
index --> footer
portfolio --> header
portfolio --> footer
portfolio --> card
data --> portfolio : iteración
project --> header
project --> footer
project --> badge
project --> gallery
content --> project : proyecto individual
note right of card
Fragmento reutilizable
para mostrar una tarjeta
de proyecto con:
- thumbnail
- titre
- tags
- highlights
end note
@enduml
Pattern de extracción de datos
JBake transforma automáticamente los atributos de AsciiDoc en propiedades accesibles en Thymeleaf :
@startuml
skinparam backgroundColor #FEFEFE
rectangle "Documento AsciiDoc" {
(":project-client: Acme Corp") as attr1
(":project-duration: 6 meses") as attr2
(":project-tags: java, react") as attr3
}
rectangle "Modelo JBake" {
(content['project-client']) as prop1
(content['project-duration']) as prop2
(content.tags) as prop3
}
rectangle "Plantilla 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
Convenciones de nomenclatura
-
Atributos del proyecto : prefijo`project-*` (ex:
project-client,project-tech-stack) -
Archivos : kebab-case (ej:`ecommerce-platform.adoc`)
-
Imágenes : prefijo nombre-proyecto (ej:`ecommerce-platform-thumb.jpg`)
-
Plantillas : nombre funcional (ej:)
project-card.html,tech-badge.html)
Flujo de publicación
Pipeline de desarrollo
@startuml
skinparam backgroundColor #FEFEFE
skinparam handwritten false
class ProjetAsciiDoc {
+titre: String
+jbake-type: "proyecto"
+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 : analizar
JBakeEngine --> ThymeleafTemplate : proporciona datos
ThymeleafTemplate --> PortfolioPage : genera
@enduml
entornos
| Entorno | Uso | Estado aceptado |
|---|---|---|
Local |
Desarrollo y preview |
borrador, publicado |
puesta en escena |
Validación de preproducción |
publicado únicamente |
Producción |
Sitio público |
publicado únicamente |
Extensibilidad
Agregado de nuevos atributos
Para enriquecer el modelo de datos, simplemente agregar nuevos atributos prefijados`project-*` :
-
project-awards: Premios y reconocimientos -
`project-testimonial`Citación del cliente
-
`project-team-size`Tamaño del equipo
-
`project-budget-range`Rango presupuestario
Estos atributos se vuelven automáticamente disponibles en las plantillas sin modificar el motor JBake.
Categorización avanzada
@startuml
skinparam backgroundColor #FEFEFE
object Projet {
project-category = "web"
project-subcategory = "comercio electrónico"
project-industry = "venta al por menor"
project-complexity = "alto"
}
object Taxonomie {
categories : [web, mobile, data, devops]
subcategories : Map<category, List>
industries : [retail, finance, healthcare, ...]
complexities : [low, medium, high]
}
Projet --> Taxonomie : clasificado según
note right of Taxonomie
Permite filtrado multi‑criterio
en la plantilla portfolio.html
a través de JavaScript o del lado del servidor
end note
@enduml
Buenas Prácticas
Organización de los archivos
-
Archivo = proyecto : evitar mezclar varios proyectos
-
Imágenes en carpeta dedicada
assets/img/portfolio/nom-projet/ -
Nomenclatura coherente : facilita la búsqueda y el mantenimiento
-
Versioning Git : seguimiento completo de las modificaciones
Gestión del contenido
-
Estado borrador por defecto: publicar solo cuando esté listo
-
revisión antes de la publicación: validación de calidad y confidencialidad
-
Metadatos completos : completar todos los campos pertinentes
-
Contenido narrativo rico: no limitarse a los metadatos
Rendimiento
-
Optimizar imágenes : compresión antes del commit
-
Paginación si es necesario : si >20 proyectos
-
Carga diferida : imágenes de las galerías cargadas bajo demanda
-
Caché del navegador: encabezados adecuados para activos
Conclusión
Esta arquitectura permite:
-
Facilidad de uso: agregar un proyecto = crear un archivo de texto
-
Flexibilidad : extensible mediante nuevos atributos
-
Mantenibilidad : separación contenido/presentación
-
Trazabilidad : control de versiones Git completo
-
Automatización : build y despliegue continuo posibles
La elección de AsciiDoc garantiza la coherencia con el resto del sitio mientras ofrece la riqueza de los metadatos necesarios para un portafolio profesional.