配置主题组件以与pretix集成时遇到的一些问题

您好 -

我还没有通过任何我能找到的方法让它工作,我想知道是不是我的期望有问题。

我正在与我的 pretix 安装(用于销售活动门票)集成。这应该只是将 HTML 添加到帖子中,并确保包含 pretix HTML 和 CSS

<link rel="stylesheet" type="text/css" href="https://pretix.eu/demo/democon/widget/v1.css">
<script type="text/javascript" src="https://pretix.eu/widget/v1.en.js" async></script>

<!-- elsewhere, in a post -->
<pretix-widget event="https://pretix.eu/demo/democon/"></pretix-widget>
<noscript>
   <div class="pretix-widget">
        <div class="pretix-widget-info-message">
            JavaScript is disabled in your browser. To access our ticket shop without JavaScript,
            please <a target="_blank" href="https://pretix.eu/demo/democon/">click here</a>.
        </div>
    </div>
</noscript>

显然,pretix 脚本会按标签扫描文档中的相应元素,然后将它们替换为可自定义的条目(正如我所追求的)。

我相信我可以(并且希望)以轻量级的方式实现此集成,并且我曾想过可以通过自定义主题组件来实现,只需包含外部 pretix 脚本/样式,并将 widget HTML 添加到帖子中(即,仅进行“配置”)。

我首先遇到了 CSP 保护(很好)和 allowList(也很好)。同样,我已经添加了 CSP 配置,但现在我似乎无法在不进行实际代码修改的情况下更改 allowList——因此我不得不将“风味化”的 HTML 插入帖子中,然后尝试在渲染后修改它们。

我继续尝试在主题组件规范中使用一些轻量级的 JS(就像一个内联脚本)——类似于这样,只是使用了 allowList 的 [data-*] 排除。

function upgradeWidgets() {
    const divsWithDataEvent = document.querySelectorAll('div[data-event]');

    divsWithDataEvent.forEach((div) => {
      const attributes = div.attributes;

      for (let i = 0; i < attributes.length; i++) {
        const attr = attributes[i];
        if (attr.nodeName.startsWith('data-')) {
          const newAttrName = attr.nodeName.replace('data-', '');
          const attrValue = attr.nodeValue;

          div.setAttribute(newAttrName, attrValue);
          div.removeAttribute(attr.nodeName);
        }
      }
    });
}

当然,这现在会受到时间问题的影响——我无法挂钩 onload(脚本是否从主题组件中删除?!),并且我能从脚本中捕获的每个其他 DOM 事件都还没有到达一个点,在这个点上,这个帖子的 HTML 在文档中是可靠可用的。

我相信 Discourse 中有一些特别惯用的方法可以做到这一切——但我想,我不需要成为主题专家就能进行如此轻量级的集成。

我很乐意获得一些指导。

搜索 api.onPageChange(),这会为您提供一个处理此问题的不错位置。

3 个赞

解决了这个问题需要几个关键部分,我将在此列出供未来参考。

  • <script type="text/discourse-plugin" /> (出乎意料)
  • loadScripts (很棒)
  • api.decorateCookedElement (不是我第一个想到搜索的)
  • api.pageLoaded (有用)

仅通过“配置”,我就成功地集成了一个 pretix 和我的 Discourse 站点。

1 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.