Tabbis 主题组件

您好!我正在尝试创建一个主题组件来使用外部脚本 tabbis.js,以便在帖子中创建选项卡。我遵循了这里的教程:Embed widget within text in a topic - #2 by Johani

这是我目前的主题组件的样子。

Common > Header

<script type="text/discourse-plugin" version="0.8">
// options
const TABBIS_SCRIPT_SRC = "https://cdn.jsdelivr.net/gh/jenstornell/tabbis.js/assets/js/src/tabbis.es6.js";

// we use the Discourse Load script lib to ensure scripts are loaded
// properly. Don't worry, this is smart enough to not duplicate the script
// if it's already loaded
const loadScript = require("discourse/lib/load-script").default;

// create a post decorator
api.decorateCookedElement(
  post => {
    // does this post have tabbis tabs?
    const tabbisTabs = post.querySelectorAll('[data-wrap="tabbis"]');

    // Yes, so let's do some work.
    if (tabbisTabs.length) {
      // for each tabbis widget
      tabbisTabs.forEach(tabbisTab => {

        // load the tabbis script.
        loadScript(TABBIS_SCRIPT_SRC).then(() => {

          // everything is ready, let's call the tabbis script
          tabbis();
        });
      });
    }
  },
  // add an id to the decorator to avoid memory leaks
  { id: "render-tabbis-tabs" }
);

</script>

Common > CSS (copied straight from the tabbis.js repo)

[data-tabs],
[data-panes] {
  --color: #000;
}

[data-tabs] {
  background: var(--color);
  border: 2px solid var(--color);
  border-bottom: none;
  overflow-x: auto;
  display: flex;
}
[data-tabs] > [role="tab"] {
  all: unset;
  padding: 0.75rem 1.5rem;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  font-weight: 600;
  color: #fff;
  border: 1px solid transparent;
  outline: none;
}
[data-tabs] > [role="tab"]:hover {
  background: rgba(255, 255, 255, 0.2);
}
[data-tabs] > [role="tab"]:active {
  background: rgba(255, 255, 255, 0.3);
}
[data-tabs] > [role="tab"]:focus {
  border: 1px dotted rgba(255, 255, 255, 0.5);
}
[data-tabs] > [role="tab"][aria-selected="true"] {
  background: #fff;
  color: #000;
}
[data-tabs] > [role="tab"][aria-selected="true"]:focus {
  border: 1px dotted rgba(0, 0, 0, 0.5);
}

[data-panes] {
  border: 2px solid var(--color);
  border-top: none;
}
[data-panes] > * {
  background: #fff;
  padding: 2rem;
  font-weight: 600;
  outline: none;
  border: 1px solid transparent;
}
[data-panes] > *:focus {
  border: 1px dotted rgba(0, 0, 0, 0.5);
}
@media screen and (max-width: 460px) {
  [data-panes] > * {
    padding: 1rem;
  }
}

Content Security Policy Script src: added https://cdn.jsdelivr.net

Post markup

[wrap="tabbis"]<div data-tabs>
<button>Tab1</button>
<button>Tab2</button>
<button>Tab3</button>
</div>

<div data-panes>
<div>Pane1</div>
<div>Pane2</div>
<div>Pane3</div>
</div>[/wrap]

脚本在我编辑帖子后似乎加载了一瞬间,但一旦完全加载就无法使用了。

这出现在控制台中,但我不知道如何修复。是否存在与 Discourse 中的其他选项卡冲突?

我该如何让它工作?我束手无策!

1 个赞

我认为您需要一个插件来实现这一点,不过我也可能弄错。

您可以查看 math 插件或插件指南。

此脚本为何需要插件而不是主题组件?单页应用程序结构对我来说仍然很新。

请分享您的整个主题组件源代码(最好是 GitHub 存储库),以便我们轻松地为您提供帮助。

顺便说一句,这听起来像是一个非常有用的主题组件!

6 个赞

谢谢!我很惊讶地发现这里还没有某种标签插件或组件;这是我非常希望为我的社区实现的功能,所以我正在尝试一下。我对除了非常基础的 JavaScript 之外的任何东西都相当陌生,但我正在努力学习。

2 个赞

将帖子标记更改为

[wrap="tabbis"]
  <div>
    <span>Tab1</span>
    <span>Tab2</span>
    <span>Tab3</span>
  </div>

  <div>
    <div>Pane1</div>
    <div>Pane2</div>
    <div>Pane3</div>
  </div>
[/wrap]

即可生效 :tada:

您可以注意以下几点以进一步改进:

  1. 请勿多次调用 loadScript。在调用之前检查它是否已加载,否则它将被调用多次。

  2. tabbis() 调用传递一个更具体的选择器,以便初始化您专门选择的那个。

6 个赞