새로운 사용자 지정 홈페이지 기능 사용

새로운 사용자 정의 홈페이지 기능을 시험해 보고 있습니다: DEV: allow themes to render their own custom homepage - Pull Request #26291 - discourse/discourse - GitHub :tada:

@pmusaraj 컴포넌트를 추가하는 가장 좋은 방법은 무엇일지 궁금합니다.

  1. 사용자 정의 홈페이지 수정자를 추가하면 discovery.custom 라우트가 활성화되고, custom-homepage 아웃렛에 렌더링되는 기본 정보 알림이 표시됩니다:

  2. 아웃렛에 컴포넌트를 추가하면 기본 알림 대신 렌더링됩니다:

  3. 그러나 하나의 아웃렛에 여러 컴포넌트를 추가하면 오류가 발생합니다:

  4. 다른 아웃렛에는 여러 컴포넌트를 추가할 수 있습니다. 플러그인 아웃렛이 표시된 뷰입니다:

따라서 새로운 아웃렛이 어떻게 작동해야 하는지 궁금합니다:

  • 어떤 면에서는 아웃렛이 필요하지 않을 수도 있습니다. 다른 사용 가능한 아웃렛을 사용하고 컴포넌트를 discovery.custom 라우트로 제한하면 되기 때문입니다.
  • 하지만 아웃렛에 최소 한 개의 컴포넌트를 넣어야 하는 것 같습니다. 그렇지 않으면 기본 알림이 렌더링됩니다. 빈 템플릿을 넣는 것은 작동하지 않습니다.
  • 반면, 아웃렛에 여러 컴포넌트를 추가할 수 있다면 라우트 로직이 전혀 필요 없을 것입니다. 아웃렛이 다른 라우트에서는 사용되지 않기 때문에 컴포넌트는 홈페이지에서만 표시될 것입니다.

그럼이 당연하지 않나요?

여기에 템플릿 파일을 하나만 두고, Components 폴더(여기에는 여러 개를 둘 수 있습니다)의 컴포넌트를 참조하세요.

<MyFirstComponent />
<MySecondComponent />
<MyThirdComponent />

또는 원하시는 대로 하셔도 됩니다 … 이 폴더에는 템플릿을 하나로 유지하는 것이 좋을까요?

다른 매체에서는 작동하니까 그렇다고 생각했어요. 위 스크린샷처럼요..

아, 미안합니다. 말씀이 맞으시네요. Outlets(보통은)에서는 하나의 Theme Component에 템플릿 파일을 하나 이상 게시하는 것이 합법적인 것 같습니다(Theme Component와 플러그인 간의 충돌을 처리하므로 모두 렌더링될 수 있다는 점은 알고 있었습니다). 흥미롭네요.

그런데 제 생각에는: 왜 그렇게 하고 싶으신가요? 레이아웃에 대한 제어력이 줄어들지 않나요?

하나의 템플릿은 원하는 수의 하위 컴포넌트를 사용하여 전체 레이아웃을 한 번에 구성하도록 강제하지 않나요?

다만, 동작이 일관되지 않은 것처럼 보이긴 합니다…

커스텀 홈페이지를 만들려면, 그 페이지에서 여러 개의 기존 컴포넌트를 렌더링할 수 있어야 합니다. 그리고 앞서 언급했듯이, 다른 가용한 아웃렛을 사용하고 컴포넌트를 커스텀 홈페이지 경로로 제한하면 이미 이 기능이 작동합니다.

만약 해당 커스텀 홈페이지 아웃렛에 컴포넌트를 하나만 추가할 수 있고, 기본 yield를 비활성화하기 위해 또 다른 컴포넌트를 추가해야 한다면, 이는 실제로 레이아웃 제어 능력을 제한하는 것이 됩니다.

그런데 왜 모든 컴포넌트를 하나의 템플릿에서 참조할 수 없나요?

아, 서로 다른 테마 컴포넌트에서 가져오는 것이기 때문인가요?

우리가 서로 다른 이야기를 하고 있었던 것 같습니다.

(Ember) 컴포넌트를 모두 Components 폴더에 넣으라고 할 때, 저는 정확히 하나의 테마 컴포넌트 안에서 그렇게 하라는 뜻이었습니다.

이 문제의 핵심은 단순히 "왜 이 아웃렛은 다르게 동작하나요?"라고 생각합니다. 서로 다른 테마 컴포넌트를 결합하려는 시도를 하고 있다는 점은 이해합니다.

네, 그런 뜻입니다. 위에는 예시를 위해 일반 텍스트 템플릿을 사용했습니다. 예를 들어 Featured Lists를 사용합니다. 그리고 이 설정으로 아웃렛에 렌더링할 수 있습니다:

하지만 같은 방식으로 다른 것을 렌더링하려고 하면 다중 커넥터 오류가 발생합니다.

:+1:t4:

이것을 테스트해 주시고 질문해 주신 @manuel 님 감사합니다.

저도 이 질문에 대한 답을 몰랐지만, 살펴본 끝에 대략적인 이유를 파악했습니다. 지난 해 이 PR(DEV: Allow PluginOutlets to 'wrap' a core implementation - Pull Request #23110 - discourse/discourse - GitHub)을 통해 클래식 플러그인 아웃렛과 래퍼(wrapper) 플러그인 아웃렛 간의 구분을 최근에 도입했습니다.

래퍼 플러그인 아웃렛은 연결자(connector)를 하나만 허용하는 반면, 나머지는 다수를 허용합니다. 예를 들어, 현재 코어 플러그인 아웃렛 코드는 다음과 같습니다:

<PluginOutlet @name="custom-homepage">
  {{#if this.currentUser.admin}}
    <p class="alert alert-info">
      {{i18n "custom_homepage.admin_message"}}
    </p>
  {{/if}}
</PluginOutlet>

이것은 연결자를 하나만 허용합니다. 하지만 코어 아웃렛 코드를 다음과 같이 변경하면:

<PluginOutlet @name="custom-homepage" />

여러 개의 연결자 템플릿을 문제없이 허용합니다. 우리는 이 특정 아웃렛에 대해 코어에서 이 변경을 수행할 수 있지만, 이 차이는 더 일반적인 문제입니다. 다만 개발자 입장에서 다소 불투명하게 느껴질 수 있다는 점은 이해합니다.

또한, 여러 연결자가 순서 문제를 가지고 있으며, AFAIK(제 지식范围内) 순서를 결정하는 메커니즘이 없습니다.

어쨌든, 여기서는 @merefield 님이 제안한 것이 가장 좋은 접근 방식이라고 생각합니다: 하나의 템플릿을 사용하되, 그 안에서 Ember 컴포넌트를 참조하는 것입니다.

참고로, 기본 알림은 관리자만 볼 수 있습니다.

설명해 주셔서 감사합니다!

더いろいろ하게 시도해 보고 있는데… 정말 신선하고 사용하기도 즐겁습니다!

이 레이아웃을 위해 기존 컴포넌트 3개를 사용했는데, 커스텀 홈페이를 만들 때 일반적으로 기대하는 방식이라고 생각합니다. 하지만 래퍼 아웃렛에 이 중 하나만 추가할 수 있어서, 여기에는 단순한 아웃렛이 있는 것이 더 도움이 될 것 같다고 생각합니다.

또 다른 관찰 사항: /custom URL을 사용하여 사이드바에 링크를 추가했습니다:

커스텀 라우트에 있을 때 하이라이트가 되지 않습니다.

사이드바 하이라이트 로직을 제 이해대로라면, 루트 URL /에 있을 때도 하이라이트가 되어야 합니다.

Featured Lists 컴포넌트를 빠르게 살펴본 후, 문제가 무엇인지 더 명확하게 파악했습니다. 한 가지 옵션은 해당 컴포넌트를 리팩토링하여 모든 목록을 하나의 Ember 컴포넌트로 출력하도록 하는 것입니다. 그런 다음 그 컴포넌트를 플러그인 래퍼 아웃렛에 추가할 수 있습니다.

또 다른 옵션은 커스텀 홈 페이지 템플릿에 두 번째 플러그인 아웃렛을 추가하는 것입니다. 예를 들어 <PluginOutlet @name="below-custom-homepage"/>와 같은 형식입니다.

솔직히 말하면, 관리자용 메시지로 이 custom-homepage 아웃렛을 유지하는 데는 큰 이유가 없습니다. 그 경고가 그렇게 유용하지도 않으니까요…

네, 그 부분은 까다로울 수 있습니다. 방금 로컬 테스트를 해보았는데, /custom에서는 제대로 작동하지 않습니다. 라우팅이 올바르게 이루어지려면 /를 사용하는 것이 더 좋습니다. 하지만 여전히 하이라이트가 되지 않습니다.

이것은 일반적인 문제인 것 같습니다. / 를 사용해도 랜딩 페이지로 설정된 다른 라우트도 하이라이트되지 않습니다.

네, 경고가 다르게 표시되는 것도 상상할 수 있습니다. 래퍼 아웃렛의 주요 이점은 코어 코드를 조건부로 yield 하거나 커스텀 코드를 렌더링할 수 있다는 것입니다. 하지만 그 정보 메시지에 대해서는 그런 경우가 거의 없을 것입니다.

오해가 있는 것 같습니다. 해당 컴포넌트는 이미 모든 목록을 하나의 래핑 컴포넌트 안에 감싸서 주어진 아웃렛에 렌더링하고 있습니다:

image

따라서 현재 커스텀 홈 페이지의 래퍼 아웃렛에 해당 컴포넌트를 문제없이 추가할 수 있습니다.
제가 할 수 없는 것은 커스텀 홈 페이지에서 그 아웃렛을 사용하여 독립형 컴포넌트 하나 이상을 렌더링하는 것입니다. 테마 컴포넌트로 설치했을 컴포넌트들, 예를 들어 이 세 가지처럼요:

커스텀 홈 페이지를 구축하기 위해 이러한 독립형 테마 컴포넌트 여러 개를 사용하는 것이 일반적인 접근 방식이라고 생각합니다. 하나의 테마에서 처음부터 끝까지 모두 구축하는 것보다는요.

다른 아웃렛을 추가하거나 아웃렛 구성을 변경하는 것을 고려 중이시라면, 제가 지금까지 사용하면서 느낀 점을 더 자세히 피드백해 드릴 수 있습니다. 다만 그 토끼 구멍을 디테일로 감싸게 될 것입니다 :smile:

아웃렛이 main-outlet 요소 내부에서 렌더링된다는 것을 깨달았습니다. 이 요소들의 전체 구조는 다음과 같습니다:

  • main-outlet 래퍼
    • sidebar-wrapper
    • main-outlet
      • custom-homepage 아웃렛

디자이너로서, 이 아웃렛을 사용하여 커스텀 홈 페이지에서 항목을 배치하는 것은 그렇게 유연하지 않습니다. 위에서 공유한 디자인의 경우, 여러 컴포넌트를 배치할 수 있을 뿐만 아니라 main-outlet 요소 내부에 컴포넌트를 중첩하지 않기 때문에 before-main-outlet 아웃렛을 사용했습니다.

위 스크린샷에 공유한 구조는 다음과 같습니다:

  • main-outlet 래퍼
    • sidebar-wrapper
    • component: search banner
    • component: featured topics
    • component: featured lists
    • main-outlet

장점은 main-outlet 요소 내부에서만이 아니라 main-outlet 래퍼의 전체 너비로 요소를 배치할 수 있다는 것입니다. 이 점을 설명하기 위해, 현재 custom-homepage 아웃렛에 컴포넌트 중 하나를 렌더링하면 main-outlet 요소 내부에 중첩되어 다음과 같이 렌더링됩니다:

제 생각에 커스텀 디자인에 대한 가장 큰 유연성은 다음과 같이 배치된 플러그인 아웃렛에서 제공될 것입니다:

  • main-outlet 래퍼의 직접 자식으로 (before-main-outlet 아웃렛과 유사하게)
  • 래핑 div 내부에

그 래핑 div는 추가된 모든 컴포넌트를 묶어주고 정렬을 쉽게 허용합니다. 그런 구조는 다음과 같이 보일 것입니다:

  • main-outlet 래퍼
    • sidebar-wrapper
    • custom-homepage-wrapper
      • component: search banner
      • component: featured topics
      • component: featured lists
    • main-outlet

그러므로 이것이 디자이너로서의 제 피드백입니다. 커스텀 홈 페이지 기능의 일반적인 응용으로 고려하는 것과 얼마나 일치하는지는 당신이 결정할 문제일 것입니다.

아마도 이 페이지는 사용자가 볼 수 있지만 "Googlebot"에게는 표시되지 않으므로 인덱싱되지 않는 "표면적"인 페이지일 것입니다.

맞아요, 크롤러 뷰의 경우 상단 메뉴만 출력하도록 설정했습니다. Rails 앱에서는 해당 라우트에서 테마가 무엇을 출력할지 정확히 알기 어렵거든요.

여기서 제안된 내용들을 @manuel 님과 함께 고민해 보고, 곧 시간을 내서 몇 가지 변경 사항을 테스트해 보겠습니다. :bear: 잠시만 기다려 주세요.

이 기능에 대한 지원을 Discourse Bars 🍻 🍸 (a sidebar framework) - #43 by merefield 에 추가했습니다.

제가 겪은 문제입니다. 홈페이지 기능 컴포넌트를 사용자 지정 홈페이지에 표시하고 싶었습니다. 하지만 이 경로에서는 토픽이 필터링되지 않습니다. 해당 컴포넌트는 이미지가 있는 최근 토픽을 아무거나 표시할 뿐입니다.

컴포넌트의 코드는 다음과 같습니다:

    const topicList = await this.store.findFiltered("topicList", {
      filter: "latest",
      params: {
        tags: [`${settings.featured_tag}`],
        order: sortOrder,
      }

사용자 지정 홈페이지에서는 params가 적용되지 않는 것으로 보입니다. 다른 곳에서는 정상적으로 작동합니다. 왜 이런 현상이 발생하는지 확신이 서지 않습니다.

수정: 추천 목록 컴포넌트에서도 동일한 메서드를 사용하고 있습니다. 이 컴포넌트를 사용자 지정 홈페이지에 사용할 경우에도 필터가 적용되지 않습니다. 하지만 첫 번째 목록에서만 그런 것이며, 목록이 더 있으면 그 이후의 목록들은 모두 올바르게 필터링됩니다.

흥미롭네요. 왜 그런지는 정확히 모르겠지만, topicList 스토어에 discovery 라우트와 연결된 로직이 있는 것 같아요. 커스텀 홈페이지는 discovery 라우트가 아니거든요.

궁금한 점이 있는데, 파라미터를 가진 그 동일한 컴포넌트가 admin 라우트나 사용자 프로필 라우트에서는 정상적으로 작동하나요? 확인해 주실 수 있을까요?

@tynaut 도 비슷한 문제를 겪었으니, 여기서 처리해야 할 무언가가 있을 가능성이 높습니다.

Featured Lists 컴포넌트를 사용해 봤는데, 이미 해당 컴포넌트를 모든 곳에 표시하도록 설정하는 옵션이 있습니다. 이 설정에는 관리자 라우트가 포함되지 않지만, 그 외 모든 곳(정적 페이지, 사용자 프로필 등)에서 시도해 보니 커스텀 홈페이지를 제외하고는 모든 곳에서 정상적으로 동작하는 것으로 보입니다.

또 다른 이상한 점은 언급했듯이 첫 번째 목록만 필터링이 되지 않는다는 것입니다. 예를 들어 여기서는 두 개의 목록을 필터링하고 있는데, 하나는 ‘featured’ 태그를 위한 것이고 다른 하나는 ‘General’ 카테고리를 위한 것입니다. 다른 모든 라우트에서 목록은 다음과 같이 표시됩니다:

하지만 커스텀 홈페이지 라우트에서는 다음과 같이 표시됩니다:

즉, 첫 번째 목록은 더 이상 태그로 필터링되지 않지만, 두 번째 목록은 카테고리로 필터링됩니다. 그리고 목록의 순서를 바꾸면, 첫 번째 목록은 카테고리로 필터링되지 않고 두 번째 목록은 태그로 필터링됩니다:

Featured Homepage 컴포넌트로 이 문제를 제대로 재현하는 것이 다소 까다로웠습니다. 다른 조건들이 너무 많이 섞여 있기 때문입니다.

다만, 단순화된 컴포넌트로라면 쉽게 재현할 수 있습니다. 샘플 저장소를 여기에 올렸습니다: GitHub - pmusaraj/discourse-sample-custom-homepage · GitHub

해당 저장소의 sample-list 컴포넌트는 featured 태그가 붙은 주제만 가져와야 하지만, 그렇지 않습니다(제 환경에서는 처음 3개의 주제가 가져와집니다). 해당 테마의 about.json 파일에서 custom_homepage 수정자를 제거하면 올바른 주제가 가져와집니다.

store 서비스에 더 익숙한 사람을 찾아서 확인을 요청하겠습니다. 감사합니다!

안녕하세요

home.hbs 파일에 검색 배너나 포럼에 이미 설치된 사용자 정의 컴포넌트를 추가하여 새로운 사용자 정의 홈페이지에 표시되도록 하는 방법을 설명해 주실 수 있을까요?

감사합니다