I've been working quite a bit recently on upgrading Discourse's plugin architecture to allow for more complex plugins such as tagger without all the megahacks that were there before.
I've still got a bunch to do but I figured I'd throw out some ideas here and see what plugin authors and the dev team think of them.
Problem: Inserting Content into Templates
Currently, in a plugin if you define a handlebars template with the same name as one in discourse, it will overwrite it. This is okay if the template is simple, but if you just want to add some information to an existing template it is quite onerous.
Potential Solution: Plugin Outlets
In my pluginnew branch, I have added support for the following.
In the main discourse codebase, we can identify points where we will allow templates to be injected into ours.
This can be done as simply as {{plugin-outlet "composer-open"}}
, where composer-open
is a string that identifies the extension point for the plugin.
Then, in a plugin, if you create a connector
, which is a template that will be inserted at that plugin-outlet
. You identify a connector by putting it in a directory called connectors/composer-open
or whatever the name of the plugin-outlet
was. So for the tagger work I'm doing, I called the file connectors/composer-open/tags.js.handlebars
and put in the tag specific handlebars to be inserted into the composer when it's open.
Another advantage to this is that multiple plugins can insert templates into the same outlet. It will just append them sequentially.
Problem: Explicitly Declaring all your javascript files is annoying
Right now you have to make a call to register_asset
for every javascript file you include. This is tedious, and annoying if you ever rename or move a file.
Potential Solution: Automatically include every javascript file
I am afraid that if I include this it might break some plugins, so for now I have restricted it to .es6
files only as they are pretty new. In the latest master if you put an .es6
file in your project, it will be included automatically. I would love to hear thoughts on whether there is a good reason to NOT include all javascript by default.
Problem: How to extend classes using ES6 modules?
I am in the process of converting Discourse's javascript code base to use ES6 modules. I am currently restricting this to 30 minutes of work a day, but it's coming along and before we know it we'll be using ES6 modules for everything.
One issue with these modules is the code inside them is not executed automatically. So if you are used to calling reopen
or reopenClass
on something to add more functionality it will not happen.
Solution: Use an initializer
If you put a file in the initializers
folder that returns an Ember initializer, it will be executed when the application starts up. Just return a plain old Javascript object with a name
field and a initialize
function. Do your class modifications in there and everything will work nicely!
I'd love to hear thoughts on this so let me know what you think before I merge it into master.