المنشورات هي وحدات واجهة، مما يعني أن ما تحاول فعله سيتطلب جهدًا أكبر من مجرد إضافة HTML.
تمتلك سمة Discourse القدرة على تزيين الوحدات، لذا يمكنك الاستفادة من ذلك.
يُشرح تزيين الوحدة في الرابط أعلاه، لذا دعنا نركز على ما تحاول فعله: إضافة علامة تنسيق بعد أول منشور في كل موضوع.
ابدأ بإضافة العلامة التنسيقية إلى جميع المنشورات. شيء مثل هذا:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
return helper.h("div", "test text");
});
</script>
إلى قسم الرأس في سمتك. هذا يجب أن يكون كافيًا لإضافة “نص تجريبي” أسفل كل منشور.
دعنا نحلل الكود أعلاه:
api.decorateWidget("post:after", helper => {
تستدعي طريقة decorateWidget، حيث تكون الوحدة المستهدفة هي post والموقع المستهدف هو after. أي بعد وحدة المنشور.
helper هي أداة مساعدة مدمجة تمنحك الوصول إلى مجموعة من الأشياء التي سأشرحها لاحقًا.
return helper.h("div", "test text")
هذا هو تنسيق الإضافة المطلوب الذي تريد إضافته. قد تلاحظ عدم وجود HTML هناك، والسبب هو أن وحدات Discourse تُصدر عُقدًا افتراضية (virtual nodes) وليس HTML خام.
شرح ماهية العُقد الافتراضية أو كيفية عمل بناء الجملة يقع خارج نطاق هذا الموضوع، لذا سأتخطاه. لقد أضفت ملاحظة لكتابة دليل حول تأليف العُقد الافتراضية، ولكن إليك بعض الأمثلة حاليًا:
helper.h("div", "test text")
تُظهر النتيجة:
<div>test text</div>
و
return helper.h("div#custom-ad", [
helper.h(
"a.custom-ad-link",
{ href: "example.com" },
helper.h("img", { src: "https://picsum.photos/id/74/750/90" })
)
]);
ستُظهر النتيجة:
<div id="custom-ad">
<a href="example.com" class="custom-ad-link">
<img src="https://picsum.photos/id/74/750/90">
</a>
</div>
باختصار، تبدو العقدة هكذا:
helper.h(selector, {properties}, children)
سأشرح هذا المزيد في دليل العُقد الافتراضية.
إذًا، الآن بعد أن أصبحت العُقد جاهزة، ستحتاج فقط إلى إضافة الكود الكامل إلى قسم الرأس في سمتك، مثل هذا:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
return helper.h("div#custom-ad", [
helper.h(
"a.custom-ad-link",
{ href: "example.com" },
helper.h("img", { src: "https://picsum.photos/id/74/750/90" })
)
]);
});
</script>
ومع ذلك، لا تزال هناك مشكلة هنا، حيث سيتم إدراج الإعلان أسفل كل منشور في السلسلة، وهو أمر غير مثالي.
هنا تأتي فائدة أداة المساعدة helper، حيث يتم تمرير سمات المنشور إليها، لذا يمكنك إجراء فحص سريع:
console.log(helper)
ستتمكن من رؤية جميع سمات المنشور المتاحة للعمل معها.
هذه مجرد أمثلة، وهناك المزيد هناك.
لحسن الحظ، سمة firstPost متاحة لنا هنا، لذا كل ما تبقى هو إدخال ذلك في شرط سيُظهر علامة الإعلان فقط إذا كان المنشور هو الأول بالفعل، وإلا فلن يحدث شيء. شيء مثل هذا:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
const firstPost = helper.attrs.firstPost;
const h = helper.h;
if (firstPost) {
return h("div#custom-ad", [
h(
"a.custom-ad-link",
{ href: "example.com" },
h("img", { src: "https://picsum.photos/id/74/750/90" })
)
]);
}
});
</script>
وهذا سيقوم بإدراج إعلانك فقط بعد أول منشور. شيء إضافي يجب فعله هنا هو إضافة ارتفاع للصورة، وإلا فسيتسبب ذلك في اهتزاز أثناء التحميل. كما ذكرت سابقًا بإيجاز، سمة height لوسم الصورة هي خاصية، لذا تحتاج إلى إضافتها بجانب src.
مع تجميع كل ذلك معًا، إليك الكود النهائي لما تحاول تحقيقه:
<script type="text/discourse-plugin" version="0.8">
api.decorateWidget("post:after", helper => {
const firstPost = helper.attrs.firstPost;
const h = helper.h;
if (firstPost) {
return h("div#custom-ad", [
h(
"a.custom-ad-link",
{ href: "example.com" },
h("img", { src: "https://picsum.photos/id/74/750/90", height: "90" })
)
]);
}
});
</script>
ملاحظة أخيرة أود تسليط الضوء عليها هي أنه يمكنك في الواقع استخدام HTML خام إذا أثبتت العُقد الافتراضية أنها صعبة للغاية، لكن هذا غير موصى به، ومن الأفضل بكثير استخدام العُقد الافتراضية. لذا فإن نفس الكود مع HTML الخام سيبدو هكذا:
<script type="text/discourse-plugin" version="0.8">
const RawHtml = require("discourse/widgets/raw-html").default;
api.decorateWidget("post:after", helper => {
const firstPost = helper.attrs.firstPost;
if (firstPost) {
return [
new RawHtml({
html: `<div id="custom-ad">
<a href="example.com">
<img src="https://picsum.photos/id/74/750/90" height="90">
</a>
</div>`
})
];
}
});
</script>
ولكن مرة أخرى، هذا غير موصى به.


