Custom Layouts Plugin

Separate out the logic you currently have inside the success method of the ajax call. And change all the instances of data.category_list.categories to just categories


          url: "/categories.json",
          dataType: 'json',
          async: false,
          success: function(data) {
            for (var i = 0 ; i < data.category_list.categories.length ; i++) {

Will change to this

const categories = Discourse.Category.list()
for (var i = 0 ; i < categories.length ; i++) {

thank you bot I didn’t mean than.
I mean where should I find a reference of something like Discourse.Category.list(). For example can I get received_likes with just one line code with this?
I have another question, what is the problem with ajax?

Whenever you see the discourse namespace being used in this fashion in the client, it means that the method can be found in the relevant model file. In this case, you will find the Discourse.Category.list() method in the Category model file, here.

You’ll see that that method refers to the property categories on the Site model (Site is a singleton - i.e. there is only ever one instance of it - and the method currentProp is just a method that lets you get a property from a singleton model - see here).

The categories property on the Site model is kept updated from the server by a message bus subscription in an initializer - see here. This subscription subscribes to data on the server when the app initializes and gets updates when the data on the server changes.

When the categories subscription receives data, it updates the categories property on the Site model using the updateCategory method.

The server side of the message bus subscription is here. As you can see, it serializes (i.e. “sends one after another”) the categories (i.e. “self” in the Category model) to the server as JSON.

If you want to see another example of a plugin using the message bus to push data to the client, see here in the topic ratings plugin. That publication pushes ratings data to all clients when one user adds or creates a rating.

You could use your own ajax call in this scenario if you want. However, generally it is a good idea to try and re-use as much existing core discourse infrastructure as possible. You’ll save a lot of time and energy (perhaps not initially but definitely over time), you’ll understand more about how Discourse works and your work will be better able to keep up with changes in the Discourse codebase.


In further response to a question via PM: “How do I get data from the server in a plugin?”

Firstly, before you go trying to get data from the server, check if the data is already available on the client. If its data about the user, a category, a topic list or even a topic, you may already have it on the client and there is no need to add a new call to the server.

Furthermore, if you want extra data about a model you already have on the client, e.g. the user, normally the best way to get that is to add that extra data to the serializer that is already serializing that model to the client. It’s a bit like calling your friend and asking them to pick up something extra from the supermarket while they’re there, rather than going to the supermarket for that one thing yourself. I can elaborate on how to add data to an existing serialization separately.

That said, there are two basic ways to get data from the server in a plugin:

  1. Ajax call. You can call any get route the server already has set up - see the server route file here, or you can create your own get route in a plugin - see here for an example of how to create a new route in a plugin.

  2. Message bus. See previous post for an example of how the message bus works. To see what other message buses you can subscribe to, just do a search for MessageBus in the server code.

If the route or message bus subscription is not already available, you’ll have to create it in your plugin.rb file.


is it somehow possible, to add a sidebar beneath the header/user menu?

What’s the use case you have in mind? You can currently create a banner topic:

Sorry, i forgot to mention that i would like to have that sidebar on a users profile page.
Like, when a user enters his twitter handle, other users will see his twitter feed in this sidebar on his profile page.
But I think I will go with a custom build theme. Tanks anyway :slight_smile: That banner feature looks usefull.


hi Angus,

can the custom layouts and profile widget, work for RTL languages as well?

as when I use the profile widget, it appears in the left direction of a RTL forum which is not a good place.

using the layouts with the option show subcategory list active results in an error and the layout plugin plus the sidebars are hidden.


TypeError: Cannot read property 'get' of null at i (_plugin-third-party-930ad4e….js:2679) at i.value (_plugin-third-party-930ad4e….js:3029) at i.<anonymous> (_application-0483356….js:80) at c.h.get (_ember_jquery-60dedd1….js:15271) at Object.r [as get] (_ember_jquery-60dedd1….js:20094) at i.get (_ember_jquery-60dedd1….js:32651) at i.value [as discoveryDomEdits] (_plugin-third-party-930ad4e….js:3001) at Object.t [as applyStr] (_ember_jquery-60dedd1….js:36010) at Object.f [as sendEvent] (_ember_jquery-60dedd1….js:16116) at w (_ember_jquery-60dedd1….js:20018)


Thanks, should be fixed now.

Yes, I’ll have a look at this soon.


When the width of my browser is less than 1000px, the sidebars disappear but they are still there! I mean the topic-list width doesn’t go back to the full width (look at the red ellipses):

Is it fixable?

Hi @angus Thanks for making this plugin, I have a question, i’m wondering is this a bug or a “feature”.
As soon as I install the plug in my “Black” theme gets a black background, are you aware of this or is it something I can fix?

Kind Regards,

Hey @Nigel_Tatschner. Do you mean your Black theme gets a white background?

There was a css rule that changed the background color of the body. I’ve now removed it.

1 Like

@angus Good man, thank you. i’ll give it a go now.
Have a good day.

1 Like

hm, which widgets are you using there? It looks like the widgets have disappeared, not the sidebars.

This is not an inherent issue, e.g. this is a layout with widgets squeezed to 750px.

1 Like

Just added the plugin back in and it seems to be the content that’s white, not the background.

it dose the same on each color scheme, I think it’s the Main-Content Discovery background.

Sorry Angus, but I couldn’t make use of category setting for the left or right sidebars,

When I activate the widgets for categories globally in the admin panel, things are ok. but I don’t want to see some widgets for some categories, and this way I need to remove them using css selectors.

but if I activate sidebar and widgets using category setting , the widgets do not appear in the category.

is it a bug? or am I missing something?

e.g.: you can see an empty box in the picture, this is a widget which is not supposed to be shown in the latest list. an if is used to remove this widget from the latest, while if we could use the category setting we don’t need to use this if.

I ran into a stupid problem:

I used the setting in the category to disable the “Disable discovery list header for selected routes in this category” and "navigation menu " for a category. Now I’m unable to bring them back, since even the admin can’t see the category setting :frowning:

any way to disable these settings only for non-admins?

Ok I’ve removed all the other background colors that could be the culprit here

1 Like

Yes the route filters were not working properly. Working now.

To use a different widget in a category route, make sure you don’t have category selected in the sidebar enabled site settings as this overrides category-specific settings. If you remove this setting, the sidebars and the widgets for each category are controlled by the relevant category specific settings.