Display different content within a topic based on user's groups membership?

I’m working in discourse.org’s hosting, so plugins are not possible for me in this case. Imagine I have a topic posted where anyone can see it.

If someone is in group “A” then I want them to see this content. If NOT, then I want them to see this other content. And some of the topic everyone should see. Schematically like this…

This is content everyone sees.

{wishful thinking: only for ppl in group A}
Hey thanks for being in the special group!
{/wishful}

{wishful thinking: only for ppl NOT in group A}
Hey we have a special group you can join. [Read more about that](…)
{/wishful}

I feel confident (but forget exactly how to do it) that this can be done with a theme component to set CSS classes on the content I want to “toggle” display of. I’ll do this if this is the best I can figure out.

But CSS display: none is weak sauce. I’d like to disappear from the DOM what they shouldn’t see. Disappeared server-side if possible, but I’d settle for at least j/s based disappeared browser-side. (That requires a much higher clever-level to get around than display: none does in CSS.)

bump! nobody? :~(

why can’t we tag @team :wink:

I don’t have too much time to dive into it right now but this theme component may help you because it’ll list all of the current user’s groups in, I think, the body tag. Then you could probably use CSS selectors to show/hide based on whether certain group class names exist in the body tag.

And combine that with some info from this post on how which HTML elements you can use in the composer and how to wrap composer text in classes, and it may work:

Yup, just tested it here and it should work if you use that component combined with something like:

<span data-group-a>Text only for group A</span>
<span data-group-b>Text only for group B</span>

And then have css selectors that do something like:

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

Or something like that…

Sorry for all the edits. Just tested it on one of my instances and it works.

But as you mentioned, maybe that’s not what you wanted :slight_smile:

This might be possible with a theme javascript, adding something in the <head> section to select the elements and remove it. Still may require the span and wrapping as above, but remove it through that.

2 Likes

Ok I realized I may need this as well so I dove more deeply into it :slight_smile:

This code doesn’t yet work and is not that pretty, but I think it’s almost good enough to go in the </head> part of the theme, just needs to have the right way to select the elements using 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>

CAVEAT: I think it may be hard to hide all the info from search and things like that, so while this may be better than just hiding it via CSS, I don’t think it’ll completely prevent people from seeing the info.

EDIT: Fixed it so the CSS selectors should work. Repeat the code for as many groups as you want to use. Change THEME-ID to a unique name. I think this should work :slight_smile:

Oops, didn’t get this part yet:

3 Likes