こんにちは。
これまで、見つけたいずれの方法でもこれを機能させることができず、私の期待が間違っているのかどうかを知りたいです。
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スクリプト/スタイルを含め、投稿にウィジェット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でこれをすべて行うための特に慣用的な方法があると思いますが、このような軽量な統合を実行するために専門家になる必要がないことを願っていました。
ここでガイダンスを得られることを嬉しく思います。