ما مدى "صعوبة" تعديل/توسيع Discourse لمطور backend؟

بعض الأفكار حول هذا الموضوع.

تطوير دورات Discourse مدفوعة

فكرة الدورات المتعلقة بتطوير Discourse على منصة مثل Udemy أو Coursera مثيرة للاهتمام. أظن أن المشكلات الرئيسية هي أنه لا يوجد الكثير من الأشخاص خارج فريق Discourse المؤهلين لإنشاء دورة في تطوير Discourse وأن العدد المحتمل للطلاب لدورة ما صغير جدًا. ومع ذلك، أنا متأكد من أن دورة جيدة متعلقة بتطوير سمات أو إضافات Discourse يمكن أن تحصل على عدد كافٍ من الطلاب بمرور الوقت لجعلها تستحق عناء إنشاء دورة.

هناك أيضًا مشكلة محتملة وهي أن فرض رسوم على دورات Discourse قد يتعارض مع روح هذا المنتدى. أنا فقط أتكهن بشأن ذلك.

دروس تطوير Discourse

أعتقد أن الملاحظة بأن التنفيذ الفعلي للعديد من إضافات وسمات ومكونات سمات Discourse بسيط جدًا صحيحة. كما هو الحال مع التطوير للمنصات الأخرى، تكمن المشكلة في تجاوز الحاجز الأولي لعدم فهم كيفية ترابط الأجزاء. يمكن لفريق Discourse (أو بعض المطورين المؤهلين الآخرين) المساعدة في ذلك من خلال كتابة بعض الدروس التعليمية التي ترشدك خلال العملية الكاملة لإنشاء سمات ومكونات سمات وإضافات وظيفية. على سبيل المثال، دليل خطوة بخطوة لإنشاء شيء مثل مكون سمة Discourse Placeholder.

أدرك أن هذا سيتطلب استثمارًا كبيرًا في الوقت، لذلك سيحتاج إلى التوافق مع أهداف عمل Discourse.

الموارد المتاحة حاليًا

مع القليل من البحث، هناك الكثير من المعلومات الجيدة حول تطوير Discourse في هذا المنتدى. النظر إلى أمثلة الكود من مستودع GitHub الخاص بـ Discourse هو أيضًا طريقة رائعة للتعلم.

أداة حديثة لا ينبغي تجاهلها هي GitHub Copilot. إذا قمت بتهيئة بيئة التطوير الخاصة بك بالطريقة الصحيحة، فيمكن أن تكون مفيدة للحصول على فكرة عن كيفية تطوير سمات وإضافات Discourse. لتطوير سمات Discourse، فإن أفضل نهج وجدته هو تطوير السمة (باستخدام Discourse Theme CLI) في الدليل الجذر لتثبيت Discourse المحلي الخاص بي. يمنحك هيكلة الأمور بهذه الطريقة وصولاً سهلاً إلى قاعدة كود Discourse. (لاحظ أنه لتطوير الإضافات، يوجد مجلد plugins بالفعل في الدليل الجذر /discourse.) (لاحظ أيضًا، قد أكون مخطئًا بشأن وصول Copilot فعليًا إلى قاعدة كود Discourse التي قمت بتحميلها في بيئة التطوير المتكاملة الخاصة بي. في أي حال، من المفيد توفير كود Discourse الأساسي للرجوع إليه.)

لتجنب التشتيت وأيضًا للتركيز على استخدام Copilot كأداة للتعلم، أقوم بإيقاف تشغيل إكمال Copilot في بيئة التطوير المتكاملة الخاصة بي (VS Code) وأتفاعل فقط مع Copilot عبر الدردشة. إليك مثال على نوع المساعدة التي يمكن أن يقدمها. (الملف shopify.js هو الملف الذي أنشأته Theme CLI في الدليل /javascripts/discourse/api-initializers/ الخاص بسمتي.)

محادثة مع Copilot

scossar: هل يمكنك شرح ما يفعله التصدير الافتراضي في shopify.js؟ إنه في الأساس الكود الأساسي الذي توفره Discourse عند إنشاء سمة باستخدام gem discourse_theme. لقد قمت بتعديل الكود الأساسي بحيث يسجل كل تغيير في الصفحة. أفهم استدعاء api.onPageChange، لكن ليس لدي فهم واضح لكيفية حقن الكائن api في الكود الخاص بي.

GitHub Copilot: يتم حقن الكائن api في الكود الخاص بك من خلال الدالة withPluginApi التي يتم استدعاؤها في طريقة initialize للكائن الذي تم إرجاعه بواسطة apiInitializer.

إليك نسخة مبسطة مما يحدث:

  1. عند بدء Discourse، يقوم بتشغيل جميع المُهيئات.
  1. تنشئ الدالة apiInitializer مُهيئًا يعمل بعد المُهيئ \"inject-objects\".
  1. عند تشغيل هذا المُهيئ، فإنه يستدعي الدالة withPluginApi، ويمرر لها المعلمات version و cb و opts.
  1. تتحقق الدالة withPluginApi مما إذا كان إصدار Discourse الحالي متوافقًا مع الإصدار المحدد. إذا كان كذلك، فإنه يستدعي دالة رد الاتصال (cb) ويمرر مثيل PluginApi كوسيط. هذا المثيل api هو الكائن api الذي تراه في الكود الخاص بك.

لذا، فإن الكائن api هو مثيل لـ PluginApi، ويتم تمريره إلى الكود الخاص بك بواسطة الدالة withPluginApi. يوفر هذا الكائن عددًا من الطرق التي تسمح لك بالتفاعل مع Discourse، مثل onPageChange، الذي تستخدمه بالفعل.

scossar: إذن الدالة التي هي الوسيط الثاني للتصدير الافتراضي في shopify.js هي دالة رد الاتصال التي تقبلها apiInitializer؟

GitHub Copilot: نعم، هذا صحيح. الوسيط الثاني لـ apiInitializer هو دالة رد اتصال. يتم استدعاء هذه الدالة مع مثيل PluginApi كوسيط عند تشغيل المُهيئ (بافتراض أن إصدار Discourse الحالي متوافق مع الإصدار المحدد). هذه هي الطريقة التي يصبح بها الكائن api متاحًا في ملف shopify.js الخاص بك.

بمجرد أن فرزت ذلك…

scossar: … فكرة أخرى، هل يمكن استخدام api.decorateCooked لحقن إطار iframe تم استضافته على تطبيق خارجي (على سبيل المثال، مستضاف بواسطة تطبيق Shopify الذي أقوم بتطويره)؟

GitHub Copilot: نعم، يمكنك استخدام api.decorateCooked لحقن إطار iframe في منشور. إليك مثال تقريبي لكيفية القيام بذلك:

api.decorateCooked($elem => {
  const postId = $elem.data('post-id');
  const iframe = document.createElement('iframe');
  iframe.src = `https://your-app.com/ratings?post_id=${postId}`;
  iframe.width = '100%';
  iframe.height = '200'; // اضبط حسب الحاجة
  $elem.append(iframe);
}, { id: 'rating-iframe' });

في هذا المثال، يتم استخدام api.decorateCooked لإلحاق إطار iframe بكل منشور. يتم تعيين مصدر إطار iframe إلى عنوان URL على تطبيقك الخارجي، مع تضمين معرف المنشور كمعلمة استعلام. ستحتاج إلى استبدال 'https://your-app.com/ratings' بعنوان URL الفعلي لصفحة التقييمات الخاصة بك.

يرجى ملاحظة أن هذا مثال مبسط. قد تحتاج إلى تعديله ليناسب احتياجاتك، ويجب عليك بالتأكيد إضافة معالجة الأخطاء والاحتياطات الضرورية الأخرى لضمان عمله بشكل صحيح وآمن.

ليس من المعقول في هذه المرحلة توقع أن يكتب Copilot كل الكود الخاص بك، ولكنه أداة رائعة لتعلم كيفية كتابة كود Discourse.