Запрос обратной связи: компонент отображения тегов в списках тем — раскрытие/сворачивание тегов в списках тем

Вы используете это в классе. В противном случае это не сработает.

Тогда вам нужно написать 3.6.0.beta1, иначе в данный момент никто не сможет его установить.

Я немного проверил. Действительно, простого способа достичь этого нет; однако я нашел интересный и упрощенный метод с использованием API.

  • Он использует модель темы для изменения того, какие видимые теги будут выведены до генерации шаблона. Это означает отсутствие манипуляций с DOM и независимость от настроек. В зависимости от состояния (revealTags) он вернет либо исходный список, либо его часть.

  • Для создания кнопки переключения используется API для добавления тега с HTML-кодом кнопки (к сожалению, здесь нет точки расширения плагина). Событие клика обрабатывается отдельно. При клике обновляется состояние переключения (revealTags), и мы запускаем повторный рендеринг списка тегов.

Главное преимущество этого подхода в том, что вам не нужно возиться с HTML и выяснять, что показывать/скрывать с помощью CSS, исходя из различных стилей.

chrome_lSKqwYt5Z7

Делюсь здесь своим тестовым кодом:

import { apiInitializer } from "discourse/lib/api";
import { i18n } from "discourse-i18n";
import { computed } from "@ember/object";

export default apiInitializer((api) => {
  const siteSettings = api.container.lookup("service:site-settings");

  const maxVisibleTags = Math.min(
    settings.max_tags_visible,
    siteSettings.max_tags_per_topic
  );

  let topicModels = {};

  api.modifyClass(
    "model:topic",
    (Superclass) =>
      class extends Superclass {
        revealTags = false;

        init() {
          super.init(...arguments);
          topicModels[this.id] = this;
        }

        @computed("tags")
        get visibleListTags() {
          if (this.revealTags) {
            return super.visibleListTags;
          }
          return super.visibleListTags.slice(0, maxVisibleTags);
        }
      }
  );

  api.addTagsHtmlCallback(
    (topic, params) => {
      if (topic.tags.length <= maxVisibleTags) {
        return "";
      }

      const isExpanded = topic.revealTags;
      const label = isExpanded
        ? i18n(themePrefix("js.tag_reveal.hide"))
        : i18n(themePrefix("js.tag_reveal.more_tags"), {
            count: topic.tags.length - maxVisibleTags,
          });

      return `<a class="reveal-tag-action" role="button" aria-expanded="${isExpanded}">${label}</a>`;
    },
    {
      priority: siteSettings.max_tags_per_topic + 1,
    }
  );

  document.addEventListener("click", (event) => {
    const target = event.target;
    if (!target?.matches(".reveal-tag-action")) {
      return;
    }

    event.preventDefault();
    event.stopPropagation();

    const element =
      target.closest("[data-topic-id]") ||
      document.querySelector("h1[data-topic-id]");
    const topicId = element?.dataset.topicId;
    if (!topicId) {
      return;
    }

    const topicModel = topicModels[topicId];
    if (!topicModel) {
      return;
    }

    topicModel.revealTags = !topicModel.revealTags;
    topicModel.notifyPropertyChange("tags");
  });
});
.reveal-tag-action {
  background-color: var(--primary-50);
  border: 1px solid var(--primary-200);
  color: var(--primary-800);
  font-size: small;
  padding-inline: 3px;
}

.discourse-tags__tag-separator:has(+ .reveal-tag-action) {
  visibility: hidden;
}