Bootbox가 더 이상 지원되지 않습니다

이 커밋부터:

다이얼로그를 위한 bootbox 라이브러리는 더 이상 사용되지 않습니다(deprecated).

개발자 여러분께서는 커스텀 테마와 플러그인에서 bootbox 대신 코어의 dialog 서비스를 사용해 주십시오. bootbox 라이브러리는 2023년 중 코어 Discourse에서 완전히 제거될 예정입니다.

다이얼로그 서비스로의 전환 방법을 보여주는 플러그인과 테마의 예시 PR은 다음과 같습니다:

사용자 정의 테마에 다음과 같은 코드가 있습니다:

<script type="text/discourse-plugin" version="0.8">
    bootbox.alert('alert text');
</script>

대화가 전역적으로 사용 가능하지 않은 것으로 보이는데, 테마에서 대화(dialog) 서비스에 액세스하는 방법은 무엇인가요?

가장 간단한 방법은 lookup을 사용하여 서비스를 로드하는 것입니다. 다음은 예시 코드입니다(이 코드는 테스트되지 않았지만, Ember 컴포넌트/컨트롤러/루트 외부에서 코어에 이와 유사한 것을 사용합니다):

<script type="text/discourse-plugin" version="0.8">
  import { getOwner } from "discourse-common/lib/get-owner";
  const dialog = getOwner(this).lookup("service:dialog");
  dialog.alert('alert text');
</script>

감사합니다. 이를 시도해 보았지만 다음과 같은 오류가 발생했습니다:
SyntaxError: /discourse/theme-11/initializers/theme-field-36-common-html-script-2: 'import' 및 'export'는 최상위 수준에서만 나타날 수 있습니다. (13:4)

아, 맞아요. 이 스크립트 태그에서는 require를 사용해야 합니다. 공유가 가능하다면, 현재 작성 중인 전체 코드를 보여줄 수 있을까요? 이 <script> 태그에 대한 대안을 제안하고 싶습니다. 저희가 직접 관리하는 테마 컴포넌트에서 대부분의 테마 코드를 별도의 JS 파일로 분리했는데, 여기서 더 일반적인 리팩토링을 진행하는 것이 더 쉬울 수도 있습니다.

제안해 주셔서 감사합니다! 아래는 전체 스크립트입니다 (일부 텍스트가 약간 수정됨). 이 스크립트는 Bootbox 팝업이 HTML 태그를 올바르게 렌더링하지 못하기 전까지는 잘 작동했습니다.

<script type="text/discourse-plugin" version="0.8">
    if (typeof bootbox === 'undefined') {
        console.log('Cannot trigger undefined "bootbox"');

        return;
    }

    let currentUser = api.getCurrentUser();

    if (currentUser) {
        api.container.lookup('store:main').find('user', currentUser.username).then((user) => {
            let userGroups = user.groups.map(group => group.name);

            let bodyClasses = userGroups.map(group => `user-group--${group}`);

            document.querySelector('body').classList.add(...bodyClasses)

            let showPopup;

            switch(true) {
                case userGroups.includes('restricted_member'):
                    showPopup = true;
                    break;
                case userGroups.includes('users_all'):
                case userGroups.includes('officers'):
                    showPopup = false;
                    break;
                default:
                    showPopup = true;
                    break;
            }

            if (!showPopup) {
                return;
            }

            let alertHeading = '<h2>Oh no!</h2>';

            let alertBody = '<p>Your account is currently restricted and you no longer have access to valuable resources. <a href="https://meta.discourse.org">Click here</a> for more information.</p>';

            bootbox.alert(alertHeading + alertBody);
        });
    }
</script>

Tim님, 안녕하세요.

대안안을 첨부합니다. 여기 포함된 내용은 컴포넌트의 초기화(initializer) JS 파일에 들어가야 한다는 점에 유의해 주세요. 전체 컴포넌트 구조의 간단한 예시는 여기에서 확인하실 수 있습니다.

import { withPluginApi } from "discourse/lib/plugin-api";
import { getOwner } from "discourse-common/lib/get-owner";
import { schedule } from "@ember/runloop";
import { htmlSafe } from "@ember/template";

export default {
  name: "tester-initializer",

  initialize() {
    withPluginApi("0.8", (api) => {
      const currentUser = api.getCurrentUser();

      if (currentUser) {
        const userGroups = currentUser.groups.map((group) => group.name);
        let showPopup = false;

        switch (true) {
          case userGroups.includes("admins"):
            showPopup = true;
            break;
        }

        if (!showPopup) {
          return;
        }

        const alertHeading = "Oh no!";
        const alertBody =
          'Your account is currently restricted and you no longer have access to valuable resources. <a href="https://meta.discourse.org">Click here</a> for more information.';

        schedule("afterRender", () => {
          // delay needed so that the dialog service is loaded
          const dialog = getOwner(this).lookup("service:dialog");
          dialog.alert({
            message: htmlSafe(alertBody),
            title: alertHeading,
          });
        });
      }
    });
  },
};

도움이 되셨으면 좋겠습니다.

완벽합니다. 정말 감사합니다!

이 PR(DEV: remove bootbox dependency - Pull Request #27443 - discourse/discourse - GitHub)으로 bootbox의 비추천 사용(deprecation) 문제가 완전히 해결되었습니다. 최초 게시글(OP)에 언급된 대로, 대신 dialog 서비스를 사용하세요.