Скрыть подкатегории, не скрывая их темы в списке тем?

Привет, ребята!

Есть ли способ «скрыть» подкатегории из списков тем и вместо этого отображать родительские категории под заголовком темы?

Мой желаемый результат — корневая категория с n подкатегориями. Эти подкатегории не должны отображаться на фронтенде. Они используются только для ограничения доступа к сообщениям в зависимости от членства в группах.

В списке тем я хочу отображать родительскую категорию под заголовком темы вместо подкатегории.

Я думал об использовании тегов, но, к сожалению, я не могу ограничить доступ к темам таким образом.

Шаблон для элементов в списке тем показывает только ссылку на категорию темы, например:
{{category-link topic.category}}

Поэтому вам нужно изменить этот шаблон, чтобы отображать ссылки на родительскую категорию:

{{#if topic.category.parentCategory}}
  {{category-link topic.category.parentCategory}}
{{else}}
  {{category-link topic.category}}
{{/if}}

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

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

Я не смотрел, но, думаю, вы сможете скрыть их с помощью CSS.

Мне также нужно изменить шаблон для этого подхода? Я не смог найти такую настройку сайта в своей админ-панели.

Родительские категории отсутствуют в шаблоне по умолчанию, так что да, полагаю, вам придётся изменить шаблон. По крайней мере, я не знаю более лёгкого способа этого добиться.

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

В целом, следует избегать полной замены шаблонов, так как они требуют поддержки: если обновление Discourse нарушает работу вашей темы, вам придется сравнивать версии (diff) и проверять, что изменилось.

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

topic-list-item — это компонент Ember, поэтому вы можете использовать api.modifyClass, чтобы внести нужные изменения.

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

<script type="text/discourse-plugin" version="0.8">
  const { on } = require("discourse-common/utils/decorators");

  // идентификаторы родительских категорий
  const targetCategoryIds = [9, 15, 50];

  const useParentCategory = function () {
    const parentCategory = this.attrs.topic.category.parentCategory;
    const switchToParent = parentCategory && targetCategoryIds.includes(parentCategory.id);

    if (switchToParent) {
      this.attrs.topic.set("category", parentCategory);
    }
  };

  api.modifyClass("component:topic-list-item", {
    @on("didReceiveAttrs")
    setCategory() {
      useParentCategory.call(this);
    }
  });

  api.modifyClass("component:latest-topic-list-item", {
    @on("didReceiveAttrs")
    setCategory() {
      useParentCategory.call(this);
    }
  });
</script>

Это потрясающе!

Есть ли способ ограничить его одной или несколькими конкретными категориями?

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

  1. Все подкатегории в родительской категории «foo» должны иметь такое поведение.
  2. Некоторые подкатегории в разных родительских категориях должны иметь такое поведение.

@Johani

Именно это мы и искали.

Я отредактировал приведенный выше фрагмент, чтобы отразить это изменение. Всё, что вам нужно сделать, — добавить идентификаторы родительских категорий в массив targetCategoryIds. Идентификатор категории можно найти, посетив страницу категории и проверив URL.

 https://meta.discourse.org/c/support/6

«6» в конце приведенного выше URL — это идентификатор категории «Поддержка» здесь, на Meta.

Спасибо за то, что поделились этим, @Johani! Я только начинаю работать с Ember… вы действительно очень помогаете! :pray: :relaxed:

Это потрясающе! Большое спасибо за быструю помощь.

Это замечательно!

Два больших пальца вверх

К этому нужно просто немного привыкнуть. Если что-то в коде непонятно, не стесняйтесь создать тему в категории Development и отметить меня.

Это действительно здорово. Спасибо за это и спасибо тем, кто уделяет вам время на это.

:+1:

@Johani Где именно мне нужно вставить этот фрагмент кода?
Я пытался вставить его в </head> и в часть заголовка компонента моей темы, где я храню все свои CSS-стили. Но тогда список тем обрезается ровно в том месте, где должен быть показан первый затронутый топик из подкатегории.

Да, была проблема с тем, как была настроена категория, которую я упустил локально. Я отредактировал фрагмент кода выше, и теперь он должен работать.

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

<script type="text/discourse-plugin" version="0.8">
  const { on } = require("discourse-common/utils/decorators");

  const useParentCategory = function () {
    const parentCategory = this.attrs.topic.category.parentCategory;

    if (parentCategory) {
     this.attrs.topic.set("category", parentCategory);
    }
  };

  api.modifyClass("component:topic-list-item", {
    @on("didReceiveAttrs")
    setCategory() {
      useParentCategory.call(this);
    }
  });

  api.modifyClass("component:latest-topic-list-item", {
    @on("didReceiveAttrs")
    setCategory() {
      useParentCategory.call(this);
    }
  });
</script>

Спасибо @Johani за вашу помощь, я очень это ценю!