根据用户所属群组显示不同主题内容?

我正在使用 discourse.org 的托管服务,所以在此情况下无法使用插件。想象一下我发布了一个任何人都可以看到的主题。

如果某人属于“A”组,我希望他们看到内容。如果不是,我希望他们看到其他内容。有些内容是每个人都应该看到的。示意图如下……

这是每个人都看到的内容。

{愿望:仅限 A 组成员}
嘿,感谢您加入特别小组!
{/愿望}

{愿望:仅限不在 A 组成员}
嘿,我们有一个特别小组可以加入。[了解更多信息](…)
{/愿望}

我很有信心(但忘记了具体如何操作)可以通过主题组件为我想“切换”显示的内容设置 CSS 类来实现这一点。如果这是我能想到的最好的方法,我会这样做的。

但是 CSS display: none 是比较弱的方法。我希望从 DOM 中移除他们不应该看到的内容。如果可能的话,最好是在服务器端移除,但我至少可以接受在浏览器端通过 j/s 移除。(这比 CSS 中的 display: none 需要更高的技巧水平才能绕过。)

2 个赞

bump!没人回复吗?:~(

为什么我们不能标记 @team :wink:

我现在没有太多时间深入研究,但这个主题组件可能会有所帮助,因为它会列出当前用户的所有组,我认为是在 body 标签中。然后您可以使用 CSS 选择器,根据 body 标签中是否存在某些组类名来显示/隐藏。

并结合这篇关于您可以在编辑器中使用哪些 HTML 元素以及如何将编辑器文本包装在类中的帖子的信息,这可能会奏效:

是的,我在这里测试了一下,如果您将该组件与类似以下内容结合使用,它应该会起作用:

<span data-group-a>仅限 A 组的文本</span>
<span data-group-b>仅限 B 组的文本</span>

然后有 CSS 选择器执行类似以下操作:

span[data-group-a] {display: none;}
body.group-a span[data-group-a] {display: block;}

或者类似的东西……

抱歉进行了所有编辑。我刚刚在我的一台实例上进行了测试,它确实有效。

但是,正如您所提到的,也许这并不是您想要的 :slight_smile:

这可能可以通过主题 JavaScript 来实现,在 head 部分添加一些内容来选择元素并删除它。仍然可能需要上面的 span 和包装,但通过它删除。

3 个赞

好的,我意识到我可能还需要这个,所以我对此进行了更深入的研究 :slight_smile:

这段代码还不能正常工作,而且不太美观,但我认为它几乎可以放入主题的 <head> 部分了,只需要找到使用 JS 选择元素的正确方法:

  <script type="text/discourse-plugin" version="0.8.42">

  api.decorateCookedElement(
    element => {
      var hasGroupA = document.body.classList.contains('group-a');

      const group_a_spans = element.querySelectorAll("span[data-group-a]");

      if (!group_a_spans.length) {
        return;
      }

      if (!hasGroupA) {
        group_a_spans.forEach(function (el) {
           el.innerHTML = "";
        });
      }

      },
      { id: "THEME-ID", onlyStream: true }
   );
  </script>

注意:我认为隐藏所有信息(例如搜索引擎抓取等)可能很困难,所以虽然这比仅通过 CSS 隐藏要好,但我认为它并不能完全阻止人们看到信息。

编辑:已修复,CSS 选择器现在应该可以工作了。为要使用的每个组重复代码。将 THEME-ID 更改为唯一名称。我认为这应该有效 :slight_smile:

哎呀,还没弄懂这部分:

3 个赞

我真的很感激你在这方面的努力……我还在考虑这件事,我觉得你已经给了我一个可行的解决方案。我有一个我写的模板组件,这让我想我可以让类似的东西奏效……

假设我设想一个名为“foobar”的组件。我可以写一个主题,添加一些像这样的 DIV……

<div data-custom="foobar" data-foobar="<groupname>">
</div>
<div data-custom="foobar" data-foobar="!<groupname>">
</div>

然后该组件会根据查看用户所属的组,从 DOM 中删除其中一个 DIV。

这比 CSS display: none; 更强大,因为后者可以通过任何网页浏览器的 DOM 检查功能轻易地恢复。要绕过这一点,人们必须修改页面加载时运行的 j/s——这是可能的,但要困难得多。

为什么我想要这个?

这样我就可以向不属于该组的人部分公开内容。(因为加入该组需要付费订阅。)

这是一个非常酷的主题。第一个
段落非常有趣。

<div data-custom="foobar" data-foobar="<groupname>">
这是其余内容。
</div>

<div data-custom="foobar" data-foobar="!<groupname>">
嗨,抱歉打断!
这里有更多内容供我们的付费会员阅读……
您想了解如何成为其中一员吗?
</div>

属于该组的人只会看到整个主题。没有任何付费墙的迹象。

不属于该组的人会看到初始部分,不在上面的任何 DIV 中,以及一个付费墙。

这样我就可以在完全公开的区域使用它,以便人们可以看到他们注册、登录并成为付费会员后会得到什么。

终于完成了这个,地址是 https://github.com/Umbrella-CAST/discourse-umbrella-groupswitchdisplay。非常简单,只是根据当前用户是否在名为“foobar”的组中,或者不在“!foobar”组中,来从 DOM 中移除目标 DIV。这样我就可以像下面的图片一样简单地切换显示内容。

当然,如果禁用了该组件,那么所有内容都会显示(因为没有组件,DOM 就不会被修剪)。但这对我想要做的事情来说已经足够了。

4 个赞

您解决了我的一个非常相似的难题。

1 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.