Discourseプラグイン開発 - パート3 - カスタムサイト設定の追加

前回のチュートリアル: Developing Discourse Plugins - Part 2 - Connect to a plugin outlet


サイト設定

管理者権限を持つDiscourseの/admin/site_settingsにアクセスすると、設定項目の一覧が表示されます。標準では、Discourseのインストールに最適な設定が提供されていますが、ユーザーがフォーラムを思い通りに調整したいと考えることも理解しています。

プラグインが非常に単純でない限り、プラグインのユーザーが機能を変更および設定するために使用できる設定を追加したいと思うでしょう。幸いなことに、これはかなり簡単に行えます!

config/settings.yml

まず、プラグインフォルダー内にconfig/settings.ymlを作成する必要があります。このファイルには、プラグインが必要とするすべての設定が記述されます。以下に例を示します。

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

ファイルはYAML形式である必要があります。YAMLは非常にデリケートな場合があるため、Discourseが設定の読み込みに問題がある場合は、YAMLintのようなツールでYAMLを検証してみることをお勧めします。

例のファイルを詳しく説明します。最上位レベルはpluginsであり、これらの設定をサイト設定の「プラグイン」の下に表示するようにDiscourseに伝えます。

その後、awesomeness_enabledawesomeness_max_volumeの2つの設定が宣言されます。Discourseはデフォルトから設定の型を推論するため、awesomeness_enabledはブール値、awesomeness_max_volumeは数値になります。

client: trueを理解することは重要です。Discourseは、Ruby on Railsで書かれたサーバーサイドのAPIと、Ember.jsで書かれたクライアントサイドのアプリケーションという2つの主要なアプリケーションで構成されています。デフォルトでは、client: trueを追加しない限り、設定をEmber.jsクライアントアプリに公開しません。APIキーのような一部の設定はプライベートであり、エンドユーザーに送信されるべきではないため、このようにしています。また、すべて設定をクライアントに送信すると、エンドユーザーにとってダウンロード量が膨大になる可能性があります!

私たちの例では、両方の設定がサーバーサイドの世界だけでなく、JavaScriptの世界でもアクセスできるようにしたいと考えています。

重要な2番目のステップ

新しく追加したサイト設定を使用する前に、それらの翻訳を追加する必要があります。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

設定ボタンが/admin/pluginsで正しく機能するように、すべて他の設定を"awesomeness_"で始めるようにしてください。

新しい設定へのアクセス

まず、設定を有効にするために開発サーバーを再起動する必要があります。再起動すると、設定がサーバー側とクライアント側のコードで利用可能になるはずです。

サイト設定はほとんどのJavaScriptオブジェクトに自動的に挿入されるため、ComponentControllerRouteView、またはModelを宣言している場合は、単にthis.siteSettings.awesomeness_enabledを使用することでサイト設定にアクセスできるはずです。ほとんどのハンドルバーテンプレートでも{{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