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.

2 Likes

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.

3 Likes

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:

https://github.com/paviliondev/discourse-events/blob/master/assets/javascripts/discourse/initializers/event-edits.js.es6#L74
Afterwards it can be used int the raw template:
https://github.com/paviliondev/discourse-events/blob/master/assets/javascripts/discourse/connectors/topic-list-after-title/topic-list-event-rsvp.raw.hbs#L5

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.*"
./app/assets/javascripts/discourse/app/templates/flat-button.hbr
./app/assets/javascripts/discourse/app/templates/components/flat-button.hbs
./app/assets/javascripts/discourse/app/components/flat-button.js
merefield@development:~/discourse$ find . -type f -name "topic-list-item.*"
./app/assets/javascripts/discourse/app/templates/mobile/list/topic-list-item.hbr
./app/assets/javascripts/discourse/app/templates/components/topic-list-item.hbs
./app/assets/javascripts/discourse/app/templates/list/topic-list-item.hbr
./app/assets/javascripts/discourse/app/components/topic-list-item.js
merefield@development:~/discourse$ find . -type f -name "topic-post-badges.*"
./app/assets/javascripts/discourse/app/templates/components/topic-post-badges.hbs
./app/assets/javascripts/discourse/app/templates/topic-post-badges.hbr
./app/assets/javascripts/discourse/app/components/topic-post-badges.js

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:

{{topicListItemContents}}

backing Javascript:

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

Sneaky!

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

2 Likes

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