사이드바에 사용자 정의 변경 사항을 프로그래밍 방식으로 적용하는 방법

훌륭한 기능이지만, 커스텀 사이드바 섹션의 콘텐츠가 프로그래매틱하게 생성되어야 하는 경우 어떻게 해야 할까요? 저는 위 @Olya_Fursova와 유사한 방식으로 이를 구현했습니다. 다만 콘텐츠는 API를 쿼리하여 생성한 후, 일부는 카테고리로, 일부는 특정 주제로 직접 연결되는 링크를 렌더링하는 방식입니다. 제가 겪은 두 가지 문제는 다음과 같습니다:

  • 페이지가 처음 렌더링될 때 사이드바가 숨겨져 있다면, 사이드바 컨테이너가 존재하지 않아 동적 콘텐츠가 표시되지 않습니다. 또한 사이드바가 처음에는 표시되다가 접힌 후 다시 표시되면, 커스텀 로직이 실행되지 않은 상태로 사이드바 컨테이너가 다시 렌더링되어 동적 콘텐츠가 사라집니다. 질문: 사이드바가 표시될 때마다 커스텀 코드를 실행할 수 있도록 사이드바 렌더링 프로세스에 훅을 걸 수 있는 방법이 있을까요?
  • 프로그래매틱하게 사이드바에 추가한 링크를 클릭하면 페이지 전체가 새로고침됩니다. 질문: 사이드바의 커스텀 링크 중 하나를 클릭할 때 페이지 전체 새로고침을 방지할 수 있는 방법이 있을까요?

사이드바를 프로그래매틱하게 수정할 수 있는 방법이 있다면 정말 훌륭할 것입니다!

커스텀 사이드바 섹션을 추가하기 위한 API도 구축했습니다.

여기 댓글에 몇 가지 예시가 있습니다: discourse/app/assets/javascripts/discourse/app/lib/plugin-api.js at 00ab94bf53b784478d0aa7744bf3bb2d5b527580 · discourse/discourse · GitHub

이것은 실험적 기능으로 표시되어 있지만, 안전하게 사용할 수 있습니다(예: 활성화된 경우 채팅 콘텐츠를 사이드바에 추가하는 데 사용함).

흥미롭네요, 감사합니다! 다만 이걸 제대로 이해하려면 시간이 좀 걸릴 것 같습니다. 예를 들어, 라우팅이 아직은 잘 안 잡히거든요. 또한, 섹션 안의 링크는 평탄한(flat) 목록으로만 구성되는 것 같은데 맞나요? 제가 현재 시도하고 있는 것은 다음과 같은 형태, 즉 한 단계의 들여쓰기(indentation)가 있는 구조입니다:

이것은 커스텀 사이드바 섹션을 위한 새로운 API로 구현할 수 있을까요?

아니요, 기본적으로 사이드바에 들여쓰기를 적용하지는 않았습니다… 하지만 API를 통해 섹션을 원하는 순서로 정렬할 수 있다면, 들여쓰기는 CSS 스타일링으로 처리할 수 있을 것 같습니다?

조금 더 조사해 본 결과, 이것이 작동할 것이라고 확신합니다! 지금의 문제는 링크 목록이 동적이며 페이지가 변경될 때마다 잠재적으로 바뀔 수 있다는 점입니다. api.onPageChange 안에서 api.addSidebarSection을 호출하는 제 단순한 접근 방식은 작동하지 않습니다. 그 이유는 (a) 사이드바가 다시 렌더링될 때만, 즉 숨겼다가 다시 표시할 때만 새로고침되고 (b) api.addSidebarSection은 이름 키가 재사용되는지 여부에 관계없이 섹션이 반복되어 추가되기 때문입니다.

새로운 API를 사용하여 페이지 전환 시마다 업데이트되는 사이드바 섹션을 만들 수 있을까요?

chat 플러그인이 사이드바와 어떻게 통합되는지 확인해 보세요:

이 경우 링크의 상태는 서비스 객체에 저장되며, 상태가 변경될 때마다 사이드바가 업데이트됩니다:

잠재적인 해결책은 페이지 변경 이벤트에 구독(subscribe)하여 링크를 업데이트하는 것입니다. 의사 코드(pseudocode)는 다음과 같이 작성할 수 있습니다:

import { tracked } from "@glimmer/tracking";

api.addSidebarSection(
  (BaseCustomSidebarSection, BaseCustomSidebarSectionLink) => {
    const TestSectionLink = class extends BaseCustomSidebarSectionLink {
      // 여기에서 사용자 정의 링크 속성을 정의합니다
    };

    const SidebarTestSection = class extends BaseCustomSidebarSection {
      @tracked links = [];

      constructor() {
        super(...arguments);

        this.#updateLinks();
        this.onAppEvent("page:changed", () => this.#updateLinks());
      }

      get newLinksArray() {
        // 현재 URL 기반의 링크 목록
      }

      #updateLinks() {
        this.links = this.newLinksArray.map(
          (link) =>
            new TestSectionLink({
              link,
            })
        );
      }

      get sectionLinks() {
        return this.links;
      }
    };
    return SidebarTestSection;
  }
);