Wie kann man den Header mit einem Plugin anpassen?

Ich versuche, ein Plugin zu erstellen, das den Header so verändert:


Es ist nicht wirklich wichtig, wie es aussieht. Wichtig ist, dass ich keine Anpassungen über den Pfad /admin/customize/css_html vornehmen möchte. Ich möchte ein Plugin erstellen, das alles, was ich brauche, magisch verändert.

Bisher habe ich herausgefunden, dass es keine Vorlage für den Header gibt; er wird über Virtual-DOM gerendert.

Die Renderweise ist folgende:

  1. Die Vorlage assets/javascripts/discourse/templates/application.hbs, die überschrieben werden kann, rendert die Komponente site-header.

    {{plugin-outlet “above-site-header”}}
    {{site-header canSignUp=canSignUp
    showCreateAccount=“showCreateAccount”
    showLogin=“showLogin”
    showKeyboard=“showKeyboardShortcutsHelp”
    toggleMobileView=“toggleMobileView”
    toggleAnonymous=“toggleAnonymous”
    logout=“logout”}}
    {{plugin-outlet “below-site-header”}}

  2. Die Komponente assets/javascripts/discourse/components/site-header.js.es6 erweitert und gibt das Widget header zurück.

    const SiteHeaderComponent = MountWidget.extend(Docking, {
    widget: ‘header’,
    ..
    });

    export default SiteHeaderComponent;

  3. Das Widget assets/javascripts/discourse/widgets/header.js.es6 generiert Virtual-DOM für den Header.

    export default createWidget(‘header’, {
    tagName: ‘header.d-header.clearfix’,

    html(attrs, state) {}
    });

Meine Überlegungen

Ich kann mein eigenes Widget my-header erstellen, das das bestehende header erweitert. Dort werde ich einfach die html()-Methode aktualisieren. Ich möchte nichts kopieren und einfügen, sondern lediglich die html()-Methode überschreiben.

/plugins/discourse-foo/assets/javascripts/discourse/widgets/my-header.js.es6

Dann kann ich meine eigene Komponente my-site-header erstellen, die die bestehende site-header erweitert, indem sie einfach auf das my-header-Widget verweist.

/plugins/discourse-foo/assets/javascripts/discourse/components/my-site-header.js.es6

Anschließend überschreibe ich die Vorlage application, um die Komponente my-site-header anstelle von site-header anzuzeigen.

/plugins/discourse-foo/assets/javascripts/discourse/templates/application.hbs

{{plugin-outlet "above-site-header"}}
{{my-site-header canSignUp=canSignUp
              showCreateAccount="showCreateAccount"
              showLogin="showLogin"
              showKeyboard="showKeyboardShortcutsHelp"
              toggleMobileView="toggleMobileView"
              toggleAnonymous="toggleAnonymous"
              logout="logout"}}
{{plugin-outlet "below-site-header"}}

Die Frage ist: Wie kann ich all diese Komponenten und Widgets erweitern? Könntest du mich bitte auf den richtigen Weg weisen? Danke.

Based on the screenshot, this seems like something that is plausible to do with just CSS customizations. That would also be much simpler than writing a plugin and would not require updating with new versions of Discourse code.

Well, I knew you going to say that, that’s why I mentioned that I need a plugin :slight_smile:

First of all, because I want to learn how to do plugins, I’ll have to do whole lot more complicated things later. That menu is just an example.

Secondly, I really need that menu to be a plugin, because:

  1. We may reuse it on different projects;
  2. We need a version control, to roll back sometimes;
  3. Some links will be generated from external json;
  4. I want a clean solution. I believe doing it with a plugin is a clean solution;

Sitepoint use a plugin to override the header.
Take a look here:

Thank you for your link, it will be definitely interesting to see how other people are doing it.

As I see now, they are not extending existing header widget. They just copy-pasted it from the core and customised it.
In that case they have to support that code themselves, and Discourse most likely to break it on next update.