/** A plugin outlet is an extension point for templates where other templates can be inserted by plugins. ## Usage If you handlebars template has: ```handlebars {{plugin-outlet "evil-trout"}} ``` Then any handlebars files you create in the `connectors/evil-trout` directory will automatically be appended. For example: plugins/hello/assets/javascripts/discourse/templates/connectors/evil-trout/hello.hbs With the contents: ```handlebars Hello World ``` Will insert Hello World at that point in the template. Optionally you can also define a view class for the outlet as: plugins/hello/assets/javascripts/discourse/views/connectors/evil-trout/hello.js.es6 And it will be wired up automatically. ## The block form If you use the block form of the outlet, its contents will be displayed if no connectors are found. Example: ```handlebars {{#plugin-outlet "hello-world"}} Nobody says hello :'( {{/plugin-outlet}} ``` **/ var _connectorCache; function findOutlets(collection, callback) { Ember.keys(collection).forEach(function(i) { if (i.indexOf("/connectors/") !== -1) { var segments = i.split("/"), outletName = segments[segments.length-2], uniqueName = segments[segments.length-1]; callback(outletName, i, uniqueName); } }); } function buildConnectorCache() { _connectorCache = {}; var uniqueViews = {}; findOutlets(requirejs._eak_seen, function(outletName, idx, uniqueName) { _connectorCache[outletName] = _connectorCache[outletName] || []; var viewClass = require(idx, null, null, true).default; uniqueViews[uniqueName] = viewClass; _connectorCache[outletName].pushObject(viewClass); }); findOutlets(Ember.TEMPLATES, function(outletName, idx, uniqueName) { _connectorCache[outletName] = _connectorCache[outletName] || []; var mixin = {templateName: idx.replace('javascripts/', '')}, viewClass = uniqueViews[uniqueName]; if (viewClass) { // We are going to add it back with the proper template _connectorCache[outletName].removeObject(viewClass); } else { viewClass = Em.View.extend({ classNames: [outletName + '-outlet', uniqueName] }); } _connectorCache[outletName].pushObject(viewClass.extend(mixin)); }); } export default function(connectionName, options) { if (!_connectorCache) { buildConnectorCache(); } if (_connectorCache[connectionName]) { var view; var childViews = _connectorCache[connectionName]; // If there is more than one view, create a container. Otherwise // just shove it in. if (childViews.length > 1) { view = Ember.ContainerView.extend({ childViews: childViews }); } else { view = childViews[0]; } delete options.fn; // we don't need the default template since we have a connector return Ember.Handlebars.helpers.view.call(this, view, options); } else if (options.fn) { // If a block is passed, render its content. return Ember.Handlebars.helpers.view.call(this, Ember.View.extend({ isVirtual: true, tagName: '', template: function() { return options.hash.template; }.property() }), options); } }