# Code reading help. ES6, plugin-outlet \`\_connectorCache\`, custom-html \`\_customizations\`, appEvents

**URL:** https://meta.discourse.org/t/code-reading-help-es6-plugin-outlet-connectorcache-custom-html-customizations-appevents/112217
**Category:** Development
**Created:** [March 21, 2019, 5:58am UTC](https://meta.discourse.org/t/code-reading-help-es6-plugin-outlet-connectorcache-custom-html-customizations-appevents/112217 "2019-03-21T05:58:51Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Young\_Nam](https://avatars.discourse-cdn.com/v4/letter/y/ea666f/32.png) [@Young\_Nam](https://meta.discourse.org/u/Young_Nam)
#### Post date: [March 21, 2019, 5:58am UTC](https://meta.discourse.org/t/code-reading-help-es6-plugin-outlet-connectorcache-custom-html-customizations-appevents/112217/1 "2019-03-21T05:58:51Z")

</div>

I got a few questions regarding `plugin-outlet`, `custom-html`, `appEvents` in `mount-widget.js` and ES6.

I’ve included some code snippets, and that’s why this post looks too long. It’s code from Discourse source code, not mine. So, it’s guaranteed that you won’t be reading my (hard-to-read) code.

* * *

While trying to read Discourse code, I wanted to try ‘something’ and created my own Rails project and created `javascripts/something.js.es6` and `javascripts/something-else.js`. And imported them in `application.html.erb` with:

```plaintext
    <%= javascript_include_tag 'something-else' %> # loads
    <%= javascript_include_tag 'something' %> # Throws error

```

And apparently, `.es6` throws error. After some googling, I’ve discovered that I could use the `babel-transpiler` gem, but in the Discourse Gemfile, I don’t see `babel-tranpiler` gem being used. Googling “discourse es6” gives me:

[https://meta.discourse.org/t/new-es6-features-via-babeljs/24920](https://meta.discourse.org/t/new-es6-features-via-babeljs/24920)

which links to [this](https://github.com/discourse/discourse/commit/a65e0a80ba27369963d823fa2988780d3ea05a66#diff-8b7db4d5cc4b8f6dc8feb7030baa2478) commit. The Gemfile says it uses `6to5` but I don’t see that either in my Discourse folder.

How do you use ES6 in Discourse?

* * *

`plugin-outlet`.

It seems like the plugin-outlet uses data stored in `Ember.TEMPLATES` to ‘findOutlets’:

```javascript
// app/assets/javascripts/discourse/lib/plugin-connectors.js.es6
function buildConnectorCache() {
  _connectorCache = {};

  findOutlets(Ember.TEMPLATES, (outletName, resource, uniqueName) => {
    _connectorCache[outletName] = _connectorCache[outletName] || [];

    _connectorCache[outletName].push({
      templateName: resource.replace("javascripts/", ""),
      template: Ember.TEMPLATES[resource],
      classNames: `${outletName}-outlet ${uniqueName}`,
      connectorClass: findClass(outletName, uniqueName)
    });
  });
}

```

But I can’t find where and how `Ember.TEMPLATES` is defined. `TEMPLATES` doesn’t seem like a Ember thing.

I did notice that I could prompt `Ember.TEMPLATES` on my Discourse instance, and it contains many entries, more than 450 on my instance. All entries seem like “template” files.

The only occurrence where I see it being defined is:

```ruby
# lib/theme_javascript_compiler.rb
  # TODO Error handling for handlebars templates
  def append_ember_template(name, hbs_template)
    name = name.inspect
    compiled = EmberTemplatePrecompiler.new(@theme_id).compile(hbs_template)
    content << <<~JS
      (function() {
        if ('Ember' in window) {
          Ember.TEMPLATES[#{name}] = Ember.HTMLBars.template(#{compiled});
        }
      })();
    JS
  rescue Barber::PrecompilerError => e
    raise CompileError.new e.instance_variable_get(:@error) # e.message contains the entire template, which could be very long
  end

```

but this function was used in:

```ruby
# app/models/theme_field.rb
  def process_html(html)
...
    doc.css('script[type="text/x-handlebars"]').each do |node|
      name = node["name"] || node["data-template-name"] || "broken"
      is_raw = name =~ /\.raw$/
      hbs_template = node.inner_html

      begin
        if is_raw
          js_compiler.append_raw_template(name, hbs_template)
        else
          js_compiler.append_ember_template(name, hbs_template)
        end

```

Here, I didn’t bother to read more because the file was under `app/models/` that I thought this had something to do with the database.

Is there a function that searches for the template files and assigns to `Ember.TEMPLATES`? And in which file?

* * *

Regarding `custom-html` … I’m getting these questions from trying to read the `application.hbs` by the way.

```javascript
// app/assets/javascripts/discourse/components/custom-html.js.es6
import { getCustomHTML } from "discourse/helpers/custom-html";
...

export default Ember.Component.extend({
  ...

  init() {
    ...
    const html = getCustomHTML(name);

// app/assets/javascripts/discourse/helpers/custom-html.js.es6
let _customizations = {};

export function getCustomHTML(key) {
  const c = _customizations[key];
  if (c) {
    return new Handlebars.SafeString(c);
  }
...
// Set a fragment of HTML by key. It can then be looked up with `getCustomHTML(key)`.
export function setCustomHTML(key, html) {
  _customizations[key] = html;
}

```

In this case VSCode search gives me that `setCustomHTML` isn’t used elsewhere besides the test file.

How is the `_customizations` filled? Or is this because I’m not using any “custom-html”?

* * *

Came up with the question while trying to read `site-header` component.

`appEvents`. I’ve seen:

```javascript
// app/assets/javascripts/discourse/components/mount-widget.js.es6
  dispatch(eventName, key) {
    this._childEvents.push(eventName);

    const caller = refreshArg =>
      this.eventDispatched(eventName, key, refreshArg);
    this._dispatched.push([eventName, caller]);
    this.appEvents.on(eventName, caller);
  },

```

And many `appEvents.on` and `appEvents.off` lines in other files as well. But how is `this.appEvents` ‘injected’ into `mount-widget`?

I’ve only discovered it defined:

```js
// app/assets/javascripts/discourse/widgets/widget.js.es6
export default class Widget {
  constructor(attrs, register, opts) {
    ...
    this.appEvents = register.lookup("app-events:main");

```

and what I’ve discovered, `mount-widget` has connection to the Widget class in `widget.js` only through:

```js
  rerenderWidget() {
    ...
      const newTree = new this._widgetClass(args, this.register, opts);

```

So, in summary “how does `app/assets/javascripts/discourse/components/site-header.js.es6` use `this.appEvents`? I don’t see it defined as a property for `site-header`”

* * *

I’m sorry if the question looks too big, but I thought this would help you understand my confusion.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [March 21, 2019, 10:54am UTC](https://meta.discourse.org/t/code-reading-help-es6-plugin-outlet-connectorcache-custom-html-customizations-appevents/112217/2 "2019-03-21T10:54:25Z")

</div>

Have you read [Developing Discourse Plugins - Part 1 - Create a basic plugin](https://meta.discourse.org/t/beginners-guide-to-creating-discourse-plugins-part-1/30515)? That’s where I’d start.

---

<div class="post-metadata">

### Author: ![Young\_Nam](https://avatars.discourse-cdn.com/v4/letter/y/ea666f/32.png) [@Young\_Nam](https://meta.discourse.org/u/Young_Nam)
#### Post date: [March 21, 2019, 11:32am UTC](https://meta.discourse.org/t/code-reading-help-es6-plugin-outlet-connectorcache-custom-html-customizations-appevents/112217/3 "2019-03-21T11:32:52Z")

</div>

Was it updated? Last time I read:

- it was a beginners guide on how to create and use my plugin
- I don’t think that post talks about `custom-html`

Also I’m curious about how ES6 is loaded.

You could just point me to the file where `_customizations` and `Ember.TEMPLATES` are loaded. Or … just more than one guide page on Discourse.

I’m interested in the source code design, not how to get started on adding my plugins, if you’ve read my question.

Thanks to anyone who could help in advance.

---

<div class="post-metadata">

### Author: ![eviltrout](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/eviltrout/32/5275_2.png) [@eviltrout](https://meta.discourse.org/u/eviltrout)
#### Post date: [March 21, 2019, 1:35pm UTC](https://meta.discourse.org/t/code-reading-help-es6-plugin-outlet-connectorcache-custom-html-customizations-appevents/112217/4 "2019-03-21T13:35:53Z")

</div>

To be clear, you are trying to copy how Discourse’s asset pipeline works in another project?

What Discourse does is very complicated and specific to our use case. Just as an extreme example, we have our own hand-rolled template compiler for our virtual dom library. You don’t want to get lost in that unless you are Discourse.

I would not recommend it for another project. I recommend you use something like [rails-webpacker](https://github.com/rails/webpacker) instead.

---

<div class="post-metadata">

### Author: ![Young\_Nam](https://avatars.discourse-cdn.com/v4/letter/y/ea666f/32.png) [@Young\_Nam](https://meta.discourse.org/u/Young_Nam)
#### Post date: [March 22, 2019, 11:55am UTC](https://meta.discourse.org/t/code-reading-help-es6-plugin-outlet-connectorcache-custom-html-customizations-appevents/112217/5 "2019-03-22T11:55:44Z")

</div>

I see. Just curious where about (like the file names) the “hand-rolled template compiler” and where its output is plugged into. I hope it’s not a hard task to tell me about those file names. Or, I should’ve easily figured it out if I knew how to read code properly 😭
