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

**URL:** https://meta.discourse.org/t/some-issues-configuring-a-theme-component-to-integrate-with-pretix/265586
**Category:** Development
**Created:** [2023年五月19日 18:13 UTC](https://meta.discourse.org/t/some-issues-configuring-a-theme-component-to-integrate-with-pretix/265586 "2023-05-19T18:13:15Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![vai](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vai/32/102803_2.png) [@vai](https://meta.discourse.org/u/vai)
#### Post date: [2023年五月19日 18:13 UTC](https://meta.discourse.org/t/some-issues-configuring-a-theme-component-to-integrate-with-pretix/265586/1 "2023-05-19T18:13:16Z")

</div>

您好 -

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

我正在与我的 [pretix](https://pretix.eu/about/en/) 安装（用于销售活动门票）集成。这应该只是将 [HTML 添加到帖子中，并确保包含 pretix HTML 和 CSS](https://docs.pretix.eu/en/latest/user/events/widget.html)。

```html
<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-*]` 排除。

```js
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 中有一些特别惯用的方法可以做到这一切——但我想，我不需要成为主题专家就能进行如此轻量级的集成。

我很乐意获得一些指导。

---

<div class="post-metadata">

### Author: ![michaeld](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/michaeld/32/1594_2.png) [@michaeld](https://meta.discourse.org/u/michaeld)
#### Post date: [2023年五月20日 11:14 UTC](https://meta.discourse.org/t/some-issues-configuring-a-theme-component-to-integrate-with-pretix/265586/2 "2023-05-20T11:14:08Z")

</div>

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

---

<div class="post-metadata">

### Author: ![vai](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vai/32/102803_2.png) [@vai](https://meta.discourse.org/u/vai)
#### Post date: [2023年五月20日 15:35 UTC](https://meta.discourse.org/t/some-issues-configuring-a-theme-component-to-integrate-with-pretix/265586/3 "2023-05-20T15:35:49Z")

</div>

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

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

* * *

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

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [2023年六月19日 15:36 UTC](https://meta.discourse.org/t/some-issues-configuring-a-theme-component-to-integrate-with-pretix/265586/4 "2023-06-19T15:36:31Z")

</div>

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