Link rewriting for affiliate codes

نعم، هذا ممكن. لنبدأ بشيء بسيط. أولاً، أضف هذا إلى تبويب الرأس (header) لمكون سمة جديد.

<script type="text/discourse-plugin" version="0.8.42">

</script>

ماذا يفعل هذا؟ إنه نوع خاص من وسوم السكربت التي تتم معالجتها بواسطة Discourse. ما هي الفائدة؟ إنه يتيح لك الوصول إلى طرق واجهة برمجة التطبيقات للإضافات.

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

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/lib/plugin-api.js#L224-L262

تستخدمها على النحو التالي.

api.decorateCookedElement(
  element => {
    // قم بعملك هنا. 
    // العنصر الممرر هنا هو عقدة HTML للمنشور المطبوخ
  },
  {
    // توضع الخيارات هنا
  }
);

هذا هو الغلاف الذي تحتاج إلى وضع الكود بداخله ليتم تشغيله عند عرض منشور. لذا، دعنا نجرب ذلك.

نأخذ الكود الخاص بك ونضيفه كما هو

api.decorateCookedElement(
  element => {
++  // غيّر "my-affiliate-id" أدناه إلى معرف التابع الفعلي الخاص بك
++  const aid = "my-affiliate-id";
++
++  // أضف شرطة مائلة مع معرف التابع، فقط إذا لم يتم العثور على معرف تابع في الرابط بعد
++  const goglinks = document.querySelectorAll('a[href*="gog.com"]');
++  goglinks.forEach(function (el) {
++    if (!el.href.includes("pp=")) {
++      el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
++    }
++  });
  },
  {
    // توضع الخيارات هنا
  }
);

هل يعمل هذا؟ نعم، لكنه يقوم أيضًا ببعض العمل الزائد لأننا نستعلم عن document للحصول على الروابط بدلاً من عنصر المنشور. إذن، كيف يمكنك إصلاح ذلك؟

تذكر حجة element التي مررناها في الطريقة؟ حسنًا، هذا هو الوقت الذي تكون فيه مفيدة.

بدلاً من استعلام المستند، نقوم باستعلام العنصر الذي نريد استهدافه. لذا، نغير هذا.

const goglinks = document.querySelectorAll('a[href*="gog.com"]');

إلى هذا

const goglinks = element.querySelectorAll('a[href*="gog.com"]');

وهذا ما ننتهي إليه

api.decorateCookedElement(
  element => {
    // غيّر "my-affiliate-id" أدناه إلى معرف التابع الفعلي الخاص بك
    const aid = "my-affiliate-id";

    // أضف شرطة مائلة مع معرف التابع، فقط إذا لم يتم العثور على معرف تابع في الرابط بعد
--  const goglinks = document.querySelectorAll('a[href*="gog.com"]');
++  const goglinks = element.querySelectorAll('a[href*="gog.com"]');
    goglinks.forEach(function (el) {
      if (!el.href.includes("pp=")) {
        el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
      }
    });
  },
  {
    // توضع الخيارات هنا
  }
);

هذا يعمل بشكل رائع الآن، لكن لا يزال بإمكاننا تحسينه قليلاً. بما أنك تضيف معرف تابع إلى الروابط فقط، فلا تحتاج إلى تشغيل هذا عندما تكون في محرر الكتابة (composer). هذا هو المكان الذي تكون فيه خيارات الطريقة مفيدة.

إحدى الخيارات التي يمكنك تمريرها للطريقة هي onlyStream

ماذا تفعل؟ إنها تخبر الطريقة أنك تريد فقط أن يتم تشغيل هذا الكود عند عرض المنشور داخل موضوع. دعنا نضيف هذا الخيار.

api.decorateCookedElement(
  element => {
    // غيّر "my-affiliate-id" أدناه إلى معرف التابع الفعلي الخاص بك
    const aid = "my-affiliate-id";

    // أضف شرطة مائلة مع معرف التابع، فقط إذا لم يتم العثور على معرف تابع في الرابط بعد
    const goglinks = element.querySelectorAll('a[href*="gog.com"]');
    goglinks.forEach(function (el) {
      if (!el.href.includes("pp=")) {
        el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
      }
    });
  },
  {
++  onlyStream: true
  }
);

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

<script type="text/discourse-plugin" version="0.8.42">
api.decorateCookedElement(
  element => {
    // غيّر "my-affiliate-id" أدناه إلى معرف التابع الفعلي الخاص بك
    const aid = "my-affiliate-id";

    // أضف شرطة مائلة مع معرف التابع، فقط إذا لم يتم العثور على معرف تابع في الرابط بعد
    const goglinks = element.querySelectorAll('a[href*="gog.com"]');
    goglinks.forEach(function (el) {
      if (!el.href.includes("pp=")) {
        el.href = el.href.replace(/\?.*$/, "") + "?pp=" + aid;
      }
    });
  },
  {
    onlyStream: true
  }
);
</script>

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

11 إعجابًا