Не удается разместить шаблон в нужном слоте

Я пытаюсь разместить шаблон в конкретном слоте плагина в файле javascripts/discourse/initializers/persistent-banner.gjs.
Код:

import Component from "@glimmer/component";
import { apiInitializer } from "discourse/lib/api";

banner_plugin_outlet = settings.banner_position

export default apiInitializer("1.14.0", (api) => {
  try {
    banner_plugin_outlet = settings.banner_position
    api.renderInOutlet(
      banner_plugin_outlet,
      class persistentbanner extends Component {
        get bannerIsFilled() {
          if (settings.banner_text_content == "") {
            return false;
          } else if (settings.banner_visible == "hide") {
            return false;
          } else {
            return true;
          }
        }
        <template>
          {{#if this.bannerIsFilled}}
            <div class='persistent-banner'>
              <p>
                {{html_safe (theme-setting 'banner_text_content')}}
              </p>
            </div>
          {{/if}}
        </template>
      } 
    );
  } catch (e) {
    console.log(e);
  }
}

Однако HTML внутри тега <template> не отображается в указанном слоте. Более того, он вообще не отображается. Что я делаю не так?
Ссылка на репозиторий: GitHub - NateDhaliwal/discourse-persistent-banner: A theme component for Discourse that cannot be closed by the user. · GitHub

Не используйте инициализатор для этого? Используйте папку connectors. Там множество примеров.

Причина в том, что можно выбрать разные выходы.
Я адаптировал этот код из репозитория Notification Banner.

А, понял. Да, это имеет смысл. Извини, я не был уверен в твоей функциональной задумке. Мне следовало внимательнее изучить код.

Вот несколько советов, чтобы снова запустить проект:

  • В этом файле в конце вызова apiInitializer отсутствует закрывающая круглая скобка — это просто не сработает.

После исправления этой проблемы я вижу ещё ошибки.

  • banner_plugin_outlet не объявлен — здесь нужен const.

    Вы присваиваете его дважды? Скорее всего, вам не нужно делать это дважды :slight_smile:

    banner_plugin_outlet = settings.banner_position
    
    export default apiInitializer("1.14.0", (api) => {
      try {
        banner_plugin_outlet = settings.banner_position
    
  • Вам не хватает импортов:

    import { htmlSafe } from "@ember/template";
    import themeSetting from "discourse/helpers/theme-setting";
    
  • … но мне не удалось заставить themeSetting работать как хелпер здесь. Ошибки нет, просто пусто, поэтому попробуйте вместо этого этот код:

            get bannerTextContent() {
              return settings.banner_text_content;
            }
            <template>
              {{#if this.bannerIsFilled}}
                <div class='persistent-banner'>
                  <p>
                    {{htmlSafe this.bannerTextContent}}
    
  • Всегда проверяйте консоль на наличие ошибок.

Я импортировал htmlSafe, и это сработало как по волшебству!
Огромное спасибо!

Да, хелпер не работает (и не нужен) в gjs. Определение геттера — это нормально. Но если вы хотите избежать этого, вы можете обратиться к глобальной переменной settings напрямую из шаблона:

<template>
  {{htmlSafe settings.banner_text_content}}
</template>

Спасибо. Это не выглядело особенно прозрачно! :sweat_smile:

Да, это справедливо. Давайте улучшим сообщения об ошибках:


Спасибо. Это действительно помогает улучшить опыт разработчика.

Как мы знаем, он значительно улучшился с переходом на .gjs вместо виджетов.

однако

При использовании компонентов gjs возникает множество очень странных ошибок, которые сильно затрудняют поиск проблем.

Например, если допустить ошибку в имени хелпера:
{{html_safe this.bannerTextContent}}

Это приводит к классической ошибке:

program.js:100 Uncaught (in promise) TypeError: Invalid value used as weak map key at WeakMap.set (<anonymous>)

(Это также происходит, даже если имя корректно, но вы забыли импорт)

Что?! :sweat_smile: Примеров таких случаев очень много.

Полагаю, это обратная сторона использования фреймворка?

Ой, это серьёзная ошибка!

Когда я запускаю это локально, я вижу:

Где вы увидели ошибку WeakMap? На рабочем сайте? Если да, то, возможно, это одна из проверок, которые Ember исключает из продакшн-сборок для повышения производительности.

Если есть возможность, я всегда рекомендую разрабатывать темы и плагины в полноценной среде разработки — в таких случаях, как этот, процесс будет проходить гораздо лучше.

Да, производственный сайт использует Theme CLI ( что, я полагаю, является одним из его недостатков, несмотря на то, что в остальном это отличный рабочий процесс?)

Это имеет полный смысл.

Да, с плагинами это мой стандартный выбор, но с TCs есть сильное искушение разрабатывать их на производственном сайте из-за мгновенной обратной связи (хотя она не всегда очень полезна!)

Но я только что понял: через CLI можно подключиться к localhost, и это работает.

Так что, конечно же!

image

Я буду использовать это в дальнейшем! :rocket:

Не понимаю, почему я думал, что это невозможно :blush: :sweat_smile:

Как всегда, спасибо за помощь, которая сэкономила мне много времени (в будущем :slight_smile: )

Да! Локальный хост с theme-cli — это именно то, как я стараюсь работать, и то, что я рекомендую другим. Мы определённо можем улучшить документацию по этим рекомендуемым рабочим процессам :eyes:

Ещё один совет: discourse.theme-creator.io работает с ассетами Ember в режиме разработки. Так что там тоже должны быть более подробные сообщения об ошибках.