Thought it would be good to start Wiki-ing this:
So you want to extend Discourse functionality but need some guidelines?
DON’T
Put all your code in plugin.rb
If your plugin is anything but very small … it’s harder to find where everything is or determine what the code does.
Override large templates, particularly monolithic ones that contain loops.
Unless absolutely necessary. Templates can change in core without you knowing and can instantly turn a harmless plugin into a module that is blocking an update from core.
This is kind of a bummer because initially they look like a really great way of structuring an amendment.
Only consider this if a template is at or close to the leaf of the template hierarchy or architecturally impossible with a monkey-patch override.
Especially try to avoid doing this for any open-source component. Consider only for client work when the client is informed of the risk.
If you really must get something out to opensource, consider how you might change core in order to permit a monkey-patch and ask Discourse team if they would accept a PR.
Use Observers in Ember without consideration
Observers are expensive computationally, don’t use them unless you really have to.
Add additional libraries
Don’t add additional libraries unless you are absolutely sure you need to add them and things can’t be achieved in other ways with existing components.
DO
Use the Official Ember and Rails guides:
Read the source code and follow its conventions
We call this ‘core’:
https://github.com/discourse/discourse
Use the existing plugins like a library of how-to’s
e.g. https://github.com/paviliondev
Most important technique here: look for something that already does what you want, or similar to what you want and see if following that technique is a help.
Monkey-patch
You can do this with method overrides and component overrides in Ember.
Use helpful methods like super
in Ruby or _super()
in Ember to refer to the original method. This not only reduces the amount of code you have to write, but makes it much more robust to changes in core.
Use Plugin Outlets
There’s a nice Theme Component to show you visually where these are.
Use jQuery
to manipulate DOM elements, especially for modifying classes. In combination with CSS this can be quite powerful.
Use CSS
CSS can save you a lot of coding. Use it in preference to any other method to achieve a result as far as possible
Use modern code form
Use all modern language features to keep code succinct and to match the style of existing code. e.g. use ternary form instead of ugly multi-line kindergarten IF statements, Template Literals and Arrow functions.
Evaluate and reduce the number of condition checks to achieve the result
For example, when applying a jquery based modification, try to apply the mod to the parent component(page) and not to individual child components in order to avoid redundant condition checks.