Check for group membership in Header code?

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

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.

3 Likes

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

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>

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.

2 Likes

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.

6 Likes

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

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.

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

1 Like

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.

8 Likes

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

3 Likes

Actually, as of v2.2.0.beta9+29 .anon doesn’t work anymore. OTOH, .primary-group-patreons still works fine. Instead, what happens now for users who aren’t logged in is that they’re getting the “Regular member!” banner.

Did something change in Discourse? Anyone else seeing this?

Gunnar

2 Likes

Yes, I can confirm the .anon class is missing. We should fix that.

@david I think this might have happened in your commit here? https://github.com/discourse/discourse/commit/1ebd3dbbd02a684b139e74b53d0545f15d78a1af#diff-127a850b7d7b20173ad3fba88f8a25e3

9 Likes

Fixed. Now .anon CSS class is included in the html tag again

https://github.com/discourse/discourse/commit/70b56c8332a5d54e79bc48af66bb4f17a5f0ad3d

12 Likes

Verified. Thanks for your help!

4 Likes

I’m trying to do something with CSS (as a bandaid/painting with whiteout) since I have no “proper” way to do this.

I’m trying to hide all contents in a category from EVERYONE not in a specific group. While group permissions do the trick mostly, it doesn’t hide the contents from an admin. This is a problem with our board as the admin (me) should not see the contents of an executive group. (this is a business teams instance)

I know what and why this is a bandaid. Until the nature of things change with discourse access control, this is what I have to do.

I want the category contents invisible to the admin(s), but visable to the members of the a specific group:

The category name: secretary
The category id: 33
The group: secretary

Here’s my code that hides ALL within the category. It works to hide the content from the admin/(me).

This part works

.topic-list-item.category-secretary { 
    display: none; 
}

Here’s what I’ve tried to restore visability to the members of that group:

This part doesn’t work:

.primary-group-secretary .topic-list-item.category-secretary { 
	    display: table-row; 
}

Can anyone help with this? Fix my code?

You should have a second non-admin account for that purpose.

It should be the primary group of that user. Also make sure the order is correct.

3 Likes