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 лайка

Я подумал, раз прошло уже 4 года, стоит спросить ещё раз, чтобы узнать, есть ли сейчас к этому больший интерес.

Было бы здорово иметь возможность стилизовать страницу отдельной группы, но делать это без специального класса на теге <body> — как у нас есть для groups-page на главной странице списка групп по адресу /g — было бы, на мой взгляд, ещё лучше.

Кто-нибудь ещё испытывал подобную потребность или, возможно, нашёл способ применить более детальную CSS-стилизацию к странице списка отдельной группы?

Какие именно изменения вы ищете?

Если я правильно понял, вы хотите обратиться к странице группы — в этом случае добавьте префикс:

#main-outlet .container.group.FOO {
    //
}
6 лайков

Спасибо, это, вероятно, поможет мне приблизиться к цели. Обычно такие селекторы размещаются на теге <body>, поэтому я искал именно там.

Я пытаюсь создать что-то, что будет гармонировать с компонентом темы Discourse Category Banners (красивым!), созданным @awesomerobot, поэтому пока не уверен, смогу ли я реализовать это на основе выводимого HTML, но попробую поэкспериментировать.

2 лайка

Вы можете использовать JavaScript, чтобы назначать классы вышестоящим HTML-элементам, начиная с .group.

1 лайк

Да, похоже, именно так было сделано в теме Баннеры категорий Discourse, чтобы разместить нужный контент выше #main-outlet. Дополнительный JavaScript, скорее всего, ещё долго будет оставаться в моём списке желаемого/задач, так что пока я ограничусь тем, что смогу сделать с помощью CSS.

Вот неуклюжий способ сделать это. Добавление класса — дело простое. Это добавит groupname к вашему идентификатору main, где groupname — это имя группы, например: <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>

Проблема в том, что класс остаётся, даже когда вы переходите на другую страницу. Нам нужен способ удалять этот класс при выходе со страницы. Вероятно, есть простой способ сделать это, но я не очень хорошо знаю JS, поэтому не могу сообразить, как. Надеюсь, вы сможете найти более элегантное решение, но неуклюжий способ — изменить конец скрипта следующим образом:

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

Это удалит любой возможный класс с именем группы, который вы добавили. Но это кажется действительно неуклюжим решением, и вам придётся менять код каждый раз, когда вы добавляете новую группу.

1 лайк

Проблема заключалась в том, что я не мог понять, как передать переменную из getGroupInfo() в api.onPageChange(() => {.

Ниже приведенный код решает эту задачу с использованием куки и должен автоматически добавлять и удалять класс "name-of-current-group" из div с идентификатором main для любой группы, к которой вы принадлежите.

<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>