기존 컨트롤러 확장하기?

안녕하세요, 모두. 제가 이 글을 제대로 된 곳에 올리는지 모르겠습니다. 저는 제 새로운 Discourse 웹사이트용 플러그인을 개발하려고 하고 있습니다.

예제 저장소를 여기서 포크하고, 플러그인 아웃렛(Plugin Outlet)을 작동시켰지만, 벽에 부딪혀 꽤나 막막하고 혼란스러운 기분이 들었습니다. 저는 최근에 Laravel 같은 MVC PHP 프레임워크를 익히기 시작했지만, JS 프레임워크에는 매우 초보입니다. Ruby, Rails, Ember은 전혀 접해본 적이 없습니다.

문제

제 웹사이트는 HOA(주택 소유자 협회) 커뮤니티를 위한 것입니다. 제가 하려는 일은 사용자별로 몇 가지 추가 데이터 필드를 수집하고 저장하는 것입니다:

  • legal_name (문자열)
  • is_owner (부울)
  • is_resident (부울)
  • building (문자열) - 건물 번호를 나타냅니다
  • unit (문자열) - 세대(호실) 번호를 나타냅니다
  • … 그리고 модератор가 확인했는지 여부 등 몇 가지 내부 변수들.

저는 이 필드들이 사용자 가입 시 필수 입력 항목이 되기를 원합니다. 즉, 사용자 가입 양식을 수정해야 한다는 뜻입니다. 저는 create-account-after-password 아웃렛에 연결하여 추가 필드를 표시하도록 만들었지만, 당연히 이렇게 해서 기능이 정상적으로 작동하지는 않습니다.

app/assets/javascripts/discourse/app/controllers/create-account.js의 컨트롤러를 확장해야 한다고 생각합니다. 제출 시 새로운 양식 값을 포착하는 것뿐만 아니라, client.en.yml 번역 필드에서 사이트 이름 this.siteSettings.title을 사용하는 것처럼 (겉보기에는) 매우 기본적인 작업조차 수행하려면 말이죠! (현재 제 가입 양식의 추가 필드 제목은 "[누락된 %{title} 값]과의 관계는 무엇인가요?"라고 표시됩니다. 이는 분명히 좋은 상태가 아닙니다.)

답을 찾으려고 시도할수록 질문은 더 많아지고 더 커졌습니다. 제가 따르려 했던 다양한 가이드는 서로 다른 버전의 Discourse를 위해 작성된 것 같았습니다. 예제 플러그인 저장소에는 제가 이해하지 못하는 것들이 있습니다. 클라이언트 사이드 라우트와 서버 사이드 라우트의 차이는 무엇인가요? 플러그인과 모듈의 차이는 무엇인가요? 정말로 길을 잃었습니다.

누군가 도움을 줄 수 있다면 매우 감사하겠습니다. 미리 감사합니다.

Creating and configuring custom user fields 링크를 통해 그렇게 할 수 있을 것 같습니다.

감사합니다! 제가 원하는 모든 기능을 제공하지는 않지만, 해당 기능이 제 목표 달성에 도움이 될 수 있는지 한 번 생각하게 해 주었습니다.

어쨌든 기존 컨트롤러를 플러그인으로 확장하는 방법에 대한 원래 질문에 답해야 할 것 같습니다. 이런 것이 가능한가요?

어딘가에 표시하기만 위해 저장하는 건가요? 이 데이터로 구체적으로 무엇을 하려는 건가요? 어딘가에 단순히 표시하는 것보다는 다른 기능을 위해 저장하려는 것 같은 인상을 받습니다.

Creating and configuring custom user fields 링크에서 프로그래밍 없이도 이를 수행할 수 있습니다.

이 데이터를 가지고 무엇을 하려는지요? 단순히 포럼 어딘가에 표시하는 것이 아니라, 다른 기능에 사용하기 위해 저장하려는 것 같다는 인상을 받습니다.

글쎄요, 제 최종 목표/비전은 다음과 같았습니다:

1. 단계적 관리 권한 (Tiered moderation)

커뮤니티 내 각 단위(unit)의 소유자에게 해당 단위의 거주자에 대해서만 관리 권한을 부여합니다.

저희 커뮤니티에는 약 200개에 달하는 단위들이 있어, 그룹 기능을 사용하여 이를 구현하는 것은 현실적이지 않다고 판단했습니다. 또한 아래 #3번 항목과도 충돌할 수 있습니다.

2. 가입 UX (사용자 경험)

제 머릿속에서 완벽한 UX라면, 가입 양식의 “단위(unit)” 드롭다운 메뉴가 “건물(building)” 필드에서 사용자가 선택한 내용에 따라 동적으로 반응하여, 해당 건물에 속한 단위들만 제공해야 합니다. (이 기능을 위해 Discourse가 초기화될 때 JSON 설정 파일을 파싱하는 방법을 알아볼 계획이었습니다.)

3. 필드 프라이버시 설정

각 사용자에게 자신의 건물 및/또는 단위 번호를 같은 단위에 속하지 않은 다른 사용자들에게 숨길지 여부를 선택할 수 있는 옵션을 제공하고자 했습니다.

제 인식이 맞다면, 핵심 커스텀 필드 기능은 이 옵션을 필드별로(사용자별로가 아니라)만 제공하며, 또한 관리자만 설정할 수 있고 사용자 스스로는 설정할 수 없습니다.

4. 세련된 스타일링

이것은 아이스크림 위에 토핑을 얹는 것 같은 부가적인 요소일 수 있지만, "소유자: 예"처럼 표시하는 대신, 시스템이 이러한 필드에 대해 특별한 인식을 가져 사용자 요약(User Summary)에서 다르게 스타일링되도록 하고 싶었습니다. 예를 들어 SVG 지권증 아이콘을 사용하고, 관리자가 상태를 확인했다면 체크 마크를 표시하거나(거주자의 경우 집 아이콘을 표시) 하는 식입니다.

그래서, 네 …

아마도 제가 너무 까다롭게 굴고 있는 것일 수 있지만, 핵심 기능을 구현하기 위한 학습 곡선을 넘어서면 나머지 작은 희망 목록의 항목들은 거의 자명해지리라 생각합니다.

저희 커뮤니티의 많은 거주자들은 컴퓨터 지식이 거의 없거나 전혀 없는 고령의 분들입니다. 일부 거주자들이 단순히 새 사이트이고 페이스북이 아니라는 이유만으로, 혹은 주소 프라이버시나 건물/단위 번호의 미검증 입력과 같은 실제 사용상의 문제 때문에 제 Discourse 웹사이트를 채택하고 사용하지 않을 것이라는 심각한 우려가 있습니다.

그 목적을 위해 그룹 기능을 사용하는 데는 문제가 없으며, 200개의 그룹을 쉽게 가질 수 있습니다.
필드를 그룹으로 매핑하는 작업만 수동 또는 프로그래밍 방식으로 수행하면 됩니다. 하지만 등록 후 사용자가 어떤 형태의 '증명’을 보내도록 하는 것도 고려해볼 수 있습니다.
이를 수동으로 처리하거나 직접 코드를 작성하여 구현할 수 있으며, Pavilion의 커스텀 위자드 플러그인을 사용할 수도 있습니다.

맞습니다. 하지만 공개적으로 표시하기를 원하는 사용자는 해당 필드를 다른 곳에 표시할 수 있도록 할 수 있습니다. 즉, ‘비공개’ 건물 필드와 ‘공개’ 건물 필드를 따로 두는 방식입니다.

기능을 추가해야 한다면, Discourse를 포크하는 대신 플러그인이나 테마 컴포넌트를 생성하는 것이 좋습니다.

테마 컴포넌트를 통해 이를 구현할 수 있으므로 플러그인이 필요하지 않지만, 플러그인을 개발 중이라면 프론트엔드 변경 사항도 플러그인에 포함시킬 수 있습니다. Discourse 플러그인 개발 - Part 1 - 기본 플러그인 만들기. 유사한 기능을 추가하는 플러그인을 찾는 것도 좋은 방법입니다. 예시를 검색할 수 있는 'all-the-plugins’라는 Discourse 저장소가 있습니다.

제안된 대로 해당 필드의 공개 및 비공개 버전을 구분하는 것이 좋은 해결책인 것 같지만, 플러그인을 통해 사용자 필드를 추가하고 시리얼라이저에 해당 필드가 어떻게, 또는 추가될지 여부를 제어하여 표시할 수도 있습니다.

이것은 테마 컴포넌트의 역할입니다. 테마 개발자 빠른 참고 가이드로 시작해 볼 수 있습니다.

TS는 discourse를 포크하려는 의도가 아니었던 것 같습니다.

그가 링크한 저장소는 플러그인이 아니라 포크인 것 같습니다.

image

discourse-plugin-skeleton을 포크하는 것이 플러그인을 작성하는 데 좋은 시작이라고 생각합니다…

동의합니다! 제가 뭘 봤는지 모르겠어요! 포크라는 걸 어떻게 놓쳤는지 모르겠네요. :person_shrugging:

plugin.rb를 찾아봤다고 생각했는데…

괜찮아, 이 대화를 통해 몇 가지 배울 수 있었거든 :grin:

@RGJ 님, 그 부분을 명확히 설명해 주셔서 감사합니다! :sweat_smile: 네, 이 일 때문에 Discourse 자체를 포크하는 일은 절대 하지 않았을 거예요.

플러그인에서 사용자 필드를 추가하고, 이러한 필드가 직렬화기에 어떻게, 그리고 추가될 것인지(표시 여부)를 제어할 수도 있습니다.

이것에는 “계정 만들기” 모달 폼에 필드를 추가하고, 필드를 필수로 설정하는 것도 포함됩니까? 이 작업을 수행하는 방법에 대한 예제나 가이드를 알려줄 수 있으신가요?

이미 "Developing Discourse Plugins"에 링크된 전체 가이드를 읽었습니다. 저의 시작점이었습니다. 결국 그 가이드에서 확장할 수 있는 실제 기능으로 보여주는 것은 보라색 문어를 가진 새로운 관리자 페이지를 만드는 것뿐이었습니다. 제 플러그인을 위한 관리자 페이지는 이미 작동하고 있지만, 실제로 필요할지조차 확실하지 않습니다. 이는 현재 제가 직면한 문제들과는 무관하므로, 그 예제는 제 상황에 크게 도움이 되지 않습니다.

그 목적을 위해 그룹을 사용하는 데에는 문제가 없으며, 200개의 그룹을 쉽게 가질 수 있습니다

사실 모든 조합(각 단위의 소유자, 거주자 또는 제휴사)을 커버하려면 400개에서 600개 사이가 될 것입니다. 그런데 이것이 어떻게 작동하나요? 200개의 그룹이 모두 사용자에게 동일하게 표시되어, ‘소유자 187’ 같은 대신 그냥 '소유자’라고만 표시될 수 있을까요?

조금 더 세부적인 질문이지만, 내부 그룹 ID가 URL과 같은 곳에서 최종 사용자에게 노출되나요? 사용자가 자신의 단위 번호를 비공개로 설정해 놓은 경우, 다른 사용자와 그룹 ID를 대조하여 이를 추측해 낼 수 있을까요?

내 생각에는 단순히 3개의 그룹(소유자, 거주자, 제휴사 – 또는 그냥 2개: 소유자와 거주자)을 만드는 것이 더 나은 결과를 가져올 것 같습니다. 말씀하신 대로 해당 그룹을 적절히 할당하고, 사용자가 잘못된 단위의 거주자를 관리하려고 할 때 특정 작업을 차단하는 방식으로 작동할 수 있지 않을까요?

그런 작업을 차단하는 것이 완전히 불가능하다면, 600개의 그룹을 만들고 … 사용자가 시스템을 '해킹’하거나 누군가를 디도싱(doxing)하려는 영리한 생각을 하지 않기를 바라는 수밖에 없겠네요.

잠깐. 뭐라고요? 제가 임차인이라면 포럼에서 무언가를 말했을 때, 집주인이 제 글을 수정할 수 있다는 뜻인가요? 토픽은 단일 카테고리에만 속하므로, 그러면 소유자와 임차인 사이에서만 이루어지는 대화가 생기게 됩니다.

그건 말이 안 됩니다. 그리고 토픽 수준의 권한을 설정하는 쉬운 방법이 실제로는 없습니다.

건물별 그룹과 카테고리를 원하는 것이 더 합리적일 것 같지만, 단위별 제어는 전혀 말이 안 됩니다.

토픽 단위 권한에 대해서는 아무 말도 하지 않았습니다.

아마 "moderator(모더레이터)"라는 표현이 잘못된 것일까요? 저도 잘 모르겠습니다. (지금까지 디스코스를 사용해 본 적이 없거든요.)

제가 말하고자 하는 것은 사용자별로 포럼 접근을 승인하거나 제거하는 것입니다. 따라서 네, 집주인이 당신의 글을 수정할 수는 없지만, 거주자로 가입을 확인하는 권한은 그들에게 있습니다. 또한 당신이 트롤이 되면 그들은 당신을 음소거하거나 밴할 수 있습니다. 게시물과 토픽은 웹사이트 스태프가 콘텐츠 정책에 따라 동등하게 관리하며, 소유자가 관리하는 것이 아닙니다.

제 목표는 포럼 접근을 각 부동산 자체에 대한 법적 권한 체인과 최대한 연결하는 것입니다. 여기서 부동산을 합법적으로 소유한 확인된 소유자가 밴되는 일은 절대 일어나서는 안 되지만, 정책 위반 게시물을 작성하면 스태프에 의해 해당 게시물이 삭제될 수 있습니다. 그러나 부동산을 매도하면 “소유자” 지위는 즉시 박탈되며, 이로 인해 웹사이트에서 제거될 수 있습니다(부동산의 새 소유자의 승인을 받아 “아필리에이트” 지위를 선택하는 경우를 제외하고).

우리의 커뮤니티에서는 같은 건물 내의 한 유닛이 다른 유닛과 물리적으로 연결되어 있다는 점을 제외하고는 어떤 관계도 없습니다. 그것이 전부입니다. 건물별로 사람들을 그룹화하는 것은 거의 미적인 UX 결정에 불과하며, 건물 전체에 대한 권한을 부여하는 것은 여기서 의미가 없습니다.

이것을 찾았습니다: Add a custom per-user setting in a plugin

댓글에서 한 사용자는 자신이 "컨트롤러를 패치했다"고 말했습니다. assets/javascripts/discourse/initializers/ 디렉터리 안에 api.modifyClass()라는 메서드를 참조하는 .js.es6 파일이 있습니다 …

흠mmm :thinking: 뭔가 핵심을 파악하고 있는 것 같습니다.

좋아요! 바로 그거예요!

무엇을 하고 싶은지 결정하기 전에 먼저 Discourse에 대해 좀 더 익숙해지시길 권해 드립니다.

사이트에 가입하는 사람을 승인하는 권한을 소수의 인원에게 맡기는 것이, 각 유닛 소유자가 모두 사이트 접근을 통제하는 것보다 훨씬 쉬울 거라고 생각합니다. 소유자가 결정한다면, 누군가 유닛을 팔면 어떻게 되나요? 그때는 누가 결정하게 되나요? 세입자가 포럼 회원이 되는 것에 관심이 없는 소유자는 어떡하죠? 제 생각에는 단지 매니저에게 맡기는 것이 훨씬 더 합리적이고, 플러그인도 필요 없을 것 같습니다.