Fügen Sie im Editor einen direkten Button für vorgefertigte Antworten hinzu

Ich verwende das Plugin „vorgefertigte Antworten" recht häufig. Sie befinden sich jetzt zwei Klicks entfernt (Zahnrad → vorgefertigte Antworten); gibt es eine Möglichkeit, meine Editor-Symbolleiste so anzupassen, dass ich direkten Zugriff habe, dabei aber die Benutzerberechtigungen zu berücksichtigen?

Zwei Klicks sind nicht wirklich viel Arbeit, aber das ist eine gute Gelegenheit für eine allgemeine Erklärung, die dokumentiert, wie man mit Composer-Buttons arbeitet, mit Fokus auf das, was Sie erreichen möchten.

Das Hinzufügen von Buttons zur Symbolleiste erfolgt über eine andere pluginAPI-Methode.

Die Symbolleiste verwendet diese Methode plugin-api.js.es6#L375-L391, während das Popup-Menü diese hier verwendet plugin-api.js.es6#L396-L411.

Das Plugin für vorgefertigte Antworten verwendet die Popup-Menü-Methode wie folgt:

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

Sie können den Button nicht verschieben, es sei denn, Sie forken das Plugin – was dringend nicht empfohlen wird.

Was Sie tun können, ist, einen weiteren Button in der Symbolleiste hinzuzufügen, der dasselbe tut, und den alten auszublenden. Um einen Button in der Symbolleiste zu erstellen, müssen Sie sich ansehen, wie andere Buttons hinzugefügt werden.

Es gibt zwei Arten von Buttons in der Symbolleiste. Die erste Art sind Buttons, die Formatierungen wie Fett und Kursiv verarbeiten. Da sie nicht dem entsprechen, was Sie erreichen möchten, ignorieren wir diese vorerst.

Die andere Art sind Buttons, die Dinge wie Daten und Emojis einfügen. Schauen wir uns den Datums-Kalender-Button an.

Jetzt haben wir ein Beispiel, auf das wir zurückgreifen können. Versuchen wir also, den neuen Button zu erstellen.

Wir beginnen damit:

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

und fügen die Attribute des vorgefertigten Antwort-Buttons nacheinander hinzu. Zur Referenz sind dies:

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

id: Damit können Sie CSS-Klassen zum Button hinzufügen – wir verwenden custom-canned-button.

icon: Das Symbol, das der Button verwendet – wir lassen es gleich.

label: Popup-Buttons haben Text, während Composer-Buttons keinen haben, also müssen wir das in title ändern und denselben Wert verwenden.

action: Hier definieren Sie, was der Button tut. Fassen wir alles zusammen:

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

Wenn Sie dies ausprobieren, erhalten Sie einen Button in der Symbolleiste, aber das Klicken darauf bewirkt nichts. Das liegt daran, dass die Aktion showCannedRepliesButton nicht definiert ist. Das geschieht aufgrund des unterschiedlichen Kontexts – da Sie dies in einem Theme tun.

Wenn Sie sich das Plugin für vorgefertigte Antworten ansehen, werden Sie feststellen, dass diese Aktion im Composer-Controller definiert ist:

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

Der nächste Schritt besteht also darin, auf den Composer-Controller zu verweisen, um diese Aktion auszulösen, wenn der Button geklickt wird. Das können Sie so tun:

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")
  });
});

Beachten Sie, dass wir das gleiche Muster wie beim Kalender-Button für sendAction verwendet haben. Die einzigen beiden Abweichungen sind, dass wir anstelle von toolbar.context.send composerController.send verwenden

und wir das Event nicht übergeben, da ich denke, dass dies nicht erforderlich ist.

Dies sollte Ihnen einen voll funktionsfähigen Button in der Symbolleiste geben:

aber wir sind noch nicht fertig, da dieser Button nun für alle Mitglieder sichtbar ist. Die Berechtigungen gelten weiterhin, und wenn ein Benutzer ohne Berechtigung versucht, darauf zu klicken, erhält er nur eine Fehlermeldung. Ein defekter Button ist jedoch nicht gut, also beheben wir das.

Die Berechtigungen für die Verwendung vorgefertigter Antworten finden Sie hier:

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

Wir müssen also nur diese als Bedingungen für das Hinzufügen des Buttons replizieren. Etwas in der Art:

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

if (!canUseCannedReplies) return;

Dies stellt sicher, dass der Button nur angezeigt wird, wenn Sie die erforderlichen Berechtigungen haben.

Fassen wir also alles zusammen:

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")
        });
      });
    });
  }
};

Dies geht in eine Theme-Komponente in folgende Datei:

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

wenn Sie die neue https://meta.discourse.org/t/splitting-up-theme-javascript-into-multiple-files/119369-Funktion verwenden – dringend empfohlen.

Oder Sie können dieses Skript einfach in den Header-Tab Ihres Themes hinzufügen, wenn Sie dies im Admin-Bereich tun.

Alte Syntax
<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>

Das letzte, was Sie benötigen, ist das Ausblenden des alten Buttons, und das können Sie so tun:

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

Ich habe wirklich nicht mit einer so ausführlichen Antwort gerechnet, das ist fantastisch! Ich werde mir heute Abend etwas Zeit nehmen, um das alles zu verarbeiten. Danke! :pray:

Willkommen bei @johani :tada: