الدليل السابق: Developing Discourse Plugins - Part 4 - Setup git
في بعض الأحيان، لا تكون إعدادات الموقع كافية كواجهة إدارية لتعمل إضافة (Plugin) بالطريقة التي تريدها. على سبيل المثال، إذا قمت بتثبيت إضافة discourse-akismet، قد تلاحظ أنها تضيف عنصر تنقل إلى قسم الإضافات في لوحة إدارة Discourse:
في هذا الدليل، سنوضح لك كيفية إضافة واجهة إدارية لإضافتك. سأسمي إضافتي “purple-tentacle” (المجس الأرجواني) تكريماً لـ واحدة من ألعاب الكمبيوتر المفضلة لدي. بجدية، أحب تلك اللعبة جداً!
إعداد مسار الإدارة
لنبدأ بإضافة ملف plugin.rb كما فعلنا في الأجزاء السابقة من الدليل.
plugin.rb
# name: purple-tentacle
# about: A sample plugin showing how to add a plugin route
# version: 0.1
# authors: Robin Ward
# url: https://github.com/discourse/purple-tentacle
add_admin_route 'purple_tentacle.title', 'purple-tentacle'
Discourse::Application.routes.append do
get '/admin/plugins/purple-tentacle' => 'admin/plugins#index', constraints: StaffConstraint.new
end
سطر add_admin_route يخبر Discourse أن هذه الإضافة ستحتاج إلى رابط في صفحة /admin/plugins. سيكون عنوانها purple_tentacle.title من ملف ترجمات i18n الخاص بنا، وسيكون الرابط موجهاً إلى مسار purple-tentacle.
الأسطر التالية تحدد تعيين المسارات على جانب الخادم لإضافتنا. تفترض Discourse أن كل مسار تقريباً على الواجهة الأمامية له مسار على جانب الخادم يوفر البيانات. بالنسبة لإضافة المثال هذه، لا نحتاج فعلياً إلى أي بيانات من الخادم، لكننا بحاجة إلى إخبار Discourse بتقديم شيء ما في حال قام المستخدم بزيارة /admin/plugins/purple-tentacle مباشرة. يخبر هذا السطر النظام: “أهلاً، إذا زار المستخدم هذا الرابط مباشرة على جانب الخادم، قم بتقديم محتوى الإضافات الافتراضي!”
(إذا كان هذا مربكاً، لا تقلق كثيراً، سنعود إليه في دليل مستقبلي عندما نتعامل مع إجراءات جانب الخادم).
بعد ذلك، سنضيف قالباً (Template) سيتم عرضه عند زيارة المستخدم للمسار /admin/plugins/purple-tentacle. سيكون مجرد زر يعرض صورة متحركة (GIF) لمجس أرجواني عند ضغط المستخدم على الزر:
assets/javascripts/discourse/templates/admin/plugins-purple-tentacle.gjs
import DButton from "discourse/components/d-button";
<template>
{{#if @controller.tentacleVisible}}
<div class="tentacle">
<img src="https://eviltrout.com/images/tentacle.gif" />
</div>
{{/if}}
<div class="buttons">
<DButton
@label="purple_tentacle.show"
@action={{@controller.showTentacle}}
@icon="eye"
@id="show-tentacle"
/>
</div>
</template>
إذا كنت قد تعلمت أساسيات Handlebars، فيجب أن يكون القالب بسيطاً للفهم. العنصر <DButton /> هو مكون في Discourse نستخدمه لعرض زر مع تسمية وأيقونة.
لربط قالبنا الجديد، نحتاج إلى إنشاء خريطة مسار (Route Map):
assets/javascripts/discourse/purple-tentacle-route-map.js
export default {
resource: "admin.adminPlugins",
path: "/plugins",
map() {
this.route("purple-tentacle");
},
};
خريطة المسار هي شيء أضفناه إلى Discourse لتمكين الإضافات من إضافة مسارات لتطبيق Ember. يكون بناء الجملة داخل map() مشابهاً جداً لـ موجه Ember. في هذه الحالة، خريطة المسار الخاصة بنا بسيطة جداً، حيث تعلن فقط عن مسار واحد يسمى purple-tentacle تحت /admin/plugins.
أخيراً، دعنا نضيف سلاسل الترجمة الخاصة بنا:
config/locales/client.en.yml
en:
js:
purple_tentacle:
title: "Purple Tentacle"
show: "Show Purple Tentacle"
إذا قمت بإعادة تشغيل خادم التطوير الخاص بك، يجب أن تتمكن من زيارة /admin/plugins وسترى رابطنا! إذا نقرت عليه، سترى الزر لعرض المجس الأرجواني:
لسوء الحظ، عند النقر على الزر، لا يحدث شيء ![]()
إذا نظرت إلى وحدة تحكم المطور (Developer Console)، يجب أن ترى خطأً يوفر دليلاً على السبب:
Uncaught Error: Nothing handled the action 'showTentacle'`
أه نعم، السبب هو أننا في قالبنا نعتمد على شيئين:
- أنه عند نقر المستخدم على الزر، سيتم استدعاء
showTentacleعلى المتحكم (Controller). - يجب أن تقوم
showTentacleبتعيين الخاصيةtentacleVisibleإلىtrueحتى تظهر الصورة.
إذا لم تقرأ دليل Ember حول المتحكمات، فإن الوقت مناسب للقيام بذلك الآن، لأننا سنقوم بتنفيذ متحكم لقالب purple-tentacle الخاص بنا سيتعامل مع هذا المنطق.
قم بإنشاء الملف التالي:
assets/javascripts/discourse/controllers/admin-plugins-purple-tentacle.js
import Controller from "@ember/controller";
import { action } from "@ember/object";
import { tracked } from "@glimmer/tracking";
export default class AdminPluginsPurpleTentacleController extends Controller {
@tracked tentacleVisible = false;
@action
showTentacle() {
this.tentacleVisible = true;
}
}
والآن عند تحديث صفحتنا، يؤدي النقر على الزر إلى عرض الشخصية المتحركة!

سأترك لك كممارسة إضافية للقارئ إضافة زر يخفي المجس عند النقر عليه ![]()
إذا كنت تواجه صعوبة في تشغيل نسختك من هذه الإضافة، فقد قمت بدفعها إلى GitHub.
المزيد في السلسلة
الجزء 1: أساسيات الإضافات
الجزء 2: مخارج الإضافات
الجزء 3: إعدادات الموقع
الجزء 4: إعداد git
الجزء 5: هذا الموضوع
الجزء 6: اختبارات القبول
الجزء 7: نشر إضافتك
يخضع هذا المستند للتحكم في الإصدارات - اقترح تغييرات على GitHub.





