How to customise the header with a plugin?


(Dmitry Demenchuk) #1

I’m trying to make a plugin which will change header into something like this

It doesn’t really matter how does it look, that matters is I don’t want to use customisation on /admin/customize/css_html path. I want to make a plugin which will magically change everything I need.

That I found so far is, there is no template for the header, it renders via virtual-dom.

The way it renders is following:

  1. assets/javascripts/discourse/templates/application.hbs template, which can be overloaded, renders site-header component.

    {{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. assets/javascripts/discourse/components/site-header.js.es6 component extends and returns header widget.

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

    });

    export default SiteHeaderComponent;

  3. assets/javascripts/discourse/widgets/header.js.es6 widget generates virtual-dom for the header.

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

    html(attrs, state) {}
    });

My thoughts

I can create my own widget my-header which will extend existing header, there I’ll just update html. I don’t want to copy-paste anything into it, I want just to override html() method.

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

Then I can create my own my-site-header component which will extend existing site-header with just overriding it to point into my-header widget.

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

Then I override application template to show my-site-header component instead of site-header

/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"}}

The question is, how can I extend all of these components and widgets? Can you please point me to the right way of doing that? Thanks.


(Jeff Atwood) #2

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.


(Dmitry Demenchuk) #3

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;

(Daniela) #4

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


(Dmitry Demenchuk) #5

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.