# Отображать разный контент в теме в зависимости от групповой принадлежности пользователя?

**URL:** https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075
**Category:** Development
**Created:** [15.Май.2022 12:01:25 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075 "2022-05-15T12:01:25Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [15.Май.2022 12:01:26 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/1 "2022-05-15T12:01:26Z")

</div>

Я работаю с хостингом [discourse.org](http://discourse.org), поэтому в данном случае использование плагинов для меня невозможно. Представьте, что у меня есть тема, которую может увидеть любой.

Если пользователь состоит в группе «A», я хочу, чтобы он видел _этот_ контент. Если нет — я хочу, чтобы он видел _другой_ контент. При этом часть темы должна быть видна всем. Схематично это выглядит так…

```plaintext
Это контент, который видят все.

{мечты: только для людей из группы A}
Спасибо, что вы в специальной группе!
{/мечты}

{мечты: только для людей НЕ из группы A}
У нас есть специальная группа, в которую можно вступить. [Узнайте больше об этом](…)
{/мечты}

```

Я уверен (но точно не помню, как это делается), что это можно реализовать с помощью компонента темы, который добавляет CSS-классы к контенту, отображение которого нужно «переключать». Если лучшего варианта не найти, я поступлю именно так.

Но CSS `display: none` — это слабое решение. Я бы хотел, чтобы то, что не должны видеть пользователи, исчезало из DOM. Желательно на стороне сервера, но я согласен и на решение, основанное на JavaScript, которое скрывает контент на стороне браузера. (Обойти это сложнее, чем просто использовать `display: none` в CSS, и требует гораздо большей изобретательности.)

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [17.Май.2022 17:22:51 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/2 "2022-05-17T17:22:51Z")

</div>

поднимаю! никто? :~(

почему мы не можем упомянуть [@team](https://meta.discourse.org/groups/team) 😉

---

<div class="post-metadata">

### Author: ![jimkleiber](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jimkleiber/32/121814_2.png) [@jimkleiber](https://meta.discourse.org/u/jimkleiber)
#### Post date: [17.Май.2022 19:15:14 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/3 "2022-05-17T19:15:14Z")

</div>

Сейчас у меня нет времени подробно вникать в это, но этот компонент темы может вам помочь, так как он, как я помню, выводит все группы текущего пользователя в тег `body`. Затем вы, вероятно, сможете использовать CSS-селекторы для показа/скрытия элементов в зависимости от того, присутствуют ли в теге `body` определённые классы групп.

> [@CSS Classes for Current User's Groups](https://meta.discourse.org/t/css-classes-for-current-users-groups/226068):
>
> discourse2Summary CSS Classes for Current User’s Groups adds the groups that a member is a part of as CSS classes on the \<body\> tag.eyeglassesPreview [Preview on theme-creator.discourse.org](https://discourse.theme-creator.io/theme/Johani/user-groups-css-classes)hammer_and_wrenchRepository Link [https://github.com/discourse/discourse-groups-css-classes-in-body](https://github.com/discourse/discourse-groups-css-classes-in-body)open_bookNew to Discourse Themes? [Beginner’s guide to using Discourse Themes](https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966) Install this theme component Before: [image] After: [image] Discourse only adds the current us…

А в сочетании с информацией из этого поста о том, какие HTML-элементы можно использовать в редакторе и как оборачивать текст редактора в классы, это может сработать:

> [@What are the different ways to customize content inside a post (custom attributes and such)](https://meta.discourse.org/t/what-are-the-different-ways-to-customize-content-inside-a-post-custom-attributes-and-such/226747):
>
> So far I’m aware of two way to do it: \<span data-theme-custom\>some text\</span\> CSS: [data-theme-custom] { color: pink; } [wrap="indent"]some text[/wrap] It will create either a div or a span (if there is other content on the same line), containing the following attributes: class="d-wrap" and data-wrap="custom" CSS [data-wrap="custom"] { color: pink; } Are there other ways to customize some chosen content in a post I’m not aware of? Also, is there a way to add a custom c…

Да, я только что проверил это здесь, и это должно сработать, если использовать этот компонент вместе с чем-то вроде:

```html
<span data-group-a>Текст только для группы A</span>
<span data-group-b>Текст только для группы B</span>

```

А затем добавить CSS-селекторы, которые делают что-то вроде:

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

```

Или что-то в этом роде…

Извините за все правки. Я просто протестировал это на одном из своих экземпляров, и всё работает.

Но, как вы упомянули, возможно, это не то, что вы искали 🙂

> [@craigconstantine](#):
>
> Но CSS `display: none` — это слабовато. Я хотел бы полностью удалять из DOM то, что они не должны видеть. Желательно на стороне сервера, но меня устроит хотя бы скрытие на стороне браузера с помощью JS. (Это требует гораздо более высокого уровня хитрости, чем просто `display: none` в CSS.)

Это может быть возможно с помощью JavaScript темы: добавить что-то в секцию `<head>`, чтобы выбрать элементы и удалить их. Всё ещё может потребоваться использование `span` и оборачивание, как описано выше, но удаление будет происходить через скрипт.

---

<div class="post-metadata">

### Author: ![jimkleiber](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jimkleiber/32/121814_2.png) [@jimkleiber](https://meta.discourse.org/u/jimkleiber)
#### Post date: [17.Май.2022 19:56:48 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/4 "2022-05-17T19:56:48Z")

</div>

Хорошо, я понял, что это мне тоже может понадобиться, поэтому я копнул глубже 🙂

Этот код пока не работает и выглядит не очень красиво, но, думаю, он уже почти готов для вставки в часть `<head>` темы. Нужно лишь правильно подобрать способ выбора элементов с помощью JS:

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

```

ВАЖНО: Думаю, будет сложно полностью скрыть всю информацию от поисковиков и подобных систем. Поэтому, хотя этот метод лучше, чем простое скрытие через CSS, я не считаю, что он полностью предотвратит просмотр информации людьми.

ИЗМЕНЕНИЕ: Исправил, чтобы селекторы CSS работали. Повторяйте код для каждой группы, которую хотите использовать. Замените `THEME-ID` на уникальное имя. Я _думаю_, теперь это должно работать 🙂

Ой, этот момент я пока не доделал:

> [@craigconstantine](#):
>
> ```plaintext
> {wishful thinking: only for ppl NOT in group A}
> Привет, у нас есть специальная группа, в которую вы можете вступить. [Подробнее об этом](…)
> {/wishful}
> 
> ```

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [29.Август.2022 14:39:42 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/5 "2022-08-29T14:39:42Z")

</div>

Я действительно ценю ваши усилия по этому вопросу… Я всё ещё обдумываю это и считаю, что вы предложили мне рабочее решение. У меня есть шаблонный компонент, который я написал, и это заставляет меня думать, что я смогу реализовать что-то подобное…

Допустим, я представляю компонент «foobar». Я мог бы написать тему, добавив такие DIV-элементы:

```plaintext
<div data-custom="foobar" data-foobar="<groupname>">
</div>

```

```plaintext
<div data-custom="foobar" data-foobar="!<groupname>">
</div>

```

Затем компонент удаляет из DOM один из этих DIV-элементов в зависимости от группы, к которой принадлежит просматривающий пользователь.

Мне это кажется более надёжным, чем CSS `display: none;`, который легко переключить обратно через любые инструменты инспекции DOM в браузере. Чтобы обойти это, кто-то должен был бы изменить JavaScript, который выполняется при загрузке страницы — это возможно, но гораздо сложнее.

# Зачем мне это нужно?

Чтобы я мог частично раскрывать контент для тех, кто НЕ входит в группу. (Поскольку вход в группу требует платной подписки.)

```plaintext
Это действительно интересная тема. Первый
абзац действительно увлекателен.

<div data-custom="foobar" data-foobar="<groupname>">
Вот остальная часть контента.
</div>

<div data-custom="foobar" data-foobar="!<groupname>">
Привет, извините за прерывание!
Здесь есть больше контента для наших платных участников...
хотите узнать, как стать одним из них?
</div>

```

Пользователи, входящие в группу, видят всю тему целиком. Никаких признаков платного доступа.

Пользователи, не входящие в группу, видят только начальную часть (не входящую ни в один из вышеуказанных DIV-элементов) и сообщение о платном доступе.

Таким образом, я могу использовать это в полностью публичной области, чтобы люди могли увидеть, что они получат, если зарегистрируются, войдут в систему и станут платными участниками.

---

<div class="post-metadata">

### Author: ![craigconstantine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/craigconstantine/32/511195_2.png) [@craigconstantine](https://meta.discourse.org/u/craigconstantine)
#### Post date: [21.Октябрь.2022 18:48:32 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/6 "2022-10-21T18:48:32Z")

</div>

Наконец-то собрал это, так как [https://github.com/Umbrella-CAST/discourse-umbrella-groupswitchdisplay](https://github.com/Umbrella-CAST/discourse-umbrella-groupswitchdisplay). Всё очень просто: скрипт удаляет целевой DIV из DOM в зависимости от того, состоит ли текущий пользователь в группе с именем «foobar» или не состоит (обозначается как «!foobar»). Это позволяет легко переключать отображение контента, как на изображении ниже.

Конечно, если компонент отключён, то отображается весь контент (поскольку без компонента DOM не обрезается). Но этого достаточно для моих задач.

 ![Screen Shot 2022-10-21 at 14.45.00](https://global.discourse-cdn.com/meta/original/4X/8/a/c/8ac929ad9267b6c6544b976da4bbe4a79655a2fc.jpeg)

---

<div class="post-metadata">

### Author: ![Jagster](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagster/32/192154_2.png) [@Jagster](https://meta.discourse.org/u/Jagster)
#### Post date: [21.Октябрь.2022 19:56:15 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/7 "2022-10-21T19:56:15Z")

</div>

Вы решили одну из моих очень похожих проблем.

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [20.Ноябрь.2022 19:56:19 UTC](https://meta.discourse.org/t/display-different-content-within-a-topic-based-on-users-groups-membership/227075/8 "2022-11-20T19:56:19Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
