Как вручную добавить содержимое в pluginOutlet после AJAX-запроса? И как перерендерить или обновить pluginOutlet?

Верно. Есть два способа решить эту задачу…

  1. Вы можете сделать вашу кастомизацию виджетом, а затем подключить этот виджет в pluginOutlet следующим образом:

    {{mount-widget widget="widget-name"}}
    

    Вы можете увидеть пример создания виджета в Discourse, например, логотип на главной странице: discourse/app/assets/javascripts/discourse/app/widgets/home-logo.js at 2dbcea9eeeb816dda347027497b3a49634ef851f · discourse/discourse · GitHub

    В теме вы добавите свой файл widget-name.js в директорию javascripts/discourse/widgets.

    Подробнее о виджетах читайте здесь: A tour of how the Widget (Virtual DOM) code in Discourse works, но обратите внимание, что мы постепенно отказываемся от виджетов, поэтому любые знания, полученные в этом процессе, не будут полезны в долгосрочной перспективе.

  2. Оставьте ваш декоратор виджета без изменений и создайте отдельный компонент Ember, который выполнит то, что вам нужно, в pluginOutlet. Мы отказываемся от виджетов в пользу компонентов Ember (на которых построена большая часть Discourse).

    Этот процесс выглядит следующим образом:

    1. Создайте файлы JS и HBS (шаблон) компонента в директории javascripts/discourse/components вашей темы.
    • component-name.js

    • component-name.hbs

    1. Создайте компонент Ember… к сожалению, этот шаг по сути означает «изучить Ember» (Руководство по Ember), но, думаю, это даст вам общее представление для начала:
    • В 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(); // предполагается, что это JSON
          this.navLinks = data;
        } catch (error) {
          console.error("Ошибка:", error);
        }
      }
    }
    
    • В component-name.hbs:
    <div {{did-insert this.fetchNavLinks}}>
     {{#each this.navLinks as |link|}}
       <a href={{link.anchor}}>{{link.title}}</a>
     {{/each}}
    </div>
    

    Это вызовет действие fetchNavLinks всякий раз, когда компонент вставляется (в данном случае, когда вы посещаете сайт Discourse и приложение рендерится). Всякий раз, когда navLinks обновляется, содержимое компонента также обновляется, так как это отслеживаемое свойство.

    Если вы хотите обновлять ссылки чаще, чем при рендеринге компонента, вам нужно добавить в JS дополнительную логику… например, проверку того, соответствует ли текущий маршрут (страница) определенным условиям.

    1. Этот компонент будет добавлен в pluginOutlet путем добавления его в коннектор в javascripts/discourse/connectors/below-site-header/my-component-connector.hbs:
    <ComponentName />