Correct. There are two ways to go about it…
-
You can make your customization a widget, and then mount the widget in the plugin outlet like this:
{{mount-widget widget="widget-name"}}
You can see an example of how a widget is created in Discourse, for example the home logo: discourse/app/assets/javascripts/discourse/app/widgets/home-logo.js at 2dbcea9eeeb816dda347027497b3a49634ef851f · discourse/discourse · GitHub
In a theme you’d add your
widget-name.js
file to ajavascripts/discourse/widgets
directoryThere’s more about widgets in A tour of how the Widget (Virtual DOM) code in Discourse works, but note that we’re going to gradually phase out widgets so anything you learn in this process won’t be useful long-term.
-
Keep your widget decorator as-is, and create a separate Ember component that does what you want in the plugin outlet. We’ve been phasing out widgets in favor of Ember components (which is what most of Discourse is built on).
This process would look like:
- Create a component JS and HBS (template) file in your theme’s
javascripts/discourse/components
directory.
-
component-name.js
-
component-name.hbs
- Build your Ember component… unfortunately this step is essentially “learn Ember” (Ember Guides) … but I think this might give you a rough idea to start:
- In
component-name.js
:
import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { action } from "@ember/object"; const endpoint = settings.site_navigation_links_endpoint; export default class ComponentName extends Component { @tracked navLinks = null; @action async fetchNavLinks() { try { const response = await fetch(endpoint); const data = await response.json(); // assuming this is json this.navLinks = data; } catch (error) { console.error("Failed:", error); } } }
- In
component-name.hbs
:
<div {{did-insert this.fetchNavLinks}}> {{#each this.navLinks as |link|}} <a href={{link.anchor}}>{{link.title}}</a> {{/each}} </div>
This will call the
fetchNavLinks
action whenever the component is inserted (in this case, when you visit the Discourse site and the app renders). WhenevernavLinks
is updated, the content of the component will update because it’s a tracked property.If you want to update the links more often than on component render you’ll need to add some more logic to the JS here… checking if the current route (page) meets certain conditions for example.
- This component would be added to a plugin outlet by adding it to the outlet in
javascripts/discourse/connectors/below-site-header/my-component-connector.hbs
:
<ComponentName />
- Create a component JS and HBS (template) file in your theme’s