AI를 사용해 콘텐츠 숨기기 bbcode 래퍼 만들기

일반적인 bbcode 래퍼를 사용하여 그룹 문자열 변수에 속하지 않으면 내용을 숨기는 테마 컴포넌트를 생성

초안 보기

일반적인 BBCode 래퍼 및 테마 컴포넌트 생성
요구 사항 이해
요청 사항에 따라 다음을 생성할 것입니다:

사용자 정의 속성을 받을 수 있는 일반적인 BBCode 래퍼.
BBCode 래퍼에 전달되는 그룹 문자열 변수에 기반하여 내용을 숨기는 테마 컴포넌트.
BBCode 래퍼 구현
임의의 속성을 받을 수 있는 BBCode 래퍼를 생성합니다. 이러한 속성은 평가하기 위해 테마 컴포넌트로 전달됩니다.

Ruby

# config/initializers/bbcode.rb
Discourse::Plugins::BBCode.add_parser(:hide_if_not_in_group) do |tag, content|
  attributes = tag.attributes || {}
  "<div class='hide-if-not-in-group' data-group-names='#{attributes[:groups]}'>#{content}</div>"
end

코드를 신중하게 사용하세요.

테마 컴포넌트 생성
테마 컴포넌트는 현재 사용자가 data-group-names 속성에 지정된 그룹 중 하나에 속하는지 확인합니다. 속하지 않는 경우, 내용은 숨겨집니다.

JavaScript

// app/assets/javascripts/discourse/components/hide-if-not-in-group.js
import Component from 'discourse/components/component';

export default Component.extend({
  tagName: 'div',
  classNames: ['hide-if-not-in-group'],

  didInsertElement() {
    const currentUserId = Discourse.currentUser.id;
    const groupNames = this.element.dataset.groupNames.split(',');

    // 사용자가 지정된 그룹 중 하나에 속하는지 확인하는 함수
    const userIsInAnyGroup = (userId, groupNames) => {
      // 사용자 그룹 멤버십을 확인하는 로직으로 이 부분을 교체하세요
      // 예를 들어, Discourse API 또는 사용자 정의 로직 사용
      return groupNames.some(groupName => {
        // 사용자가 `groupName`이라는 이름의 그룹에 속하는지 확인
        // 사용자가 그룹에 속하면 true, 아니면 false 반환
      });
    };

    if (!userIsInAnyGroup(currentUserId, groupNames)) {
      this.element.style.display = 'none';
    }
  }
});

코드를 신중하게 사용하세요.

BBCode 사용
BBCode는 다음과 같이 사용할 수 있습니다:

[hide_if_not_in_group groups="staff,moderators"]
이 내용은 스태프나 모더레이터가 아닌 사용자에게는 숨겨집니다.
[/hide_if_not_in_group]

중요한 고려 사항
그룹 멤버십 확인: 사용자 그룹 멤버십을 확인하는 자리 표시자 로직을 실제 구현으로 교체해야 합니다. 그룹 멤버십을 결정하기 위해 Discourse API 또는 사용자 정의 로직이 필요할 수 있습니다.
성능: 사용자 또는 그룹 수가 많은 경우, 그룹 멤버십 확인을 최적화해야 할 수 있습니다.
보안: 보안 취약점을 방지하기 위해 그룹 이름에 대한 적절한 검증과 제거(sanitization)를 보장하세요.
유연성: 다른 동작(예: 내용을 숨기는 대신 메시지 표시)을 제어하기 위해 BBCode에 추가 속성을 허용하는 것을 고려하세요.
이 단계를 따르면 그룹 멤버십에 기반하여 내용을 숨길 수 있는 유연한 BBCode 래퍼와 테마 컴포넌트를 갖출 수 있습니다.


Gemini를 사용했습니다. 위의 코드 스니펫을 얻을 수 있었지만 작동시키는 데 어려움을 겪고 있습니다.

커스텀 컴포넌트에 어디에 배치해야 하는지, 그리고 코드를 수정해야 하는 부분이 어디인지 안내해 주실 수 있을까요?

JavaScript를 common에 넣었을 때 “import” 라인이 {를 예상하지 않는다는 오류가 발생했습니다.

에러 이미지

정말 멋지네요!

아마도 이미 알고 계실 텐데, 텍스트는 CSS로 숨겨져 있을 뿐이므로 여러 방식으로 접근할 수 있습니다. 그중 하나가 바로 이 게시물 경로입니다:

/posts/123/raw

그렇습니다. 누군가가 더 복잡한 방식으로 콘텐츠를 제거하는 커스텀 컴포넌트를 만들었었는데요. 하지만 지금은 깨진 것 같습니다.

기억이 정확하지는 않지만, 쿠크된(cooked) 요소에서 콘텐츠를 제거하는 방식이었던 것 같네요.

여기에는 한 사용자가 컴포넌트를 생성했지만, 제가 시도했을 때 작동하지 않아 DeV에게 개인 메시지를 보낸 주제가 있습니다. 하지만 이미 넘어간 것 같습니다.

죄송합니다. 방금 읽은 바로는 작동하지 않는다고 하네요.

해결 방법은 discourse_theme를 사용해 새로운 빈 테마를 생성하는 것입니다. 그런 다음 “extends component” 섹션이 있는 다른 테마 구성 요소를 찾아보세요… 아, 아마도 작동하지 않을 것 같습니다. 기존 DOM에 있는 내용을 대상으로 수정하는 코드가 필요합니다. 사실, 이런 것에 아직 능숙하지 않아 정확히 확신할 수 없습니다.

그룹 멤버십을 CSS에 추가하는 그 구성 요소를 사용한다면 CSS만으로 해결할 수 있다고 생각합니다.

하지만 지난 게시물에서 제가 보여드린 라우트에서 원시 마크다운은 접근 가능합니다. 플러그인을 사용하더라도 숨겨진 텍스트를 사람들이 볼 수 없도록 안전하게 만드는 것이 불가능해 보입니다. 사용자 메모(user notes)가 이 문제를 해결해 줄 수 있거나, 게시물에 적용해야 한다면 사용자 메모를 모델로 삼아 스태프만 볼 수 있는 게시물 커스텀 필드를 추가하는 게시물 메모(post notes)를 만들 수 있습니다.

네, API를 변경하지 않고서는 이 문제를 제대로 해결할 수 없어요. 따라서 테마 구성 요소가 아니라 플러그인이 필요합니다.

사이트에서 모더레이션을 위해 위스퍼를 사용하지 않고 있다면, 기본으로 제공되는 위스퍼를 사용하는 것을 고려해 보시는 건 어떨까요?

이것의 용도는 보안 중심이 아닙니다.

이것은 더 가벼운 애플리케이션에 적합합니다. 이전 주제에서 한 사용자가 테이블톱 RPG용으로 이와 같은 것을 찾고 있었습니다. 예를 들어 던전 마스터가 플레이어의 캐릭터 시트에 접근해야 할 수 있습니다. 캐릭터 시트는 플레이어와 게임 마스터 모두에게 표시되어야 합니다.

그 한 분이 만든 우산(umbrella) 컴포넌트는 괜찮아 보입니다. 하지만 제가 테스트해 보니 깨진 것 같습니다. 물론 그 것도 쉽게 타협(침범)당할 수 있다고 생각합니다. 틀리지 않았다면 자바를 비활성화하는 것과 같은 방식일 것입니다. 또는 사이트 안전 모드에 대해 아는 교묘한 사람도 있을 수 있습니다. 안전 모드를 스태프/관리자로 제한할 수 있을까요?

어떤 컴포넌트든 클라이언트 측 모드는 당연히 보안 요구사항을 위해 설계된 것이 아닙니다. 멤버들은 테마/테마 컴포넌트와 유사하거나 동일한 방식으로 Tampermonkey 스크립트도 사용할 수 있습니다.

이 아이디어를 더 확장하면, 이론상 배지 등을 기반으로 콘텐츠를 숨길 수 있습니다.

네. 이 기능을 비활성화하면 Staff만 안전 모드를 사용할 수 있습니다.

image