يتضمن Discourse مئات من نقاط الإضافة (Plugin Outlets) التي يمكن استخدامها حقن محتوى جديد أو استبدال محتوى موجود في واجهة Discourse. يتم توفير “حجج الإخراج” (Outlet arguments) بحيث يمكن تخصيص المحتوى بناءً على السياق.
اختيار نقطة الإخراج
لإيجاد اسم نقطة الإضافة، ابحث في نواة Discourse عن “<PluginOutlet”، أو استخدم مكوّن ثيم مواقع نقاط الإضافة. (مثلاً: topic-above-posts).
نقاط الإخراج المغلفة (Wrapper outlets)
تبدو بعض نقاط الإخراج في النواة على شكل <PluginOutlet @name="foo" />. تتيح لك هذه الحقن محتوى جديد. نقاط إخراج أخرى ستقوم بـ “تغليف” تنفيذ نواة موجود على النحو التالي:
<PluginOutlet @name="foo">
core implementation
</PluginOutlet>
عند تعريف موصل (connector) لهذا النوع من نقاط الإخراج “المغلّفة”، سيتم استبدال تنفيذ النواة. يمكن لموضوع/إضافة نشط واحد فقط أن يساهم بموصل لنقطة إخراج مغلّفة.
لنقاط الإخراج المغلّفة، يمكنك عرض تنفيذ النواة الأصلي باستخدام الكلمة المفتاحية {{yield}}. قد يكون هذا مفيداً إذا كنت ترغب في استبدال تنفيذ النواة فقط تحت ظروف معينة، أو إذا كنت ترغب في تغليفه بشيء ما.
تعريف الموصل (Connector)
بمجرد اختيارك لنقطة الإخراج، قرر اسماً لموصلك. يجب أن يكون هذا الاسم فريداً عبر جميع الثيمات / الإضافات المثبتة في مجتمع معين. مثال: brand-official-topics
في ثيمك / إضافتك، عرّف موصل .gjs جديداً بمسار منسّق على النحو التالي:
![]()
{theme}/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
![]()
{plugin}/assets/javascripts/discourse/connectors/{outlet-name}/{connector-name}.gjs
سيتم عرض محتوى هذه الملفات كمكوّن Ember. للمعلومات العامة حول Ember وصيغة .gjs، راجع أدلة Ember.
لموصل “brand official topics” الافتراضي لدينا، قد يبدو الملف على النحو التالي:
<template>
<div class="alert alert-info">
This topic was created by a member of the
<a href="https://discourse.org/team">Discourse Team</a>
</div>
</template>
استخدام حجج الإخراج (Outlet arguments)
توفر نقاط الإضافة معلومات حول السياق المحيط عبر @outletArgs. تختلف الحجج الممررة لكل نقطة إخراج. طريقة سهلة لعرض الحجج هي إضافة هذا إلى قالبك:
{{log @outletArgs}}
سيؤدي هذا إلى تسجيل الحجج في وحدة تطوير المتصفح الخاصة بك. ستظهر ككائن Proxy - لاستكشاف قائمة الحجج، قم بتوسيع [[Target]] للوكيل (proxy).
في مثال topic-above-posts لدينا، يتوفر الموضوع المُعرض تحت @outletArgs.model. لذا يمكننا إضافة اسم مستخدم عضو الفريق على النحو التالي:
<template>
<div class="alert alert-info">
This topic was created by
{{@outletArgs.model.details.created_by.username}}
(a member of the
<a href="https://discourse.org/team">Discourse Team</a>)
</div>
</template>
إضافة منطق أكثر تعقيداً
أحياناً، لا يكون القالب البسيط كافياً. لإضافة منطق JavaScript إلى موصلك، قم بترقية ملف .gjs الخاص بك لتصدير مكوّن قائم على فئة (class-based component). يعمل هذا بنفس طريقة أي تعريف مكوّن آخر، ويمكن أن يتضمن حقن الخدمات (service injections).
في مثال topic-above-posts لدينا، قد نريد عرض المستخدم بشكل مختلف بناءً على إعداد الموقع “prioritize username in ux”. قد يبدو ملف .gjs على النحو التالي:
.../connectors/topic-above-posts/brand-official-topic.gjs:
import Component from "@glimmer/component";
import { service } from "@ember/service";
export default class BrandOfficialTopics extends Component {
@service siteSettings;
get displayName() {
const user = this.args.outletArgs.model.details.created_by;
if (this.siteSettings.prioritize_username_in_ux) {
return user.username;
} else {
return user.name;
}
}
<template>
<div class="alert alert-info">
This topic was created by
{{this.displayName}}
(a member of the
<a href="https://discourse.org/team">Discourse Team</a>)
</div>
</template>
}
العرض الشرطي (Conditional rendering)
إذا كنت تريد عرض محتواك فقط تحت ظروف معينة، فغالباً ما يكون كافياً تغليف قالبك بكتلة {{#if}} من handlebars. إذا لم يكن ذلك كافياً، فقد ترغب في استخدام خطاف shouldRender للتحكم في ما إذا كان قالب الموصل الخاص بك سيُعرض أم لا.
أولاً، تأكد من أن لديك موصل .gjs قائماً على فئة كما هو موصوف أعلاه. ثم، أضف دالة static shouldRender(). مع توسيع مثالنا:
import Component from "@glimmer/component";
export default class BrandOfficialTopics extends Component {
static shouldRender(outletArgs, helper) {
const firstPost = outletArgs.model.postStream.posts[0];
return firstPost.primary_group_name === "team";
}
// ... (أي منطق آخر)
<template>
{{! ... }}
</template>
}
الآن لن يتم عرض الموصل إلا عندما يكون المنشور الأول للموضوع قد أُنشئ بواسطة عضو في الفريق.
يتم تقييم shouldRender في سياق تتبع تلقائي (autotracking) لـ Glimmer. أي تغييرات مستقبلية في أي خصائص مرجعية (مثل outletArgs) ستسبب إعادة تقييم الدالة.
تقديم نقاط إخراج جديدة
إذا كنت بحاجة إلى نقطة إخراج غير موجودة بعد، فلا تتردد في تقديم طلب سحب (pull request)، أو فتح موضوع في Development.
هذا المستند يخضع للتحكم في الإصدارات - اقترح تغييرات على github.