discourse/app
David Taylor af30536690
DEV: Allow PluginOutlets to 'wrap' a core implementation (#23110)
Our existing PluginOutlet system allows theme/plugin developers to easily insert new content into Discourse.

Another common requirement is to **replace** existing content in Discourse. Previously this could be achieved either using template overrides, or by introducing new content via a PluginOutlet and then hiding the old implementation with CSS. Neither of these patterns are ideal from a maintainability or performance standpoint.

This commit introduces a new mode for PluginOutlets. They can now be used to 'wrap' blocks of content in core. If a plugin/theme registers a connector for the outlet, then it will be rendered **instead of** the core implementation. If needed, outlets can use `{{yield}}` to render the core implementation inside their own implementation (e.g. to add a wrapper element).

In this 'wrapper' mode, only one connector can be registered for each outlet. If more than one is registered, only one will be used, and an error will be printed to the console.

To introduce a new PluginOutlet wrapper, this kind of thing can be added to a core template:

```hbs
<PluginOutlet @name="site-logo" @defaultGlimmer={{true}} @outletArgs={{hash title=title}}>
  <h1>This is the default core implementation: {{title}}</h1>
</PluginOutlet>
```

A plugin/theme can then register a connector for the `site-logo` outlet:

```hbs
{{! connectors/site-logo/my-site-logo-override.hbs }}
<h2>This is the plugin implementation: {{@outletArgs.title}}</h2>
```

Care should be taken when introducing new wrapper PluginOutlets. We need to ensure that

1) They are properly sized. In general it's preferable for each outlet to wrap a small amount of core code, so that plugin/themes only need to re-implement what they want to change

2) The `@outletArgs` are carefully chosen. It may be tempting to pass through lots of core implementation into the outletArgs (or worse, use `this` to pass a reference to the wrapping component/controller). Doing this will significantly increase the API surface area, and make it hard to refactor core. Instead, we should aim to keep `@outletArgs` to a minimum, even if that means re-implementing some very simple things in themes/plugins.
2023-09-25 14:56:06 +01:00
..
assets DEV: Allow PluginOutlets to 'wrap' a core implementation (#23110) 2023-09-25 14:56:06 +01:00
controllers FIX: Return 403 instead of redirect on username routes when hiding profiles (#23545) 2023-09-13 14:33:47 -05:00
helpers DEV: Switch to using standard ember-cli test bundle (#23337) 2023-09-04 17:09:55 +01:00
jobs FEATURE: site settings to revoke api keys older than a number of days (#23595) 2023-09-15 16:31:29 -03:00
mailers FIX: Order tags shown in email subject by topics count and name (#22586) 2023-07-13 15:39:58 +08:00
models DEV: Remove deprecated PostAction.act method (#23641) 2023-09-24 08:16:32 +01:00
serializers FIX: Don't mix up action labels between different reviewables (#23365) 2023-09-06 10:57:30 +08:00
services FIX: Everyone should be aware a cached summary is outdated. (#23438) 2023-09-06 12:09:21 -03:00
views DEV: Stop building test assets in production under Embroider (#23388) 2023-09-11 09:12:37 +01:00