エディタの定型返信に直接ボタンを追加

「定型返信」プラグインをよく使っています。現在は2クリック(設定→定型返信)の奥にありますが、ユーザー権限を尊重しつつ、エディタツールバーから直接アクセスできるようにカスタマイズする方法はありますか?

2 クリックはそれほど大変なことではありませんが、これはあなたが目指していることに焦点を当てて、composer ボタンとの連携方法を説明する良い機会です。

ツールバーにボタンを追加するには、異なる pluginAPI メソッドを使用します。

ツールバーはこのメソッド plugin-api.js.es6#L375-L391 を使用し、ポップアップメニューはこのメソッド plugin-api.js.es6#L396-L411 を使用します。

Canned Replies プラグインは、以下のようにポップアップメニューのメソッドを使用します。

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L18-L25

プラグインをフォークしない限り、ボタンを移動することはできません(強く推奨しません)。

できることは、同じ機能を持つ別のボタンをツールバーに追加し、古いボタンを非表示にすることです。ツールバーにボタンを作成するには、他のボタンの追加方法を確認する必要があります。

ツールバーには 2 種類のボタンがあります。1 つ目は、太字イタリック体のような書式設定を処理するボタンです。これらはあなたが達成したいこととは似ていないため、今は無視します。

もう 1 つは、日付や絵文字などを挿入するボタンです。日付(カレンダー)ボタンを見てみましょう。

これで、参考にする例ができました。新しいボタンを作成してみましょう。

まずはこれから始めます。

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
  
  });
});

次に、canned reply ボタンから属性を 1 つずつ追加します。参照用属性は以下の通りです。

id: "canned_replies_button",
icon: "far-clipboard",
action: "showCannedRepliesButton",
label: "canned_replies.composer_button_text"

id: これによりボタンに CSS クラスを追加できます。ここでは custom-canned-button を使用します。

icon: ボタンが使用するアイコンです。そのままにします。

label: ポップアップボタンにはテキストがありますが、composer ボタンにはありません。そのため、title に変更し、同じ値を使用する必要があります。

action: ここでボタンの動作を定義します。これらをまとめてみましょう。

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
    id: "custom-canned-replies",
    icon: "far-clipboard",
    action: "showCannedRepliesButton",
    title: "canned_replies.composer_button_text"
  });
});

これを実行すると、ツールバーにボタンが表示されますが、クリックしても何も起こりません。これは、showCannedRepliesButton というアクションが定義されていないためです。これは、テーマ内でこの処理を行っているため、コンテキストが異なることが原因です。

Canned Replies プラグインを見ると、そのアクションが composer コントローラーで定義されていることがわかります。

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L5-L16

次のステップは、ボタンがクリックされたときにそのアクションを送信できるように、composer コントローラーを参照することです。以下のように行います。

const composerController = api.container.lookup("controller:composer");

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
    title: "canned_replies.composer_button_text",
    id: "custom-canned-replies",
    group: "extras",
    icon: "far-clipboard",
    sendAction: () => composerController.send("showCannedRepliesButton")
  });
});

sendAction については、カレンダーボタン で使用したパターンと同じものを使用していることに注意してください。2 つの例外として、

toolbar.context.send の代わりに composerController.send を使用し、

イベントを渡していない点です(必要ないと思われるため)。

これで、ツールバーに完全に機能するボタンが表示されるはずです。

しかし、まだ終わりではありません。このボタンは現在、すべてのメンバーに表示されます。使用権限は引き続き適用され、権限のないユーザーがクリックするとエラーが発生します。ただし、壊れたボタンは好ましくないため、これを修正しましょう。

Canned Replies の使用権限はここにあります。

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L34-L38

したがって、ボタンの追加条件としてこれらを再現するだけで済みます。以下のような形です。

const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
  ? currentUser.can_use_canned_replies
  : false;

if (!canUseCannedReplies) return;

これにより、必要な権限を持つユーザーにのみボタンが表示されます。

では、すべてをまとめましょう。

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "move-canned-button",
  initialize() {
    withPluginApi("0.8.7", api => {
      const currentUser = api.getCurrentUser();
      const canUseCannedReplies = currentUser
        ? currentUser.can_use_canned_replies
        : false;

      if (!canUseCannedReplies) return;

      const composerController = api.container.lookup("controller:composer");

      api.onToolbarCreate(toolbar => {
        toolbar.addButton({
          title: "canned_replies.composer_button_text",
          id: "custom-canned-replies",
          group: "extras",
          icon: "far-clipboard",
          sendAction: () => composerController.send("showCannedRepliesButton")
        });
      });
    });
  }
};

これは、テーマコンポーネント内のこのファイルに入ります。

javascripts/discourse/initializers/move-canned-button.js.es6

新しい機能 Split up theme Javascript into multiple files を使用している場合(強く推奨)

または、管理画面でこれを行っている場合は、テーマのヘッダータブにこのスクリプトを追加することもできます。

古い構文
<script type="text/discourse-plugin"
        version="0.8">
const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
  ? currentUser.can_use_canned_replies
  : false;

if (!canUseCannedReplies) return;

const composerController = api.container.lookup("controller:composer");

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
    title: "canned_replies.composer_button_text",
    id: "custom-canned-replies",
    group: "extras",
    icon: "far-clipboard",
    sendAction: () => composerController.send("showCannedRepliesButton")
  });
});
</script>

最後に必要なことは、古いボタンを非表示にすることです。以下のように行います。

.toolbar-popup-menu-options {
  [data-name="Canned replies"] {
    display: none;
  }
}

こんなに詳しく返信してくださるとは全く予想していませんでした!素晴らしいです!今夜は少し時間を取って内容を整理させていただきます。ありがとうございます :pray:

@johani さん、ようこそ :tada: