Bootbox 现已不推荐使用

截至此提交:

用于对话框的 bootbox 库现已弃用。

开发人员,请在您的自定义主题和插件中使用核心中的 dialog 服务,而不是 bootbox。bootbox 库将在 2023 年的某个时候从 Discourse 核心中完全移除。

以下是来自插件和主题的一些示例 PR,展示了如何迁移到 dialog 服务:

3 个赞

在我的自定义主题中,我有类似这样的内容:

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

如何在主题中访问 dialog 服务,因为它似乎不是全局可用的?

最简单的选择是使用查找来加载服务。这是一个示例代码(未经测试,但我们在核心中使用类似的代码,在 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>
1 个赞

谢谢。我试过这个但出现了一个错误:
SyntaxError: /discourse/theme-11/initializers/theme-field-36-common-html-script-2: 'import' 和 'export' 只能出现在顶层。(13:4)

1 个赞

啊,对了,我们需要在这些脚本标签中使用 require。如果方便分享的话,你这里的完整代码是什么?我想为这个 <script> 标签提供一个替代方案,我们已经将大部分主题代码移到了我们自己维护的主题组件的独立 JS 文件中,在这里为你进行更通用的重构可能会更容易。

1 个赞

感谢您的提议!这是完整的脚本(其中一些文本已稍作修改),它之前运行正常,直到我们发现 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>
1 个赞

你好 Tim,
这是替代方案,请注意这里的内容需要放在组件中的初始化 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 = "哦不!";
        const alertBody =
          '您的帐户目前受到限制,您不再可以访问有价值的资源。 \u003ca href="https://meta.discourse.org"\u003e点击这里\u003c/a\u003e 获取更多信息。';

        schedule("afterRender", () => {
          // 需要延迟,以便对话框服务已加载
          const dialog = getOwner(this).lookup("service:dialog");
          dialog.alert({
            message: htmlSafe(alertBody),
            title: alertHeading,
          });
        });
      }
    });
  },
};

希望这有帮助。

3 个赞

太棒了。非常感谢!

1 个赞

此 PR 完全解决了 bootbox 的弃用问题:https://github.com/discourse/discourse/pull/27443。根据 OP 的说法,请改用 dialog 服务。

3 个赞

此主题在 11 天后自动关闭。不再允许回复。