您好 -
我还没有通过任何我能找到的方法让它工作,我想知道是不是我的期望有问题。
我正在与我的 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 中有一些特别惯用的方法可以做到这一切——但我想,我不需要成为主题专家就能进行如此轻量级的集成。
我很乐意获得一些指导。