Shortly I will be merging a branch of Discourse into master that updates us to the latest stable version of Ember, which is 2.10. This is exciting because we’ve been behind Ember’s stable branch for a while and we’ve finally caught up! It also contains the Glimmer 2 template engine which is quite a bit faster so the application should be more responsive, and it also cuts down on our template file sizes so the app should be quicker to download.
However, there is a downside, and that I wasn’t able to get plugin outlets to work with 100% backwards compatibility due to internal changes in Ember.
What’s changed with Plugin Outlets
Previously, if your plugin made a connector to a {{plugin-outlet}}
, you’d have the exact same scope in the handlebars document as where the outlet was declared. In the latest release, you will only have access to variables that are explicitly passed in to the outlet. I’ve gone through every plugin outlet in the codebase and passed in the main models and variables so if you were using those you should be OK. However, if you were using unusual or rare variables from the template you might have to update your code.
The most likely thing to break in your plugins is if you added data to a template by extending a controller and not a model, as they won’t be passed into your connector anymore. Fortunately, there’s a straightforward way to fix that:
New in Discourse: Connector Classes
You can now optionally define a class that will be associated with your connector.
Let’s say your connector was defined in my-plugin/templates/connectors/user-profile-controls/my-connector.hbs
. You could create the following class:
my-plugin/connectors/user-profile-controls/my-connector.js.es6
export default {
setupComponent(args, component) {
component.set('today', new Date());
}
}
When your connector is inserted to the outlet, it will call the setupComponent
method and you will get access to the plugin’s arguments (such as models) and you can call set
on it to make variables available in your template.
A new feature is you can define a method called shouldRender
which will determine if the connector will be inserted into the template. This is useful because previously all connectors had to be inserted, which made working with <ul>
and <li>
tags complicated:
my-plugin/connectors/user-profile-controls/my-connector.js.es6
export default {
// if false the plugin won't be rendered
shouldRender(args, component) {
return component.siteSettings.my_plugin_enabled;
}
}
Finally, you can also declare actions
in your component class. This is much simpler than using an initializer to extend the controller and defining the actions there. If you have added any actions to controllers you’ll need to move them into component classes.
my-plugin/connectors/user-profile-controls/my-connector.js.es6
export default {
actions: {
myAction() {
console.log('my action triggered');
}
}
}
Upgrade Schedule
I’ve been reviewing all the officially supported plugins as well as many popular plugins to make sure they can be updated for this change. Once I’m confident that everything is working I’ll be merging this into the master
/ tests-passed
branches of Discourse. This should happen either this afternoon or first thing Tomorrow morning. After that, we’ll keep a close eye on it before we merge it into our next beta.
The change is due to be in our next stable release, which should be available in early January.
The faster you upgrade your plugins, the better! If you need some help or find a bug in a common plugin just let me know and I’ll fix it as soon as possible.