Unique CSS class for Group pages?

AI-generated summary

A discussion is underway about adding a unique CSS class for group pages in Discourse. downey initially asked if it’s possible to add a group-specific class on group pages, allowing for custom styling. downey mentions that without a dedicated class on the <body> tag, styling an individual group’s page is challenging.

Arkshine suggests using a CSS selector to target the group page, but downey notes that this might not be sufficient for their needs. Canapin proposes using JavaScript to set classes on upper HTML elements starting from .group.

srmtey provides an initial JavaScript solution that adds a groupname class to the main id, but notes that the class persists even after navigating away from the page. srmtey refines the solution using a cookie to store the current group name, allowing for automatic addition and removal of the class.

Any chance of a group-specific class on the group-specific pages for members, topics, posts, etc.?

e.g. /groups/FOO/topics

This would allow us to do custom styling for each group.

3 Likes

I thought since it’s been 4 years I’d ask again to see if there’s any more interest this time.

It sure would be nice to style an individual group’s page, but doing so without a dedicated class on the <body> tag – like we have for groups-page is on the main group listing at /g – would sure be nice, IMHO.

Has anyone else longed for this, or maybe alternatively, figured out a way to do more detailed CSS styling on an individual group’s listing page?

What kind of modifications you are looking for?

If I understand, you want to target a group page – you can prefix with:

#main-outlet .container.group.FOO {
    //
}
6 Likes

Thanks, that might get me pretty close. Typically it seems like these selectors have gone on <body> so that’s where I was looking.

I am trying to make something more complementary with the (beautiful) Discourse Category Banners theme component that @awesomerobot created, so not sure if I can do that based on the HTML outputted, but will hack around at it.

2 Likes

You could use js to set classes on upper html elements starting from .group.

1 Like

Yeah, that seems to be what was done on Discourse Category Banners in order to get the right content up above #main-outlet. Extra js will probably remain on my wish/todo list for quite a while and I’ll just do what I can with CSS for now.

Here is an ugly way to do it. Adding the class is easy. This will add a groupname to your main id, where groupname = whatever the name of the group is, ie <section id="main" class="ember-application groupname">

<script type="text/discourse-plugin" version="0.8">
        function getGroupInfo() {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                var myObj = JSON.parse(this.responseText);
                if (myObj.group.name) {
                    document.getElementById("main").classList.add(myObj.group.name);
                }
            }
        };
        var url = window.location.href;
        xmlhttp.open("GET", url + ".json", true);
        xmlhttp.send();    			
    }
    api.onPageChange(() =>{
        getGroupInfo();
    });
</script>

The problem is the class stays there once you navigate away. We need a way to remove that class when we leave the page. There is probably an easy way to do this but I don’t really know js so I’m not clever enough to figure it out. Hopefully you can figure out a better way to do it, but the ugly way to do it is to change the end of the script to

    api.onPageChange(() =>{
        document.getElementById("main").classList.remove("group1");
        document.getElementById("main").classList.remove("group2");
        document.getElementById("main").classList.remove("group3");
        getGroupInfo();
    });

This will remove any possible groupname class you’ve added. But it seems like a really ugly way to do it, and you have to change the code any time you add a new group.

1 Like

The problem was I couldn’t figure out how to pass a variable from getGroupInfo() to api.onPageChange(() =>{

Code below accomplishes this with a cookie and should auto add and remove a class "name-of-current-group" to/from div ID main for any group you have.

<script type="text/discourse-plugin" version="0.8">
        function getGroupInfo() {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                var myObj = JSON.parse(this.responseText);
                var groupName = myObj.group.name;
                if (groupName) {
                    document.getElementById("main").classList.add(groupName);
                    $.cookie('groupCookie', groupName, { expires: 7, path: '/' });
                }
            }
        };
        var url = window.location.href;
        xmlhttp.open("GET", url + ".json", true);
        xmlhttp.send();    			
    }
    api.onPageChange(() =>{
        var group = $.cookie('groupCookie');
        document.getElementById("main").classList.remove(group);
        $.cookie('groupCookie', 'false', { expires: -1, path: '/' })
        getGroupInfo();
    });
</script>