(nicht empfohlen) Discourse-Vorlagen über ein Theme oder Plugin überschreiben

Idealerweise sollten Sie bei der Anpassung von Discourse über Themes/Plugins CSS, die JavaScript Plugin API oder Plugin Outlets verwenden. Wenn keine dieser Methoden für Ihren Anwendungsfall funktioniert, können Sie gerne einen PR für den Discourse-Kern öffnen oder ein #dev-Thema hier auf Meta starten. Wir freuen uns immer, über das Hinzufügen neuer Outlets/APIs zu diskutieren, um die Anpassung zu erleichtern.

Wenn Sie alle anderen Optionen ausgeschöpft haben, müssen Sie möglicherweise auf Template-Überschreibungen zurückgreifen. Diese Technik ermöglicht es Ihnen, das gesamte Template jeder Ember-Komponente oder Route aus Ihrem Theme/Plugin zu überschreiben.

:rotating_light: Dies ist keine empfohlene Methode zur Anpassung von Discourse. Tägliche Änderungen im Discourse-Kern werden irgendwann mit Ihrer Template-Überschreibung in Konflikt geraten und potenziell katastrophale Fehler beim Rendern des Forums verursachen.

Wenn Sie sich für diesen Ansatz entscheiden, stellen Sie sicher, dass Sie über ausreichende automatisierte Test- und Qualitätssicherungsprozesse verfügen, um Regressionen zu erkennen. Wenn Sie ein Theme/Plugin mit Template-Überschreibungen verteilen, stellen Sie bitte sicher, dass die Forum-Administratoren sich der Stabilitätsrisiken bewusst sind, die Ihr Theme/Plugin mit sich bringt.

:rotating_light: :rotating_light: :rotating_light: Update vom Oktober 2023: Für neue Funktionen verlagert sich Discourse zunehmend auf die Verwendung von Komponenten, die mit dem .gjs-Dateiformat von Ember erstellt wurden. Templates für diese Komponenten werden inline definiert und können nicht durch Themes/Plugins überschrieben werden.

Zukünftig sollten alle Template-Anpassungen über Plugin Outlets erfolgen.

Ich verstehe, dass dies in naher Zukunft fehlschlagen wird, zeigen Sie mir trotzdem die Dokumentation

Überschreiben von Komponententemplates

Um ein Ember-Komponententemplate zu überschreiben (d. h. alles unter components/* im Discourse-Kern), sollten Sie eine identisch benannte .hbs-Datei in Ihrem Theme/Plugin erstellen. Um beispielsweise das Template für die Komponente badge-button im Discourse-Kern zu überschreiben, würden Sie eine Template-Datei in Ihrem Theme/Plugin an folgendem Ort erstellen:

:art: {theme}/javascripts/discourse/templates/components/badge-button.hbs

:electric_plug: {plugin}/assets/javascripts/discourse/templates/components/badge-button.hbs

Die Überschreibung muss immer innerhalb des /templates-Verzeichnisses verschachtelt sein, auch wenn die Kernkomponente ein „lokalisiertes“ Template hat.

Überschreiben von Routentemplates

Das Überschreiben von Routentemplates (d. h. alle Nicht-Komponenten-Templates unter templates/*) funktioniert genauso wie bei Komponenten. Erstellen Sie ein identisch benanntes Template in Ihrem Theme/Plugin. Um beispielsweise discovery.hbs im Kern zu überschreiben, würden Sie eine Datei wie erstellen

:art: {theme}/javascripts/discourse/templates/discovery.hbs

:electric_plug: {plugin}/assets/javascripts/discourse/templates/discovery.hbs

Überschreiben von „Raw“-Templates (.hbr)

Discourse’s „Raw“-Template-System wird bald durch reguläre Ember-Komponenten ersetzt. Aber in der Zwischenzeit funktioniert das Überschreiben von Raw-Templates genauso wie bei Ember-Templates. Um beispielsweise topic-list-item.hbr im Kern zu überschreiben, könnten Sie eine Datei wie erstellen:

:art: {theme}/javascripts/discourse/templates/list/topic-list-item.hbr

:electric_plug: {plugin}/assets/javascripts/discourse/templates/list/topic-list-item.hbr

Interaktion zwischen mehreren Themes / Plugins

Wenn mehrere installierte Themes/Plugins dasselbe Template überschreiben, gewinnt dasjenige mit der niedrigsten Rangfolge in dieser Liste:

  1. Theme-Überschreibungen (höchste Theme-‘id’ gewinnt)
  2. Plugin-Überschreibungen (neuester alphabetischer Plugin-Name gewinnt)
  3. Kern

Diese Reihenfolge bedeutet auch, dass Sie Plugin-Templates von Themes überschreiben können. Technisch gesehen können Sie auch Theme-Templates von anderen Themes und Plugin-Templates von anderen Plugins überschreiben, aber das Verhalten kann aufgrund der Abhängigkeit vom Plugin-Namen und der Theme-ID überraschend sein.

Wie funktioniert das?

Discourse setzt Templates in der DiscourseTemplateMap zusammen und priorisiert sie. Für lokal platzierte Komponententemplates werden diese Informationen während der App-Initialisierung verwendet, um die Kern-Template-Zuordnungen zu ersetzen. Für alle anderen Templates wird die Map zur Laufzeit vom Resolver verwendet, um das korrekte Template abzurufen.


Dieses Dokument wird versioniert – Änderungen auf github vorschlagen.

17 „Gefällt mir“

Und was ist mit mobilen Vorlagen? Wie ist die Verzeichnisstruktur, um Vorlagen aus dem Kern neu zu schreiben?

Es sollte genau gleich funktionieren – Sie passen den Namen der Kernvorlage an. Wenn sie also /mobile enthält, fügen Sie dies in Ihre Überschreibung ein.

Ich versuche, die mobile login.hbs-Vorlage neu zu schreiben, und es funktioniert nicht Imgur: The magic of the Internet, liege ich mit dem Pfad richtig?

Der vollständige Pfad ist in Ihrem Screenshot, soweit ich sehen kann, nicht sichtbar. Bitte fügen Sie ihn hier als Text ein.

themeroot/javascripts/mobile/modal/login.hbs

Sie haben discourse/templates in Ihrem Pfad vergessen

In Ihrem Fall wäre das also {theme}/javascripts/discourse/templates/mobile/modal/login.hbs

2 „Gefällt mir“

Ist das immer noch der Fall?

Ich bin etwas traurig, dass die Möglichkeit, viel Code zu überschreiben, entfernt wird.

Es ist sinnvoll, das maßgeschneiderte Widget-System bis zu einem gewissen Grad zu ersetzen, aber das gab uns die Möglichkeit, auf mehreren Ebenen in bestehenden Code einzugreifen, wodurch das Risiko von Breaking Changes erheblich reduziert wurde, da wir uns auf kleine Blöcke auf clevere Weise konzentrieren konnten, die es uns ermöglichten:

  • Funktionen hinzuzufügen
  • nichts anderes zu stören.

Ich musste zum Beispiel gerade ZWEI wesentliche Funktionen aus Discourse Journal entfernen, die auf feingranularen Überschreibungen von Widgets basierten, da die einzige Möglichkeit, sie in Glimmer neu zu erstellen, über ein Paar Template-Überschreibungen erfolgte (einschließlich des Versuchs, eine .gjs-Datei zu ändern), was anscheinend nicht mehr unterstützt wird.

Selbst wenn dies unterstützt würde, müssten wir größere Codeabschnitte überschreiben als im Widget-Framework, mit einem damit verbundenen erhöhten Risiko, dass Kernänderungen mit den Überschreibungen in Konflikt geraten.

Das ist nicht gut für die Erweiterbarkeit der Plattform.

Kann man etwas dagegen tun?

7 „Gefällt mir“

Ja, ich verstehe dich – es gab einige nette Dinge an den erweiterbaren Widget-APIs.

Aber die Kehrseite ist, dass es für uns unglaublich schwierig war, IRGENDWELCHE der Widget-basierten Benutzeroberflächen im Kern zu ändern, da wir keine Ahnung hatten, welche zufälligen Methoden/Dekorationen Leute möglicherweise einführen. Deshalb schienen Widget-Anpassungen relativ stabil zu sein – wir hatten zu viel Angst, die Kernimplementierungen anzufassen.

Unsere Lösung dafür für die Zukunft sind Wrapper Plugin Outlets. Diese ermöglichen es Themes und Plugins, optional sehr kleine Vorlagenteile mit ihrer eigenen Implementierung zu überschreiben.

Sehen Sie zum Beispiel, wie Chat bedingt das Home-Logo überschreibt mit einer benutzerdefinierten Komponente. Das funktioniert für das bestehende Widget-basierte Header und den neuen Glimmer-basierten Header (bald verfügbar! :tm:).

Wir sind generell bereit, PRs zu akzeptieren, um neue Wrapper-Outlets an verschiedenen Stellen hinzuzufügen. Wenn Sie sich bei einem bestimmten Anwendungsfall unsicher sind, können Sie gerne ein #dev-Thema mit Details eröffnen!

10 „Gefällt mir“

OK, das klingt nach einem gangbaren Weg, danke.

Ich muss die Auswirkungen davon verdauen und meine Strategie entsprechend anpassen.

Ich schätze die Antwort!

6 „Gefällt mir“