المحفظة المعمارية لـ JBake - الرؤية وحالات الاستخدام
نُشر في 15 January 2026
الرؤية المعمارية
مبدأ توجيهي
البنية تقوم على مبدأ فصل المخاوف:
-
المحتوى : ملفات AsciiDoc منظمة مع بيانات تعريفية غنية
-
عرض : قوالب Thymeleaf القابلة لإعادة الاستخدام
-
البيانات : النموذج المستخرج تلقائيًا بواسطة JBake من سمات AsciiDoc
-
النمط: Bootstrap 5 للتّوافق البصري
الخيار الاستراتيجي : AsciiDoc للملف الشخصي
| معيار | ميزة |
|---|---|
الاتساق |
نفس تنسيق مقالات المدونة |
البيانات الوصفية |
السمات المنظمة والقابلة للتوسيع ( |
قابلية الصيانة |
تحرير نصّي بسيط، قابل للتتبع بـ جيت |
المرونة |
قد يحتوي على محتوى غني (جداول، كود، صور) |
القوالب |
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 : تحليل
JBakeEngine --> ThymeleafTemplate : يوفر بيانات
ThymeleafTemplate --> PortfolioPage : يولد
@enduml
حالات الاستخدام المفصلة
UC1 : إضافة عنصر إلى المحفظة
التدفق الاسمي
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "المحرر\nTexte" as editor participant "ملف\nAsciiDoc" as file participant "JBake\nEngine" as jbake participant "موقع\nثابت" as site dev -> editor : إنشاء ملف جديد activate editor editor -> file : المحفظة/nouveau-projet.adoc activate file dev -> editor : عدّ الترويسة مع البيانات الوصفية\n(العنوان, النوع=project, status=published,\nالخصائص project-*) dev -> editor : كتابة محتوى سردي\n(contexte, défis, solutions) dev -> editor : إضافة الصور في assets/img/portfolio/ editor -> file : احفظ deactivate editor dev -> jbake : تشغيل البناء (jbake -b) activate jbake jbake -> file : قراءة وتحليل jbake -> jbake : استخراج البيانات الوصفية jbake -> jbake : تحويل AsciiDoc → HTML jbake -> jbake : تطبيق القالب project.html jbake -> jbake : إضافة إلى القائمة portfolio.html jbake -> site : إنشاء صفحات ثابتة deactivate jbake dev -> site : تحقق من النتيجة activate site site --> dev : عرض المشروع deactivate site @enduml
قالب الملف المراد إنشاؤه
المطور ينشئ`content/portfolio/nom-projet.adoc`مع بنية موحدة:
-
رأس مع جميع الخصائص المطلوبة
-
الأقسام المعيارية (السياق، التحديات، الحلول، النتائج)
-
التسمية المتسقة للصور
نقاط التحقق
-
السمات الإلزامية موجودة (
jbake-type,jbake-status,project-thumbnail) -
الصور المشار إليها موجودة في`assets/img/portfolio/`
-
ينجح build JBake بدون أي خطأ
-
يظهر المشروع على صفحة المحفظة
-
تعرض صفحة المشروع الفردية بشكل صحيح
UC2 : حذف عنصر من المحفظة
التدفق الاسمي
@startuml skinparam backgroundColor #FEFEFE actor Développeur as dev participant "نظام\nملفات" as fs participant "JBake\nمحرك" as jbake participant "موقع\nثابتة" as site database "ذاكرة التخزين المؤقت\nJBake" as cache dev -> fs : احذف portfolio/projet-ancien.adoc activate fs fs --> dev : ملف محذوف deactivate fs dev -> fs : (اختياري) حذف الصور المرتبطة\nassets/img/portfolio/projet-ancien-* activate fs fs --> dev : الصور المحذوفة deactivate fs dev -> cache : مسح الكاش JBake activate cache cache --> dev : ذاكرة التخزين المؤقت للفيديو deactivate cache dev -> jbake : إعادة بناء كاملة (jbake -b) activate jbake jbake -> jbake : مسح المحتوى/portfolio/ jbake -> jbake : مشروع غير موجود → لم يتم إنشاؤه jbake -> jbake : إعادة توليد portfolio.html\n(بدون المشروع المحذوف) jbake -> site : نشر بناء جديد deactivate jbake dev -> site : تحقق activate site site --> dev : المشروع غير موجود في القائمة deactivate site @enduml
الاستراتيجية البديلة: الأرشفة
بدلاً من الحذف النهائي، إمكانية إنشاء مجلد`content/portfolio/archive/`: (espace après les deux-points conservé tel quel)
-
انقل الملف بدلاً من حذفه
-
يسمح بالاستعادة بسهولة
-
احتفظ بتاريخ جيت أكثر وضوحًا
تنظيف الموارد
-
التحقق من الصور اليتيمة في`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 : افتح portfolio/projet.adoc activate file dev -> file : Modifier attribut\n:jbake-status: published\n↓\n:jbake-status: draft file --> dev : تم الحفظ deactivate file dev -> jbake : Rebuild (jbake -b) activate jbake jbake -> file : تحليل الملف jbake -> jbake : اكتشف status=draft jbake -> jbake : استبعاد من published_projects jbake -> jbake : لا تنشئ صفحة عامة note right المشروع لا يزال موجودًا لكنه غير منشور end note jbake -> site : إنشاء موقع (بدون هذا المشروع) deactivate jbake dev -> site : التحقق من المحفظة activate site site --> dev : مشروع غائب عن القائمة العامة deactivate site @enduml
الحالات الممكنة
@startuml skinparam backgroundColor #FEFEFE [*] --> Draft : Création initiale Draft --> Published : التحقق من الصحة والنشر Published --> Draft : انسحاب مؤقت Draft --> Archived : مشروع تم التخلي عنه Published --> Archived : مشروع منتهي الصلاحية Archived --> [*] : الحذف النهائي Published --> Published : تحديثات note right of Draft :jbake-status: مسودة غير مرئي للعلن مفيد للمشاريع الجارية end note note right of Published :jbake-status: المنشور مرئي في المحفظة فهرس بواسطة JBake end note note right of Archived تم وضعه في archive/ أو jbake-status: مؤرشف غير منشور لكن محفوظ 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 "published_projects" as data
database "محتوى (مشروع)" as content
}
index --> header
index --> footer
portfolio --> header
portfolio --> footer
portfolio --> card
data --> portfolio : تكرار
project --> header
project --> footer
project --> badge
project --> gallery
content --> project : مشروع فردي
note right of card
قطعة قابلة لإعادة الاستخدام
لعرض خريطة
لمشروع مع :
- 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`)
-
الصور : بادئة اسم المشروع (مثال:`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 : تحليل
JBakeEngine --> ThymeleafTemplate : يوفر بيانات
ThymeleafTemplate --> PortfolioPage : يولد
@enduml
بيئات
| بيئة | الاستخدام | الحالة مقبولة |
|---|---|---|
محلي |
التطوير والمعاينة |
مسودة، منشور |
التجهيز |
التحقق المسبق للإنتاج |
نشر فقط |
Production |
موقع عام |
منشور فقط |
قابلية التوسّع
إضافة سمات جديدة
لإثراء نموذج البيانات، ما عليك سوى إضافة سمات جديدة مسبوقة`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 : مُصنَّف وفقًا
note right of Taxonomie
يسمح بالتصفية المتعددة المعايير في القالب portfolio.html عبر JavaScript أو من جانب الخادم
end note
@enduml
أفضل الممارسات
تنظيم الملفات
-
ملف واحد = مشروع : تجنب خلط عدة مشاريع
-
صور في مجلد مخصص
assets/img/portfolio/nom-projet/ -
النومينكلاتور المتسقة : يسهّل البحث والصيانة
-
Versioning Git : المتابعة الكاملة للتعديلات
إدارة المحتوى
-
الحالة الافتراضية للمسودة : نشر فقط عندما يكون جاهزًا
-
مراجعة قبل النشر : التحقق من الجودة والسرية
-
البيانات الكاملة : ملء جميع الحقول ذات الصلة
-
المحتوى السردي الغني : لا تقتصر على البيانات الوصفية
الأداء
-
تحسين الصور : ضغط قبل الالتزام
-
التقسيم إذا لزم الأمر : إذا >20 مشاريع
-
التحميل المتأخر : صور المعارض تُحمَّل عند الطلب
-
ذاكرة التخزين المؤقت للمتصفح : الرؤوس المناسبة للموارد
خاتمة
تسمح هذه المعمارية:
-
سهولة الاستخدام : إضافة مشروع = إنشاء ملف نصي
-
المرونة : قابلة للتوسيع عبر سمات جديدة
-
قابلية الصيانة : فصل المحتوى عن العرض
-
التتبع : الإصدار الكامل لـ Git
-
الأتمتة : build والنشر المستمر ممكنين
اختيار AsciiDoc يضمن التوافق مع بقية الموقع مع توفير ثراء البيانات الوصفية اللازمة لمحفظة احترافية.