تطوير إضافات Discourse - الجزء 3 - إضافة إعدادات موقع مخصصة

البرنامج التعليمي السابق: Developing Discourse Plugins - Part 2 - Connect to a plugin outlet


إعدادات الموقع

إذا قمت بزيارة /admin/site_settings في منصة Discourse لديك صلاحيات المسؤول عليها، سترى قائمة بإعدادات التكوين. بشكل افتراضي، نوفر ما نعتقد أنه أفضل الإعدادات لتثبيت Discourse، ولكننا نتفهم أيضًا أن الناس يريدون تعديل تثبيتاتهم لجعل منتداهم بالطريقة التي يريدونها تمامًا.

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

config/settings.yml

أول شيء ستحتاج إلى القيام به هو إنشاء config/settings.yml داخل مجلد المكون الإضافي الخاص بك. سيحدد هذا الملف جميع الإعدادات التي سيحتاجها المكون الإضافي الخاص بك. إليك ملف مثال:

plugins:
  awesomeness_enabled:
    default: true
    client: true
  awesomeness_max_volume:
    default: 10
    client: true

يجب أن يكون الملف بتنسيق YAML. يمكن أن يكون YAML صعبًا جدًا، لذا إذا واجه Discourse مشكلة في تحميل الإعدادات الخاصة بك، أقترح عليك محاولة التحقق من صحة ملف YAML الخاص بك باستخدام أداة مثل YAMLint.

سأشرح ملف المثال بالتفصيل. المستوى الأعلى هو plugins وهذا يخبر Discourse بأننا نريد أن تظهر هذه الإعدادات تحت “Plugins” (المكونات الإضافية) في إعدادات الموقع.

بعد ذلك، يتم تعريف إعدادين، awesomeness_enabled و awesomeness_max_volume. يستنتج Discourse نوع الإعدادات من القيمة الافتراضية، لذا فإن awesomeness_enabled هو قيمة منطقية (boolean) و awesomeness_max_volume هو رقم.

السطر client: true مهم لفهمه. يتكون Discourse من تطبيقين رئيسيين، واجهة برمجة التطبيقات (API) من جانب الخادم المكتوبة بلغة Ruby on Rails، وتطبيق جانب العميل المكتوب بلغة Ember.js. افتراضيًا، لا نعرض الإعدادات لتطبيق عميل Ember.js ما لم تقم بإضافة client: true. نقوم بذلك لأن بعض الإعدادات خاصة مثل مفاتيح واجهة برمجة التطبيقات (API keys) ويجب عدم إرسالها إلى المستخدمين النهائيين. بالإضافة إلى ذلك، إذا أرسلنا كل إعداد إلى العميل، فقد يكون ذلك عبئًا كبيرًا على المستخدمين النهائيين لتنزيله!

في مثالنا، نريد أن تكون كلتا الإعدادات متاحة في عالم JavaScript بالإضافة إلى عالم الخادم.

خطوة ثانية مهمة

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

لنقم بإنشاء ترجمات لإعداداتنا باللغة الإنجليزية:

config/locales/server.en.yml

en:
  site_settings:
    awesomeness_enabled: "Is this plugin awesome?"
    awesomeness_max_volume: "What is the maximum volume possible?"

التسميات التي أضفناها في هذا الملف سيتم عرضها في قسم المسؤول. من الجيد أن تكون واضحًا قدر الإمكان بشأن ما ينجزه الإعداد.

الإعلان عن الإعداد كـ “الإعداد المُمكّن”

الآن بعد أن أصبح لدينا إعداد الموقع، يجب أن نخبر Discourse أنه هو الذي يقوم بتشغيل الميزات وإيقافها.

افتح ملف plugin.rb الخاص بك وأضف السطر التالي أسفل تعليقات البيانات الوصفية:

enabled_site_setting :awesomeness_enabled

تأكد من بدء جميع إعداداتك الأخرى بـ “awesomeness_” لكي يعمل زر الإعدادات في /admin/plugins بشكل صحيح.

الوصول إلى إعداداتك الجديدة

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

نقوم تلقائيًا بحقن إعدادات الموقع في معظم كائنات JavaScript، لذا إذا كنت تُعرّف Component أو Controller أو Route أو View أو Model، فيجب أن تكون قادرًا على الوصول إلى إعداد الموقع ببساطة عن طريق استخدام this.siteSettings.awesomeness_enabled. في معظم قوالب handlebars، يجب أن تكون قادرًا أيضًا على قول {{siteSettings.awesomeness_enabled}} وسيتم عرض قيمة الإعداد.

لم نغطِ الكثير من محتوى Ruby في هذه السلسلة بعد، ولكن إذا كنت ترغب في الوصول إلى إعدادات الموقع في تطبيق Ruby، يمكنك القيام بذلك عبر: SiteSetting.awesomeness_enabled

الآن انطلق وأضف إعدادات مخصصة إلى المكونات الإضافية الخاصة بك!


المزيد في السلسلة

الجزء 1: أساسيات المكون الإضافي
الجزء 2: منافذ المكون الإضافي
الجزء 3: هذا الموضوع
الجزء 4: إعداد git
الجزء 5: واجهات المسؤول
الجزء 6: اختبارات القبول
الجزء 7: انشر المكون الإضافي الخاص بك


يتم التحكم في إصدار هذا المستند - اقترح تغييرات على github.

34 إعجابًا

For those more familiar with YAML, this was probably obvious, and thanks to YAMLint that you referenced I was able to figure this out pretty quick, but I thought it was worth mentioning that the format for the config/locales/server.en.yml needs to specifically be:

en:
  site_settings:
    awesomeness_enabled: "Is this plugin awesome?"
    max_volume: "What is the maximum volume possible?"

Correct?

Another quick question, it’s great that I can get to the settings by clicking on the Change Settings button, but how do I get the plugin specific Settings button directly to the right of the plugin like the poll plugin?

https://s3.amazonaws.com/f.cl.ly/items/162n220f0M0P3e0j2U3M/Image%202015-07-29%20at%207.29.28%20PM.png

Or is that a little too much for a Beginner’s Guide?

4 إعجابات

I updated the guide to fix both of those :smile:

4 إعجابات

How do you get the settings button to pre-populate the search field like Discourse Tagging does? I feel like I’m missing something obvious.

Edit: Nevermind, I figured it out. You had to use *_enabled to get it to filter. I originally didn’t have an enabled setting because the URL was simply the factor for determining if it is enabled.

إعجاب واحد (1)

For some reason, {{siteSettings}} in the poster-name-right outlet returns undefined. I tested with other outlets and the return the expected value. I’m not sure why :sadpanda:

Had to work around it by using {{Discourse.SiteSettings}}

إعجاب واحد (1)

This isn’t working because the Post view code path is some of the oldest code we have and it doesn’t do all the automatic stuff newer code can do :frowning:

I’ve come up with a fix that I think will solve your problem:

In the future I’ll be able to remove this hack and it’ll just work.

3 إعجابات

Hey @eviltrout how can I add a user setting? I mean a setting for a plugin that every user can change on his profile? Can I set a default too?

I guess is the same as an Custom User Field, so can I create a new User Field from a plugin?

Unfortunately there’s no easy way to do this right now. There is probably a good argument to be made for such an API for plugin authors.

Until then the way to do it is to add the fields via plugin outlets to the user preferences, tap into serializers and saving logic to store the setting the PluginStore.

إعجاب واحد (1)

I ran into this a while back too. We have to expose the field in the site settings too. I’ll see if I can add a PR to make this easier.

إعجاب واحد (1)

For anyone following this tutorial and trying to get SiteSettings.awesomeness_enabled to return anything in a rails console, be aware that the tutorial is wrong. It should be SiteSetting.awesomeness_enabled (Setting without the s at the end!)

إعجاب واحد (1)

Hmmm, this works for me in the hbs files

{{#if siteSettings.plugin_outlet_locations_enabled}}

Different syntax depending on where it’s being called from?

EDIT
Ah, the singular - plural Rails “magic” thing.

Nope, your first guess was correct >.>

JS has Discourse.SiteSettings but Rails has SiteSetting.

3 إعجابات

Oops! Thanks for letting me know. I’ve updated the tutorial.

إعجابَين (2)

Well, I believe some infrastructure are not complete yet. But I am refurnishing old login plugins while it’s worthwhile to asking the future change to plugin infra. Shall I move settings from login to plugin prefix?

I would recommend to do that, yes.

إعجاب واحد (1)

Just to clarify, this is only the case if you say client: true, right?

Yes, that is correct. Javascript gets access to the “client side” site settings.

إعجابَين (2)

I do not completely understand this statement. I set it to client: false but it was still visible in admin settings. What exactly happens if you set client to false.

Thank you.

We ship up a big JSON object of all the site settings that have client: true to all users, so those are considered public and viewable.

If they don’t have client: true then they are meant to be available from the server side. The admin section is an exception - we need to return all site settings to admin users so they can be changed! It uses a different API to get them all.

9 إعجابات

Work for me! 2018-4-28

Code

config/settings.yml

config/locales/server.en.yml

plugin.rb

Result

http://localhost:3000/admin/site_settings/category/plugins


(oh, I saw the translation missing hint)

Thanks!

3 إعجابات