The site is built strictly modular. New products are never maintained in code — they are uploaded as folders to the server and detected automatically. This document describes the binding schema and the workflow.
الموقع مبني بشكل معياري صارم. لا تتم صيانة المنتجات الجديدة في الشيفرة أبداً — بل تُرفع كمجلدات إلى الخادم وتُكتشف تلقائياً. يصف هذا المستند المخطط الملزم وسير العمل.
Three files, one contract: the schema (binding), the template (copy source), and the loader (frontend). As long as every product satisfies the schema, the site can grow indefinitely.
ثلاثة ملفات، عقد واحد: المخطط (مُلزم)، والقالب (مصدر النسخ)، والمُحمِّل (الواجهة). طالما أن كل منتج يلبّي المخطط، يمكن للموقع أن ينمو بلا حدود.
_template/ → <slug>/
Fill required fields, drop images. املأ الحقول المطلوبة وأودِع الصور.
Upload the folder into /products/.
ارفع المجلد إلى /products/.
API scans, frontend renders. يفحص API، تعرض الواجهة.
The whole site is flat — no build tooling required. Everything
related to products lives under /products/.
الموقع كامل مسطّح — دون أدوات بناء. كل ما يتعلق بالمنتجات يقع
داخل /products/.
Every product.json is validated
against /products/_schema/product.schema.json
(JSON Schema Draft-7). Required fields are marked red.
كل product.json يتم التحقق منه مقابل
/products/_schema/product.schema.json
(JSON Schema Draft-7). الحقول المطلوبة معلَّمة بالأحمر.
| Fieldالحقل | Typeالنوع | Descriptionالوصف |
|---|---|---|
| slug required | string | URL slug. Must equal the folder name. ^[a-z0-9-]+$رمز URL. يجب أن يطابق اسم المجلد. ^[a-z0-9-]+$ |
| name.en required | string | Display name (English). name.ar optional.الاسم المعروض (إنجليزي). name.ar اختياري. |
| collection required | enum | stratum | mashraq | adat |
| category required | enum | heat-container · heat-pump · charge-container · fast-charger · energy-storage · hybrid · software · platform |
| status required | enum | available · on-request · limited · preview · in-development |
| headline.en required | string ≤140 | Single-sentence summary.ملخص من جملة واحدة. |
| description.en required | string | Body copy. Paragraphs split by \n\n.نص أساسي. تفصل الفقرات بـ \n\n. |
| specs.output_kw required | number | Useful output (heat or charge) in kW.القدرة المفيدة (تدفئة أو شحن) بالكيلوواط. |
| media.cover required | path | Path relative to the product folder, e.g. images/cover.jpgمسار نسبي لمجلد المنتج، مثل images/cover.jpg |
| Optional | ||
| specs.* optional | mixed | cascade_modules · refrigerant · cop_a7w35 · buffer_l · max_flow_temp_c · charge_outputs · max_dc_power_kw · battery_capacity_kwh · grid_connection · dimensions_cm · weight_kg · noise_db_a · monitoring · warranty_months |
| applications optional | array | Recommended use cases. Items may be string or {en, ar}.حالات الاستخدام الموصى بها. عناصر إما نصية أو {en, ar}. |
| compliance optional | string[] | Standards / certifications.المعايير والشهادات. |
| media.gallery optional | path[] | Additional images.صور إضافية. |
| colors optional | hex[] | Swatch palette.لوحة عينات الألوان. |
| price optional | object | purchase_eur · rent_eur_month · on_request: bool |
| downloads optional | object[] | label · file · kind (pdf/dwg/step/zip/…) |
| external_url optional | uri | If set, the product card links to this URL (sister brands).إن تم تحديده، تربط بطاقة المنتج بهذا الرابط (العلامات الشقيقة). |
| tags optional | string[] | Free-form keywords.كلمات مفتاحية حرة. |
| featured optional | boolean | Show on the home page.عرض في الصفحة الرئيسية. |
| published_at · updated_at | date | ISO date (YYYY-MM-DD). |
// /products/hajar-h81/product.json { "slug": "hajar-h81", "name": { "en": "Hajar H81", "ar": "الهاجر H81" }, "collection": "stratum", "category": "heat-container", "status": "available", "featured": true, "headline": { "en": "Flagship cascade heat pump…" }, "description": { "en": "…" }, "specs": { "output_kw": 81, "cascade_modules": "3 × 27 kW", "refrigerant": "R290 (Propane, GWP 3)", "cop_a7w35": 3.9, "buffer_l": 2000 }, "media": { "cover": "images/cover.jpg" } }
The frontend tries two sources — the first one to respond wins:
تجرب الواجهة مصدرين — يفوز أول من يستجيب:
products/api.php?list scans
/products/, validates each
product.json and returns the list.
Requires PHP 7+ on the web server.
products/api.php?list المجلد
/products/ ويتحقق من كل
product.json ويعيد القائمة. يتطلب PHP 7+.
products/index.json is generated by
node bin/build-index.mjs
(identical logic). For hosts without PHP.
products/index.json بأمر
node bin/build-index.mjs. للاستضافات بلا PHP.
Both sources discard folders whose product.json
is invalid or whose slug doesn't match
the folder name. A broken upload does not break the site — the
defective product simply doesn't appear.
يتجاهل كلا المصدرين المجلدات التي يكون فيها
product.json غير صالح أو لا يتطابق
فيها slug مع اسم المجلد. لا يكسر
الرفع المعطّل الموقع — ببساطة لا يظهر المنتج التالف.
// prepare locally $ cp -r products/_template products/hajar-h120 $ vim products/hajar-h120/product.json $ cp ./photos/*.jpg products/hajar-h120/images/ // upload $ rsync -av products/hajar-h120/ ftp.al-hajar.ae:/www/products/hajar-h120/ // with PHP available: done. otherwise regenerate the index: $ node bin/build-index.mjs $ scp products/index.json ftp.al-hajar.ae:/www/products/index.json
The navigation is declarative in assets/js/site.js
(the SITE object). A new page needs
three steps: create the HTML file, add an entry to
SITE.nav, append a footer column.
التنقل معلَن في assets/js/site.js
(كائن SITE). تحتاج صفحة جديدة ثلاث
خطوات: إنشاء ملف HTML، إضافة سطر إلى
SITE.nav، وإلحاق عمود تذييل.
| Pageالصفحة | Fileالملف | Modularityالمعيارية |
|---|---|---|
| Homeالرئيسية | index.html | Section-based · featured block loads dynamically.قائم على الأقسام · يحمَّل قسم المميزة ديناميكياً. |
| Catalogueالكتالوج | products.html | Fully dynamic · filters built from data.ديناميكي بالكامل · المرشحات تُبنى من البيانات. |
| Product detailتفصيل المنتج | product.html?slug=… | Fully dynamic · one template, all products.ديناميكي بالكامل · قالب واحد، كل المنتجات. |
| Houseالمؤسسة | about.html | Static · sections freely extensible.ثابتة · الأقسام قابلة للتوسيع بحرية. |
| Systemالنظام | architecture.html | This document.هذا المستند. |
| Contactتواصل | contact.html | Static · form stub.ثابتة · هيكل نموذج. |
The system is deliberately flat. Extensions follow three patterns:
النظام مسطّح عمداً. تتبع التوسعات ثلاثة أنماط:
category enum in _schema/product.schema.json.category في _schema/product.schema.json.CATEGORY_LABEL in products.js (EN + AR).CATEGORY_LABEL في products.js (EN + AR)._template/product.json as a starter value._template/product.json كقيمة ابتدائية.product.html.product.html.collection enum.collection.COLLECTION_META (colors, label).COLLECTION_META (الألوان، التسمية).