#author("2026-08-31T22:15:44+09:00","default:guide","guide") * Pkript/文法/JSX [#d4c19816] HTMLをそのまま式として書ける記法です。文字列連結の代わりに使います。 function plugin_hello_convert(e) { const name = e.args[0]; return <p class="greeting">こんにちは、{name} さん</p>; } #contents ** 有効・無効の切り替え [#t9fd2740] 既定で有効です。plugin/pkript.inc.php の PKRIPT_JSX を 0 にすると無効になり、< は比較演算子としてだけ働きます。 ** 書ける形 [#f9c2d02a] *** 要素と入れ子 [#vc082014] return <ul><li>a</li><li>b</li></ul>; *** 空要素 [#le21ad68] return <br />; 閉じスラッシュが要ります。<br> だけでは閉じタグ待ちになります。 *** フラグメント [#jb323765] 複数の要素を、囲む要素なしで並べます。 return <><p>a</p><p>b</p></>; *** 属性 [#c30385df] 文字列か {式} を書きます。 const cls = e.opts["class"]; return <p class="fixed">x</p>; return <p class={cls}>x</p>; return <p title={42}>x</p>; - className と書いても class になります。 - 値が null の属性は出力されません。 - {...obj} のスプレッド属性には対応していません。 *** {} の中身 [#k1372e15] 式なら何でも書けます。 return <div><span>{1 + 1}</span></div>; return <ul>{items.map((x) => <li>{x}</li>).join("")}</ul>; null, false, 空文字列は何も出力しません。0 は "0" と出ます。 ** エスケープの規則 [#v4e470c5] ここがJSXの要点です。''文字列は必ずエスケープされ、JSX要素はされません。'' const s = "<li>x</li>"; // ただの文字列 return <ul>{s}</ul>; // <ul><li>x</li></ul> const el = <li>x</li>; // JSX要素 return <ul>{el}</ul>; // <ul><li>x</li></ul> wiki.convert() の戻り値もエスケープされません。Wiki記法から作ったHTMLをそのまま埋め込めます。 return <div>{wiki.convert(e.body)}</div>; *** htmlsc は使わないでください [#o13643b5] {} の中は自動でエスケープされます。htmlsc() を重ねると二重エスケープになります。 return <p>{htmlsc("<b>")}</p>; // &lt;b&gt; と出てしまう return <p>{"<b>"}</p>; // <b> が正しい *** 属性値も同じ [#g5bdd147] 属性値に入れた文字列はエスケープされます。引用符を混ぜて属性を抜け出すことはできません。 const c = "a\" onclick=\"alert(1)"; return <p class={c}>y</p>; // class ごと落とされる ** サニタイザとの関係 [#l7ddd604] JSXで書いたHTMLも、他の出力と同じようにサニタイザを通ります。JSXは記法を短くするだけで、出せるHTMLの範囲は変わりません。 |~書いたもの|~出力|h |<script>alert(1)</script>|タグごと削除| |<p onclick="...">|onclick が削除| |<p id="a">|id="pkript-a" に変換| |<a href="javascript:...">|href が削除| |<p style="position: fixed">|style が削除| |<form>|action が自Wikiに補完| 詳しくは [[Pkript/設定]] のサニタイザの節を参照してください。 親ページ: [[Pkript/文法]] ** 注意点 [#tf64a291] *** 要素を文字列として切り貼りしない [#bf918fcf] JSX要素は、出力の直前まで内部の目印として持ち回ります。length や charAt の結果は、表示されるHTMLと一致しません。 const el = <b>x</b>; return el.length; // 8 ではない 連結(+)と join() は安全です。 return <b>a</b> + <i>b</i>; return items.map((x) => <li>{x}</li>).join(""); *** タグの間の空白は消えます [#ie231a9c] return <ul> <li>a</li> <li>b</li> </ul>; 上は <ul><li>a</li><li>b</li></ul> になります。要素の中の文字列に含まれる空白はそのまま残ります。 *** HTMLコメントは書けません [#m891a476] <!-- --> は使えません。 *** < が比較演算子になる場合 [#ja45a8cc] 直前のトークンで判断します。値や ) の後ろの < は比較演算子、それ以外は JSX の始まりです。 if (n < 10) { } // 比較 return <p>x</p>; // JSX