What is the difference between raw.hbs handlerbar files and only .hbs handlerbar files?

I noticied that few plugin outlet like topic-list-after-title require raw.hbs file
while other require only hbs file.

I did search in the handlebars documentation, but I could see anything as raw hbs file.

I checked in the discourse code, plugin outlet like topic-list-after-title are defined as

{{raw-plugin-outlet name="topic-list-after-title"}}

while other plugins are defined as

{{plugin-outlet name="composer-fields-below" args=(hash model=model)}}

Q1. Is there any reason why some plugin plugin are defined in above way ( raw-plugin-outlet) ?

Also I noticied that in the raw.hbs file, the setupcomponent is not called as explained in this link

Q2. Is it so? I had also asked similar question regarding this.


I would be interested in this as well. Did you find the answer yet? :grinning:

Raw templates are a performance optimisation. Only partial ember view features exists, removal of features is what makes it faster.

Hence we use a different pattern here for extensibility. We don’t have the full ember lifecycle.


Is there something similar to setupComponent(args, component) with the raw outlets as well? What about computed properties? I would like to do some computations based on the data in context. How can I go about this? I dont even know if I named my accompanying .js.es6 file right. Should I name it .raw.js.es6?

SetUpComponent not being called for topic list tags plugin outlet - #3 by net_deamon
Okay I found the solution: reopen the Topic model and create a computed property there:

Afterwards it can be used int the raw template:

1 Like

I have the same question.

Is it possible to ‘back’ a raw template with corresponding javascript as per regular Components, within a Theme Component.

I’ve got quite a challenging use-case and I need to manage actions to pass arguments back up the component chain from a deeply embedded template within the topic list.

I note there are several .hbr files with apparently corresponding Javascript Component elements in the Discourse source but noticed something odd, e.g.:

merefield@development:~/discourse$ find . -type f -name "flat-button.*"
merefield@development:~/discourse$ find . -type f -name "topic-list-item.*"
merefield@development:~/discourse$ find . -type f -name "topic-post-badges.*"

There appears to be several instances, therefore, where there are .hbr and .hbs flavours of a specific Component?

Ah, at least with topic-list-item I see the switch is made here:

Contents of hbs file:


backing Javascript:

  renderTopicListItem() {
    const template = findRawTemplate("list/topic-list-item");
    if (template) {
        template(this, RUNTIME_OPTIONS).htmlSafe()
      schedule("afterRender", () => {
        if (this.selected && this.selected.includes(this.topic)) {
          this.element.querySelector("input.bulk-select").checked = true;


So this suggests hbr files do not have underlying javascript files, unless supported by this kind of workaround?

1 Like

Yes, I believe this is the case. If there’s another way, I haven’t seen it!

1 Like

That observer is not ideal as we are trying to get away from them as we continue to upgrade Ember. I think a better way is to create a helper and put your JS in there. Here is an example


In some recent work, I’ve needed some of the template “tree” to be able to communicate data up from a leaf template using closure actions, so I’ve switched some of the hbr’s to hbs’s to support his.

The work is experimental and I appreciate this will have a performance impact, but after iterating the design a few times was unable to find an alternative way of doing this whilst keeping “in-framework”.

Can you not pass functions into a helper, and call them there? I don’t think I’ve tried this but I imagine you could do it.

1 Like

Specifically, I’m determining properties of an image in a leaf component, then storing them as properties of the grandparent to influence styling that must persist beyond the current list render. The data definitely has to pass up. If a helper can achieve that that sounds like a good option if I get stuck with current approach, thanks!

1 Like