أفضل ترقية للمحرر هي التي تزيل الخوف من العمل على المحتوى.
أضفنا محرر Tiptap React إلى PageBuilder الخاص بالتجارة الإلكترونية لأن تعديل كتل HTML الخام أصبح مكلفًا للغاية. كانت تعمل، لكنها كانت مناسبة فقط للأشخاص الذين يشعرون بالراحة عند قراءة الترميز. يجب أن يتمكن التاجر من إضافة عنوان رئيسي أو صورة أو زر أو أعمدة أو علامات تبويب أو تضمين Instagram دون كسر تخطيط صفحة المنتج أو إرسال HTML غير آمن.
تم تنفيذ العمل على فرع `codex/htmlblock-wysiwyg-editor` في قالب ecom. أضاف أول commit للتنفيذ، `08692e2e`، محرر WYSIWYG لكتل HTML. ثم عملت commits لاحقة على تحسين التفاعلات، ونقل التسميات إلى نظام الترجمة، وتعزيز التعامل مع الوسائط، وإزالة تكرار صور مكتبة الوسائط بالاعتماد على المعرّف.
كان Tiptap مناسبًا لأنه لم يجبرنا على تبني بنية CMS مغلقة. احتفظنا بعقد HTML الحالي الخاص بـ PageBuilder، واستخدمنا Tiptap كمحرك للتحرير.
ما بنيناه
الميزة الظاهرة بسيطة: أصبحت كتل HTML في PageBuilder تحتوي الآن على محرر حقيقي بدلًا من مربع نص HTML خام.
لكن التنفيذ أكثر فائدة مما توحي به هذه الجملة. يدعم المحرر:
كانت النقطة الأخيرة مهمة. لم يكن هذا محررًا جديدًا يُبنى من الصفر. فالواجهة الأمامية للتجارة الإلكترونية كانت تحتوي بالفعل على محتوى بأسلوب Bootstrap، ومقتطفات CMS قديمة، ومناطق PageBuilder، ومسارات وسائط PrestaShop، وقواعد SEO. كنا بحاجة إلى طبقة WYSIWYG يمكنها تعديل المحتوى دون تسطيح نموذج HTML الحالي للموقع.
لماذا بدا Tiptap بسيطًا
إعداد Tiptap مع React صغير: `useEditor` و`EditorContent` ومصفوفة من الإضافات. يوفر StarterKit أساسيات التحرير، ثم تضيف الأجزاء التي يحتاجها منتجك.
في حالتنا، بقيت مجموعة الاعتماديات واضحة:
كان ذلك كافيًا لبناء واجهة المحرر، ثم إضافة كتل التجارة الإلكترونية الخاصة بنا فوقها. استخدمنا `StarterKit.configure()` لسلوك المحرر القياسي، وعطّلنا التعامل الافتراضي مع الروابط حيث احتجنا إلى قواعدنا الخاصة، ثم أعددنا Link وHighlight بشكل صريح.
لم يكن الجزء البسيط هو أن Tiptap حل كل مشكلة في التجارة الإلكترونية. فهو لم يفعل ذلك. بل كانت البساطة في نموذج الإضافات. تمكنا من وصف عقد المحتوى الخاصة بنا مباشرة: الزر، والصورة، والصورة القديمة، وتضمين Instagram، والأعمدة، وعلامات التبويب، والفاصل، والجدول، وحجم الخط، ونمط القائمة، ومحاذاة النص.
يتوافق ذلك بشكل واضح مع PageBuilder. فالزر ليس مجرد نص منسق. والصورة ليست مجرد وسم `img`. ومكوّن علامات التبويب يحتوي على تسميات، ولوحات، ومعرّفات، وحالة نشطة، وأدوار يمكن الوصول إليها. أتاح لنا Tiptap نمذجة هذه العناصر كمحتوى للمحرر بدلًا من محاولة استنتاجها من مربع نص بعد فوات الأوان.
كانت دورة HTML الكاملة هي الجزء الأهم
تفشل الكثير من عمليات الانتقال إلى محررات WYSIWYG لأن المحرر يريد تنسيقًا واحدًا بينما يعرض الموقع تنسيقًا آخر.
لم نرد ذلك. فالواجهة الأمامية تعرض بالفعل كتل HTML عبر صفحات المنتجات، وصفحات المحتوى، وأقسام الصفحة الرئيسية، والمواضع القريبة من الدفع، ومناطق PageBuilder الأخرى. كان على المحرر تحميل HTML الموجود، والسماح للمسؤول بتعديله، ثم حفظ HTML يمكن للمتجر العام عرضه بأمان.
وفر لنا Tiptap أدوات التحويل اللازمة لذلك. بالنسبة إلى لوحات علامات التبويب، نستخدم `generateJSON()` لتحويل HTML الموجود إلى محتوى المحرر، ونستخدم `generateHTML()` لتحويل محتوى اللوحة مرة أخرى إلى HTML. يحافظ ذلك على تنظيم واجهة التحرير مع إبقاء مخرجات HTML العامة للموقع.
وهذا مهم أيضًا بالنسبة إلى SEO. يظل CTA عنصر ارتساء. ويظل العنوان عنوانًا. وتظل الصورة شكلًا دلاليًا مع نص بديل وتعليق توضيحي. وتحافظ علامات التبويب على محتوى اللوحات القابل للزحف. لم ندفن نصوص التجارة الإلكترونية داخل أداة تعمل من جهة العميل فقط، بحيث تضطر محركات البحث أو التقنيات المساعدة إلى محاولة تخمين محتواها.
المحرر بسيط للتجار، وصارم في الكود
تخفي واجهة الإدارة معظم التعقيد.
يرى المحررون أزرار شريط الأدوات، والنوافذ الحوارية، وبطاقات التخطيط، وحقول الصور، ومنتقي الوسائط. ويمكنهم تحديد النص واستخدام BubbleMenu عائم للتنسيق. كما يمكنهم اختيار تخطيط من عمودين أو ثلاثة أعمدة دون تذكر أصناف Bootstrap. ويمكنهم إضافة علامات تبويب ومعاينة اللوحة الأولى قبل الحفظ.
لكن الكود يظل صارمًا في الخلفية:
وهذا الفصل هو سبب إعجابي بهذا التنفيذ. تبدو الواجهة مرنة ومتسامحة، لكن المخرجات المحفوظة تظل تحت السيطرة.
لم تكن الأمانة اختيارية
تكون محررات النص المنسق خطرة عندما يثق مسار الحفظ بكل ما يعيده المتصفح.
أضفنا منظفًا مخصصًا للنص المنسق حول العرض العام. ويستخدم DOMPurify مع قائمة سماح صريحة للوسوم والسمات. كما يزيل الترميز القابل لتشغيل scripts والتنفيذ قبل وصول المحتوى إلى نقاط إدراج HTML الخام في React. بالإضافة إلى ذلك، يطبّع بيانات تضمين Instagram ويزيل بروتوكولات URL المحظورة من السمات التي تحتوي على قيم URL.
تغطي اختبارات العرض الحالات المهمة لمنشئ صفحات التجارة الإلكترونية:
وهذا هو الفرق بين قولنا «أضفنا محرر WYSIWYG» وقولنا «يمكننا السماح للناس باستخدامه في الإنتاج».
يخبرنا سجل الفرع بالقصة الحقيقية
كان أول commit كبيرًا: تغيّر 18 ملفًا، مع 6,282 إضافة و187 حذفًا. أضاف اعتماديات Tiptap إلى تطبيقي المتجر، ومكوّن محرر يتجاوز 3,000 سطر، وأكثر من 1,100 سطر من SCSS الخاص بالمحرر، واختبارات العرض، وعناصر تحكم الإدارة، ومعالجة التخطيط، ومسار التنقية.
ثم جاءت التحسينات. حسّن `d092141d` محرر كتل HTML وتفاعلات التنقل. وأضاف `320591ec` تغطية الترجمة بالإنجليزية والسويدية والفرنسية، وأزال hook الخاص بمنتقي الوسائط، وعزّز سلوك المحرر، وجعل علامات التبويب أكثر مرونة. أما `2c7928b9` فأزال تكرار صور مكتبة الوسائط بالاعتماد على المعرّف.
هذا هو النمط الحقيقي في العمل على المحررات. يثبت الإصدار الأول إمكانية وجود المحرر. ثم تجعل commits اللاحقة استخدامه عمليًا.
أين ساعد Tiptap أكثر من غيره
ساعد Tiptap في ثلاثة مواضع.
أولًا، جعل نواة المحرر مملة بالمعنى الجيد. لم نحتج إلى ابتكار التحديدات، والأوامر، والتراجع/الإعادة، وسلوك لوحة المفاتيح، أو القوائم العائمة. فقد وفّر تكامل React وStarterKit أساسًا مستقرًا.
ثانيًا، أتاح لنا نمذجة الكتل الخاصة بالتجارة الإلكترونية دون إخفائها داخل معالجة هشة للسلاسل النصية. منحت العقد والأوامر المخصصة الأزرار والصور والأعمدة وعلامات التبويب والتضمينات بنية حقيقية.
ثالثًا، أتاح لنا الحفاظ على عقد العرض. كان بإمكاننا تخزين HTML وعرضه لأن المتجر العام يعتمد بالفعل على كتل HTML، مع الاستمرار في استخدام محتوى محرر منظم داخليًا حيث يكون ذلك منطقيًا.
هذا المزيج نادر. فالكثير من المحررات تكون سهلة إلى أن تحتاج إلى مخرجات مخصصة. والكثير من المحررات المخصصة تكون مرنة إلى أن تحتاج إلى تجربة كتابة طبيعية. يقع Tiptap في المنتصف المفيد.
المفاضلة
لا يلغي Tiptap قرارات المنتج.
ما زلت بحاجة إلى تحديد أنواع المحتوى المسموح بها، وHTML الذي سيبقى، وكيفية اختيار الصور، وكيفية التحقق من الروابط، وكيفية التعامل مع المحتوى الملصق، وكيفية عمل الترجمات، وكيف ينقّي مسار العرض العام المحتوى، ومقدار الحرية التي ينبغي أن يتمتع بها التجار.
بالنسبة إلى محرر مدونة، قد يكون Tiptap سريعًا. أما بالنسبة إلى PageBuilder للتجارة الإلكترونية، فإن معظم العمل يحدث حول Tiptap: التوافق مع المحتوى القديم، واختبارات العرض، وسير عمل الوسائط، وإمكانية الوصول، وSEO، والترجمات، والضوابط الوقائية.
وهذا مقبول. يجب أن يمنحك المحرر headless أساسيات البناء، لا أن يتظاهر بعدم وجود قواعد عملك.
خلاصة تجربتي
سأستخدم Tiptap مرة أخرى لهذا النوع من العمل.
أتاح لنا التنفيذ بناء محرر Tiptap React عملي دون التخلي عن نظام PageBuilder الحالي. يحصل التجار على واجهة تحرير أكثر أمانًا. ويحافظ المطورون على HTML يمكن التنبؤ به. ويظل المحتوى المهم لـ SEO قابلًا للزحف. ولا يعتمد المتجر على حيلة هشة للعرض من جهة العميل فقط.
هذا هو المعيار الذي أريده لأدوات إدارة التجارة الإلكترونية: بسيطة على السطح، صارمة في المخرجات، ومملة بما يكفي للثقة بها بعد الإطلاق الأول.
