- الرئيسية
- منشئ المستندات
- نظام العناصر النائبة
نظام العناصر النائبة
يتيح نظام العناصر النائبة للقرّاء تخصيص عناوين IP وأرقام ASN والقيم الأخرى الخاصة بالنشر عبر الوثائق. يكتب المؤلفون رموزًا في ملفات Markdown؛ ويستبدلها المتصفح بالقيم التي يُدخلها المستخدم في وقت التشغيل.
تنسيق الرموز
Section titled “تنسيق الرموز”تتبع الرموز نمط التعبير النمطي (regex) التالي:
x([A-Z][A-Z0-9_]+)xيبدأ الرمز وينتهي بحرف x صغير ويحتوي على مُعرّف بأحرف كبيرة. على سبيل المثال، xCUSTOMER_ASNx يُشير إلى العنصر النائب CUSTOMER_ASN.
يتم تعريف التعبير النمطي في src/scripts/placeholder-dom.ts:
const PH_REGEX = /x([A-Z][A-Z0-9_]+)x/g;تعريفات العناصر النائبة
Section titled “تعريفات العناصر النائبة”يتم الإعلان عن جميع العناصر النائبة في src/data/placeholders.json. كل إدخال يأخذ الشكل التالي:
{ "CUSTOMER_ASN": { "type": "text", "default": "64496", "description": "Your public ASN (registered with ARIN/RIR)" }}| الحقل | مطلوب | الوصف |
|---|---|---|
type | نعم | "text" للإدخال الحر، "dropdown" لقوائم الاختيار |
default | نعم | القيمة الأولية المعروضة قبل أن يُغيّرها القارئ |
description | نعم | التسمية المعروضة في النموذج |
options | فقط للقوائم المنسدلة | مصفوفة من القيم المسموح بها |
إدارة الحالة
Section titled “إدارة الحالة”يتولى ملف src/lib/placeholder-store.ts إدارة جميع حالات العناصر النائبة.
التخزين
Section titled “التخزين”يتم حفظ القيم في localStorage تحت المفتاح f5xc-placeholders. يُوفّر المخزن أربع دوال:
| الدالة | الغرض |
|---|---|
getDefaults() | تُرجع خريطة لكل مفتاح عنصر نائب مع قيمته الافتراضية (default) من ملف JSON |
loadValues() | تقرأ من localStorage، وتعود إلى getDefaults() كقيمة احتياطية |
saveValues(values) | تكتب الخريطة الحالية في localStorage |
clearValues() | تحذف إدخال localStorage |
مجموعات الحقول
Section titled “مجموعات الحقول”تُنظّم FIELD_GROUPS مفاتيح العناصر النائبة في أقسام مُسمّاة لواجهة النموذج:
export const FIELD_GROUPS: FieldGroup[] = [ { label: 'Data Center & Scrubbing Centers', keys: ['DC_NAME', 'CENTER_1', 'CENTER_2'] }, { label: 'Protected Prefixes', keys: ['PROTECTED_CIDR_V4', 'PROTECTED_NET_V4', ...] }, { label: 'BGP', keys: ['CUSTOMER_ASN', 'F5_XC_ASN', 'BGP_PASSWORD'] }, // ... مجموعات إضافية];القيم المحسوبة
Section titled “القيم المحسوبة”بعض القيم مُشتقة من مُدخلات المستخدم بدلاً من إدخالها مباشرة. تحسب getComputedValues() هذه القيم من جداول البحث:
const cidrToMask: Record<string, string> = { '/24 (256 IPs)': '255.255.255.0', '/23 (512 IPs)': '255.255.254.0', // ...};يتم إنتاج عنصرين نائبين محسوبين:
| المفتاح المحسوب | مُشتق من | مثال |
|---|---|---|
PROTECTED_MASK_V4 | PROTECTED_CIDR_V4 عبر جدول بحث cidrToMask | 255.255.255.0 |
PROTECTED_PREFIX_V4 | PROTECTED_NET_V4 + PROTECTED_CIDR_V4 عبر cidrToShort | 192.0.2.0/24 |
تدمج getAllValues() القيم المُدخلة من المستخدم مع القيم المحسوبة، مما يُوفّر خريطة كاملة للاستبدال.
إطلاق الأحداث
Section titled “إطلاق الأحداث”تُرسل emitChange() حدث placeholder-change من نوع CustomEvent على document مع خريطة القيم الكاملة كـ detail:
export function emitChange(values: Record<string, string>) { document.dispatchEvent( new CustomEvent('placeholder-change', { detail: getAllValues(values) }), );}يُحرّك هذا الحدث كلاً من تحديثات عناصر span في DOM وإعادة عرض مخططات Mermaid.
مكوّن نموذج React
Section titled “مكوّن نموذج React”يُوفّر src/components/PlaceholderForm.tsx واجهة التحرير.
- الحالة:
useStateمُهيّأة منloadValues() - عند التحميل: يستدعي
useEffectدالةemitChange()لتفعيل الاستبدال الأولي في DOM - handleChange: يُحدّث حالة React، ويستدعي
saveValues()وemitChange() - handleReset: يستدعي
clearValues()، ويُعيد الحالة إلىgetDefaults()، ويُطلق التغيير - العرض: يتكرر عبر
FIELD_GROUPS، ويعرض<fieldset>لكل مجموعة. كل مفتاح يحصل إما على<input>(نوع نص) أو<select>(نوع قائمة منسدلة) - التخطيط: النموذج مُغلّف في عنصر
<details>، مطوي افتراضيًا
غلاف Astro
Section titled “غلاف Astro”يربط src/components/PlaceholderFormWrapper.astro مكوّن React بصفحة Astro:
<PlaceholderForm client:only="react" />
<script> import '../scripts/placeholder-dom.ts';</script>يُخبر client:only="react" إطار Astro بترطيب المكوّن على جانب العميل فقط (بدون SSR). يستورد وسم <script> المُتنقّل في DOM ليعمل في كل صفحة تتضمن هذا الغلاف.
يحقن الغلاف أيضًا أنماط CSS عامة لتنسيق النموذج (.ph-form-wrapper، .ph-grid، .ph-value، إلخ).
المُتنقّل في DOM
Section titled “المُتنقّل في DOM”يتولى src/scripts/placeholder-dom.ts استبدال الرموز على جانب العميل.
المسح الأولي
Section titled “المسح الأولي”عند تحميل الصفحة، تعمل init():
- تحدد
.sl-markdown-contentكجذر (تعود إلىdocument.bodyكبديل) - تستدعي
walkTextNodes(root, values)التي تستخدمdocument.createTreeWalkerمعNodeFilter.SHOW_TEXT - لكل عقدة نصية تُطابق نمط الرمز، تُقسّمها إلى جزء مستند يحتوي على عُقد نصية عادية وعناصر
<span data-ph="KEY" class="ph-value"> - تستبدل العقدة النصية الأصلية بالجزء
بعد المسح، يحتوي DOM على عناصر span بسمات data-ph بدلاً من الرموز الخام.
التحديثات اللاحقة
Section titled “التحديثات اللاحقة”عندما يُطلق النموذج حدث placeholder-change، تعمل updateSpans():
document.querySelectorAll<HTMLSpanElement>('span[data-ph]').forEach((span) => { const name = span.getAttribute('data-ph')!; if (values[name] !== undefined) { span.textContent = values[name]; }});هذا يتجنب إعادة مسح الشجرة — فهو يُحدّث محتوى نص عنصر span مباشرة.
مُستمعو الأحداث
Section titled “مُستمعو الأحداث”يُسجّل السكريبت مُستمعَين:
| الحدث | المُعالج | الغرض |
|---|---|---|
placeholder-change | handleChange | تحديث عناصر span وإعادة عرض مخططات Mermaid |
astro:page-load | init | إعادة مسح DOM بعد التنقل على جانب العميل في Astro |
كيفية: إضافة عنصر نائب جديد
Section titled “كيفية: إضافة عنصر نائب جديد”-
أضف إدخال JSON في
src/data/placeholders.json:"MY_NEW_VALUE": {"type": "text","default": "example","description": "Description shown in the form"} -
أضف المفتاح إلى مجموعة حقول في
src/lib/placeholder-store.ts. إما أضفه إلى مصفوفةkeysفي مجموعة موجودة أو أنشئ مجموعة جديدة فيFIELD_GROUPS. -
استخدم الرمز في المحتوى: اكتب
xMY_NEW_VALUExفي أي ملف.mdx. سيستبدله المُتنقّل في DOM في وقت التشغيل.
كيفية: إضافة قيمة محسوبة
Section titled “كيفية: إضافة قيمة محسوبة”القيم المحسوبة مُشتقة من عناصر نائبة أخرى. لإضافة واحدة:
-
أضف جدول بحث (إذا لزم الأمر) في
src/lib/placeholder-store.ts، متبعًا نمطcidrToMask. -
وسّع
getComputedValues()لتشمل المفتاح المُشتق الجديد:export function getComputedValues(values: Record<string, string>): Record<string, string> {// ... المنطق الموجودreturn {PROTECTED_MASK_V4: mask,PROTECTED_PREFIX_V4: `${net}${short}`,MY_COMPUTED: derivedValue, // أضف هنا};} -
استخدم
xMY_COMPUTEDxفي المحتوى مثل أي رمز آخر. لا تحتاج القيم المحسوبة إلى إدخال فيplaceholders.jsonأو مجموعة حقول — فهي غير مرئية في النموذج.