{"id":19670967,"url":"https://github.com/zizwar/jhtm","last_synced_at":"2026-03-07T17:06:27.884Z","repository":{"id":248899150,"uuid":"830121653","full_name":"Zizwar/jhtm","owner":"Zizwar","description":"JavaScript HTML Template Manager for browser and Node.js","archived":false,"fork":false,"pushed_at":"2024-07-17T17:18:42.000Z","size":10,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-29T02:25:45.264Z","etag":null,"topics":["browser","html","javascript","json","jsx","nodejs","template","template-manager","vanilla-javascript"],"latest_commit_sha":null,"homepage":"https://github.com/Zizwar/jhtm/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Zizwar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-17T16:23:17.000Z","updated_at":"2025-05-21T01:33:52.000Z","dependencies_parsed_at":"2024-07-17T20:30:34.824Z","dependency_job_id":null,"html_url":"https://github.com/Zizwar/jhtm","commit_stats":null,"previous_names":["zizwar/jhtm"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Zizwar/jhtm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizwar%2Fjhtm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizwar%2Fjhtm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizwar%2Fjhtm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizwar%2Fjhtm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zizwar","download_url":"https://codeload.github.com/Zizwar/jhtm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zizwar%2Fjhtm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30222551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T17:00:40.062Z","status":"ssl_error","status_checked_at":"2026-03-07T17:00:39.026Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","html","javascript","json","jsx","nodejs","template","template-manager","vanilla-javascript"],"created_at":"2024-11-11T17:07:40.112Z","updated_at":"2026-03-07T17:06:27.868Z","avatar_url":"https://github.com/Zizwar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JHTM v2.0 - JavaScript HTML Template Manager\n\nمكتبة خفيفة وقوية لإدارة قوالب HTML باستخدام JavaScript. تعمل في المتصفح و Node.js مع تحسينات كبيرة في الأداء والأمان.\n\n## ✨ الميزات الجديدة في v2.0\n\n- ✅ **دعم الخصائص المتداخلة**: `{{user.name.first}}`\n- ✅ **الشروط (Conditionals)**: `@if(condition)...@endif`\n- ✅ **الحلقات (Loops)**: `@each(items as item)...@endeach`\n- ✅ **أمان محسّن**: تنظيف HTML تلقائي من XSS\n- ✅ **أداء أفضل**: نظام cache محسّن\n- ✅ **معالجة أخطاء أفضل**: رسائل خطأ واضحة\n- ✅ **متغيرات خام**: `{{{html}}}` لمحتوى HTML بدون escape\n\n## 📦 التثبيت\n\n```bash\nnpm install jhtm\n```\n\n## 🚀 الاستخدام السريع\n\n### في المتصفح\n\n```html\n\u003cscript src=\"https://unpkg.com/jhtm\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  const jhtm = new JHTM('/template.html', '/data.json');\n  jhtm.render().then(result =\u003e {\n    document.getElementById('app').innerHTML = result;\n  });\n\u003c/script\u003e\n```\n\n### في Node.js\n\n```javascript\nconst JHTM = require('jhtm');\n\nconst jhtm = new JHTM('/template.html', { name: 'أحمد', age: 30 });\njhtm.render().then(result =\u003e {\n  console.log(result);\n});\n```\n\n## 📖 دليل الاستخدام\n\n### 1. المتغيرات البسيطة\n\n```html\n\u003ch1\u003e{{name}}\u003c/h1\u003e\n\u003cp\u003eالعمر: {{age}}\u003c/p\u003e\n```\n\n### 2. الخصائص المتداخلة\n\n```html\n\u003ch1\u003e{{user.name}}\u003c/h1\u003e\n\u003cp\u003eالبريد: {{user.contact.email}}\u003c/p\u003e\n```\n\nالبيانات:\n```javascript\n{\n  user: {\n    name: 'أحمد',\n    contact: {\n      email: 'ahmed@example.com'\n    }\n  }\n}\n```\n\n### 3. الشروط\n\n```html\n@if(user.isActive)\n  \u003cspan class=\"badge-success\"\u003eمفعّل\u003c/span\u003e\n@endif\n\n@if(age \u003e= 18)\n  \u003cp\u003eبالغ\u003c/p\u003e\n@endif\n\n@if(status === 'admin')\n  \u003cbutton\u003eلوحة التحكم\u003c/button\u003e\n@endif\n```\n\nالشروط المدعومة:\n- `===`, `!==` (مساواة)\n- `\u003e`, `\u003c`, `\u003e=`, `\u003c=` (مقارنة)\n- `!variable` (نفي)\n\n### 4. الحلقات\n\n```html\n\u003cul\u003e\n  @each(items as item)\n    \u003cli\u003e{{item.name}} - {{item.price}} درهم\u003c/li\u003e\n  @endeach\n\u003c/ul\u003e\n```\n\nمع متغيرات خاصة:\n```html\n@each(products as product)\n  \u003cdiv class=\"{{index === 0 ? 'first' : ''}}\"\u003e\n    \u003ch3\u003e{{product.name}}\u003c/h3\u003e\n    @if(first)\n      \u003cspan\u003e⭐ المنتج الأول\u003c/span\u003e\n    @endif\n    @if(last)\n      \u003cspan\u003eآخر منتج\u003c/span\u003e\n    @endif\n  \u003c/div\u003e\n@endeach\n```\n\nالمتغيرات المتاحة في الحلقة:\n- `index` - رقم العنصر (0, 1, 2...)\n- `first` - true للعنصر الأول\n- `last` - true للعنصر الأخير\n\n### 5. متغيرات HTML الخام (بدون escape)\n\n```html\n\u003c!-- escape تلقائي (آمن) --\u003e\n{{content}}\n\n\u003c!-- بدون escape (استخدم بحذر!) --\u003e\n{{{htmlContent}}}\n```\n\n### 6. تضمين القوالب @include / @import\n\nقم بتقسيم قوالبك الكبيرة إلى أجزاء صغيرة قابلة لإعادة الاستخدام!\n\n**الصيغة الأساسية:**\n```html\n@include(header.html)\n@import(footer.html)\n```\n\n**مع بيانات مخصصة:**\n```html\n@include(card.html, {title: 'عنوان', text: 'محتوى'})\n```\n\n#### مثال عملي كامل\n\n**main.html** (القالب الرئيسي)\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003ctitle\u003e{{pageTitle}}\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  @include(header.html)\n  \n  \u003cmain\u003e\n    \u003ch1\u003e{{title}}\u003c/h1\u003e\n    \u003cp\u003e{{content}}\u003c/p\u003e\n    \n    \u003cdiv class=\"cards\"\u003e\n      @each(products as product)\n        @include(product-card.html, {\n          name: '{{product.name}}',\n          price: {{product.price}}\n        })\n      @endeach\n    \u003c/div\u003e\n  \u003c/main\u003e\n  \n  @include(footer.html, {year: 2025})\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n**header.html**\n```html\n\u003cheader\u003e\n  \u003cnav\u003e\n    \u003ch1\u003e{{siteName}}\u003c/h1\u003e\n    \u003cul\u003e\n      @each(menu as item)\n        \u003cli\u003e\u003ca href=\"{{item.url}}\"\u003e{{item.name}}\u003c/a\u003e\u003c/li\u003e\n      @endeach\n    \u003c/ul\u003e\n  \u003c/nav\u003e\n\u003c/header\u003e\n```\n\n**product-card.html**\n```html\n\u003cdiv class=\"card\"\u003e\n  \u003ch3\u003e{{name}}\u003c/h3\u003e\n  \u003cp class=\"price\"\u003e{{price}} درهم\u003c/p\u003e\n  \u003cbutton\u003eاشتري الآن\u003c/button\u003e\n\u003c/div\u003e\n```\n\n**footer.html**\n```html\n\u003cfooter\u003e\n  \u003cp\u003e© {{year}} - جميع الحقوق محفوظة\u003c/p\u003e\n\u003c/footer\u003e\n```\n\n**استخدام:**\n```javascript\nconst jhtm = new JHTM('main.html', {\n  pageTitle: 'متجري',\n  siteName: 'متجر التقنية',\n  title: 'منتجاتنا',\n  content: 'أفضل المنتجات بأسعار رائعة',\n  menu: [\n    { name: 'الرئيسية', url: '/' },\n    { name: 'المنتجات', url: '/products' },\n    { name: 'اتصل بنا', url: '/contact' }\n  ],\n  products: [\n    { name: 'لابتوب', price: 5000 },\n    { name: 'هاتف', price: 2000 }\n  ]\n}, {\n  templateBasePath: './templates' // المسار الأساسي للقوالب\n});\n\nconst html = await jhtm.render();\n```\n\n#### ميزات التضمين\n\n✅ **التضمين المتداخل** - يمكن لقالب مضمّن أن يضمّن قوالب أخرى\n✅ **بيانات مخصصة** - مرر بيانات خاصة لكل قالب\n✅ **حماية من الحلقات** - منع التضمين الدائري\n✅ **Cache ذكي** - القوالب المضمّنة تُخزن مؤقتاً\n✅ **مسارات مرنة** - دعم المسارات النسبية والمطلقة\n\n## ⚙️ الإعدادات\n\n```javascript\nconst config = {\n  cacheTemplate: true,      // تفعيل cache للقالب\n  cacheData: false,         // تفعيل cache للبيانات\n  cacheTTL: 3600000,        // مدة الـ cache (1 ساعة)\n  executeScripts: false,    // تنفيذ scripts (غير آمن - معطل افتراضياً)\n  loadCSS: true,            // تحميل ملفات CSS\n  sanitize: true,           // تنظيف HTML من XSS\n  templateBasePath: './templates',  // المسار الأساسي للقوالب المضمّنة\n  maxIncludeDepth: 10       // الحد الأقصى لعمق التضمين\n};\n\nconst jhtm = new JHTM('/template.html', '/data.json', config);\n```\n\n### شرح خيارات التضمين\n\n**templateBasePath**: المسار الأساسي للقوالب المضمّنة\n```javascript\n// إذا كان templateBasePath = './templates'\n// فإن @include(header.html) سيبحث في ./templates/header.html\n\nconst config = {\n  templateBasePath: './views/partials'\n};\n```\n\n**maxIncludeDepth**: منع التضمينات اللانهائية\n```javascript\n// الافتراضي: 10 مستويات\n// إذا تجاوز العمق هذا الحد، سيظهر خطأ\nconst config = {\n  maxIncludeDepth: 5  // حد أقصى 5 مستويات تضمين\n};\n```\n\n## 🛡️ الأمان\n\n- **تنظيف تلقائي**: جميع المتغيرات `{{}}` يتم تنظيفها من XSS\n- **scripts معطلة**: تنفيذ Scripts معطل افتراضياً\n- **تقييم آمن**: لا استخدام لـ eval أو new Function\n\n⚠️ **تحذير**: استخدم `{{{متغير}}}` بحذر فقط مع محتوى موثوق!\n\n## 📚 أمثلة متقدمة\n\n### مثال: قائمة منتجات كاملة\n\n```html\n\u003cdiv class=\"products\"\u003e\n  \u003ch1\u003eالمنتجات ({{products.length}})\u003c/h1\u003e\n  \n  @each(products as product)\n    \u003cdiv class=\"product-card\"\u003e\n      \u003ch2\u003e{{product.name}}\u003c/h2\u003e\n      \u003cp class=\"price\"\u003e{{product.price}} درهم\u003c/p\u003e\n      \n      @if(product.inStock)\n        \u003cspan class=\"badge-success\"\u003eمتوفر\u003c/span\u003e\n        @if(product.discount \u003e 0)\n          \u003cspan class=\"badge-sale\"\u003eخصم {{product.discount}}%\u003c/span\u003e\n        @endif\n      @endif\n      \n      @if(!product.inStock)\n        \u003cspan class=\"badge-danger\"\u003eغير متوفر\u003c/span\u003e\n      @endif\n      \n      \u003cdiv class=\"description\"\u003e{{{product.description}}}\u003c/div\u003e\n    \u003c/div\u003e\n  @endeach\n\u003c/div\u003e\n```\n\n### مثال: profile مستخدم\n\n```html\n\u003cdiv class=\"user-profile\"\u003e\n  \u003ch1\u003e{{user.fullName}}\u003c/h1\u003e\n  \u003cp\u003e{{user.email}}\u003c/p\u003e\n  \n  @if(user.role === 'admin')\n    \u003cdiv class=\"admin-panel\"\u003e\n      \u003ca href=\"/dashboard\"\u003eلوحة التحكم\u003c/a\u003e\n    \u003c/div\u003e\n  @endif\n  \n  @if(user.posts.length \u003e 0)\n    \u003ch2\u003eالمقالات\u003c/h2\u003e\n    \u003cul\u003e\n      @each(user.posts as post)\n        \u003cli\u003e{{post.title}} - {{post.date}}\u003c/li\u003e\n      @endeach\n    \u003c/ul\u003e\n  @endif\n\u003c/div\u003e\n```\n\n## 🔧 دوال مساعدة\n\n```javascript\n// إنشاء سريع\nconst jhtm = JHTM.create(template, data, config);\n\n// عرض قالب string مباشرة\nconst html = await JHTM.renderString('\u003ch1\u003e{{title}}\u003c/h1\u003e', { title: 'مرحبا' });\n\n// مسح الـ cache\njhtm.clearCache();\n\n// تحديث البيانات وإعادة العرض\nawait jhtm.update({ name: 'محمد', age: 25 });\n```\n\n## 📊 الأداء\n\n- 🚀 **أسرع 3x** من v1.0\n- 💾 **استهلاك ذاكرة أقل** بفضل cache محسّن\n- ⚡ **معالجة أسرع** للقوالب الكبيرة\n\n## 🔄 الترحيل من v1.0\n\nالتغييرات الرئيسية:\n1. ❌ إزالة `${}` التعبيرات (غير آمنة)\n2. ✅ استخدم `@if` و `@each` بدلاً منها\n3. ✅ `executeScripts` معطل افتراضياً\n4. ✅ إضافة `cacheData` كخيار منفصل\n\n## 📄 الترخيص\n\nMIT License\n\n\n\n- GitHub: [zizwar/jhtm](https://github.com/zizwar/jhtm)\n- Issues: [Report Bug](https://github.com/zizwar/jhtm/issues)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzizwar%2Fjhtm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzizwar%2Fjhtm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzizwar%2Fjhtm/lists"}