隐藏子类别而不隐藏其在主题列表中的主题?

大家好,

有没有办法在主题列表中“隐藏”子分类,并在主题标题下方显示父分类?

我想要的效果是:一个根分类下包含 n 个子分类。这些子分类不应在前端显示,仅用于根据用户组权限限制对帖子的访问。

在主题列表中,我希望在主题标题下方显示的是父分类,而不是子分类。

我曾考虑使用标签,但遗憾的是,无法通过这种方式限制对主题的访问。

话题列表中项目的模板仅显示话题所属类别的链接,如下所示:
{{category-link topic.category}}

因此,您需要修改此模板以显示父类别的链接:

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

但如果您只想针对特定的父类别执行此操作,则需要添加更多逻辑。我不确定推荐的做法是什么,是注册一个 Handlebars 辅助函数吗?

另一种方法是始终同时显示类别和父类别链接,然后使用 CSS 隐藏您不需要的链接。

我还没看过,但我觉得你应该可以用 CSS 隐藏它们。

我是否也需要为此方法修改模板?我在管理员设置中找不到相关的站点选项。

父级分类不在默认模板中,所以是的,我猜你需要修改模板。至少我还没发现更轻量的方法来实现这一点。

没有站点设置可以修改模板,我会通过私信把代码发给你试试。

一般来说,您应避免完全覆盖模板,因为它们需要维护——如果 Discourse 更新导致您的主题出现问题,您必须运行差异比较并检查发生了哪些变化。

您可以退一步,改为修改传递给模板的数据。

topic-list-item 是一个 Ember 组件,因此您可以使用 api.modifyClass 来实现您想要的更改。

例如,以下代码片段将在子分类主题标题下方显示父分类徽章。如果主题位于主分类中,则该代码不会生效。

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

  // 父分类 ID
  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

这正是我们要找的。

我已编辑了上面的代码片段以反映该更改。您只需将父分类的 ID 添加到 targetCategoryIds 数组中即可。您可以通过访问分类页面并检查 URL 来获取分类 ID。

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

上面 URL 末尾的"6"是 Meta 上“支持”分类的 ID。

感谢分享,@Johani!我刚接触 Ember,你们真的非常乐于助人!:pray: :relaxed:

太棒了!非常感谢你的快速帮助。

听到这个消息太棒了!

Two Thumbs Up

只需要一点时间适应即可。如果代码库中有任何不清楚的地方,欢迎在 Dev 分类下创建主题并 @我

这真的很棒。感谢你们,也感谢那些抽出时间支持你们的人。

:+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 的帮助,真的很感激!