Check for group membership in Header code?


(Gunnar Helliesen) #1

Hi,

When adding a button or link to the Header field, can I check for group membership and make it conditional?

I.e., if the user doesn’t belong to group ‘group1’, then display the button, otherwise don’t.

Is there a way to do that?

Thanks!
Gunnar


(cpradio) #2

The answer is yes, but the amount of work varies.

By calling

var user = Discourse.User.current();

You can get access immediately to their primary_group_name, but it won’t provide you with all groups they have access to.

To get all groups, you might have to do a call to /u/username.json and read the groups property. That makes it a tad more difficult as now you are awaiting the response of a call before you can show the link.


(Gunnar Helliesen) #3

Thanks! In this case it is their primary group, so that should make it easier, then. Would you mind helping me out with a snippet of example code, how I would use this? Here’s the code I want to make conditional. If the user is a member of ‘group1’, this button should display, otherwise not:

<div id="top-navbar" class="container">
<span id="top-navbar-links" style="display:none;">
<a class="btn btn-lg btn-primary" href="https://www.demo.com/">
<i class="fa fa-flag fa-2x pull-left"></i> Click here<br>for demo!</a>
</span>
</div>

Thanks,
Gunnar


(cpradio) #4

It sort of depends on where that is being added. Is that a custom header? Or are you trying to add them on the same line as the logo?

If on the same line as the logo, this is close (create it as a custom component and enable it as part of your theme, in the </head> section)

<script type="text/discourse-plugin" version="0.2">
api.decorateWidget('home-logo:after', helper => {
        const user = Discourse.User.current();
        if(user.primary_group_name.toLowerCase() === "group1") {
            return helper.h('div#top-navbar.container', [
                    helper.h('span#top-navbar-links', [
                        helper.h('a.btn.btn-lg.btn-primary', {
                            href:'https://www.demo.com/', 
                            text:'<i class="fa fa-flag fa-2x pull-left"></i> Click here<br>for demo!' // not sure if this will work
                        })
                    ])
            ]);
        }
});
</script>

(Stephen Chung) #5

Actually, it would be nice for Discourse to add group-derived classes to the root body element.

This way makes it very easy to tailor the display according to the user. For example, if I have groups based on counties, I can easily include css that displays the country’s flag as a background.

Or each department can have a different color. And so on. Very very useful.


(Vinoth Kannan) #6

It exist already. For example, If a user’s primary group is customers then the body tag will have the CSS class primary-group-customers. And it will work only for primary group property.


(Stephen Chung) #7

Ah. Great. Didn’t notice this. Next time I’ll check first and bubble later! :sweat_smile:


(Stephen Chung) #8

But it should work for all groups. Just the primary group is very restrictive.

If you have all, I can have elaborate css to decide what format to use based on groups.

EDIT: Many groups are not primary. They are used just to restrict access for categories. Some are use simply for identification purposes, and these groups are primary candidates for formatting purposes. It is very unlikely that the primary group is all you need.


(Gunnar Helliesen) #9

So, should this work then, if I want to display “Member!” if the user is a member of the “patrons” group?

<p id="ghjldemo">Not a member!</p>

<script type="text/javascript">
if ( document.getElementById("body").className.match(/(?:^|\s)primary-group-patrons(?!\S)/) ) {
    document.getElementById("ghjldemo").innerHTML = "Member!";
}
</script>

Thanks,
Gunnar


(Vinoth Kannan) #10

Better to use CSS here

<p id="ghjldemo"></p>
#ghjldemo:after {
  content: "Regular member!";
}

.anon #ghjldemo:after {
  content: "Not a member!";
}

.primary-group-patreons #ghjldemo:after {
  content: "Patreon member!";
}

In above three styles #ghjldemo:after should be in first always.


(Gunnar Helliesen) #11

Awesome! I had no idea CSS could do that. It works, and thanks for adding the anon. Perfect!