世界を動かす技術を、日本語で。

Show HN: JavaScriptなしの(X)HTMLインクルード

概要

  • XSLT を利用した 静的ウェブサイト の共通テーマ適用手法の紹介
  • サーバーサイド処理やビルドステップ不要 のシンプルな実装
  • ヘッダーやフッターのコピペ排除 による効率化
  • どのウェブサーバー でも動作可能な互換性
  • XSLTサポート終了議論 を踏まえたデモの意義

XSL-Websiteによる静的ウェブサイトの共通テーマ適用

  • ブラウザの 組み込みXSLサポート を活用したウェブサイト構築手法
  • サーバーサイドコード・静的サイトジェネレーター・JavaScript 不要
  • index.xml などのXMLファイルをブラウザで開くと、XML冒頭で指定したテンプレート(XSLファイル)を自動読み込み
  • テンプレートファイルが、XML内の カスタムタグ をHTMLへ変換する仕組み
  • advanced/ ディレクトリには、フィールド付きテンプレートや、テンプレートの入れ子利用など、より高度な例も用意

XSLTによるテンプレート機能の特徴

  • JekyllやHugo のようなビルドステップ不要、 公開前のビルド作業を省略 可能
  • ヘッダー/フッターのコピペ不要、簡単なテンプレート記述で一貫性維持
  • どのWebサーバー でも利用可能、特別なサーバー構成やアクション不要
  • URLが通常通り (例: example.com/foobar)、ハッシュやパラメータでのページ切替不要
  • ブログ投稿 などもテンプレート化して容易に管理可能

XSLTサポートに関する注意点

  • HTML仕様からXSLTサポート除外 の議論が進行中
  • 現時点での実装例 として、サポートが残っている間の利用を推奨

関連情報・参考リンク


このアプローチは、 最小限の構成と手間で静的サイトの共通テーマ適用 を実現したい場合に有効です。 XSLTサポート終了の可能性 を考慮しつつ、現状のシンプルな選択肢として検討価値あり。

Hackerたちの意見

次のChromeのバージョンから、XSLTはフラグの後ろに隠されることになるみたい。Googleはそれを標準から削除するように頼んでるらしいよ。[0] https://github.com/WHATWG/html/issues/11523

そろそろXSLTをもっと使う時期だね。

うん、それがこの投稿のきっかけだったと思う。これで、XSLTにコンパイルするテンプレート言語のアイデアも再燃したし、今度こそやってみようかな。XSLT 3.0がウェブ標準に入ったら絶対にやるよ: https://github.com/whatwg/html/issues/11578, https://news.ycombinator.com/item?id=44987552 それに、ちょっと前にシンプルなXSLTプレイグラウンドも作ったんだ! https://xsltbin.ale.sh/

Googleが機能を標準から削除するように頼むだけで、誰も気にしないのが不思議だよね。

XSLTがもっと普及しなかったのは残念だな。確かに複雑だけど、今この問題を解決するもの(例えば、クライアントサイドで絶対に必要なReactやwebpackを使ったビルドステップ)と比べると、まだマシだよね。OPがうまく示しているように、XSLTは基本的なHTMLコンポーネントの問題を解決するための宣言的で、JavaScriptやビルドを使わない方法を提供してくれる。もしかしたら、V8の致命的な0-dayがあれば、今のベストプラクティスの代替を本当に欲しくなるかも。

次のChromeのバージョンでは、XSLTはフラグの後ろに隠されることになる。引用?それが突然で厳しいってのは、ちょっと驚きだな(今月になってやっと話し始めたし、特に企業にとってリスクが大きいって認めてるのに)し、https://chromestatus.com/feature/4709671889534976にはそんなことは書いてないよ。

期待できそう!これまでの数年間いじってきたXML/XSLTコードを見せるにはいい場所だね: https://github.com/zmodemorg/wyrm.org

2000年代にはこれをやってたな。すごく楽しかったよ。でも当時はIEのエンジンが他のXML機能よりもずっと完成度が高くて、バグも少なかった。

これ、クライアントサイドで動くよね?ユーザーがこのページに移動すると、サーバーからコンテンツを再帰的に取得するの?もしネストされたインクルードがあったら、滝のように流れる感じ?シングルページアプリのフレームワークは、クライアントから何度も往復する代わりにサーバーでレンダリングすることでほとんど解決してるし。これ、JavaScriptなしのSpinnergeddonみたいだね。ブラウザはページを表示する前にすべてのインクルードが解決されるのを待つの?それともちらつく感じ?

xsltスタイルシートを見てみると、ネストされたインクルードはないみたいで、ただの一つのスタイルシートで他は含まれてないね。リクエストの面では、cssとそんなに変わらない感じ。

サーバーサイドでコンパイルしたいなら、ci/cdでxslt変換を実行すればいいんじゃない?それでも、Jekyllよりは簡単な解決策になると思うけど、趣味プロジェクト以上にはやらないかな。

なんでHTMLインポートは残らなかったんだろう?

バカなWebコンポーネントの連中が手を出して、JavaScriptに依存させるようにして、結局サポートされなくなっちゃった。

これがxsltを削除する最近の提案に関するものであれば、CSSでも同じことができるって指摘したいな。https://bawolff.net/css-website/index.xmlはEvidloの例だけど、xsltの代わりにcssスタイルシートを使ってる。やってることを説明するためにテキストを少し変えたけど、XML自体は一つの例外を除いて変わってないよ。残念ながら、クリック可能にするためにはxhtml名前空間にタグを入れなきゃいけないけど、それ以外はXMLに変更はなし。明らかに、xsltができることはcssではできないことがたくさんあるけど、表示だけに関して言えば、ここではCSSも選択肢だね。

xsltができることはcssではできないことがたくさんある この後半部分が、過去にXSLTを使った理由だね。最近では、RSSフィードをスタイル付きのページに変換するために使ったよ。テンプレートとxpathは、ドキュメントを本当に変革できる。

CSSの例をありがとう!ところで、advanced/フォルダにはテンプレートの継承や「スロット」を示すもう少し複雑な例があるよ。

同じことをCSS Coolでもできるって指摘したいんだけど、いつCSSが標準から外されるの?

これ、ほんとにクールだけど、CSSで追加されたコンテンツは純粋に装飾的なものであることを忘れちゃダメだよ。インタラクションできないから、スクリーンリーダーみたいな支援技術には大きな問題なんだ。

うーん…あなたのCSSの例にはテンプレートのインクルードが全然ないね。ヘッダーやフッターを別ファイルに入れる方法がないよ。

ちょっと単純すぎる気がするな。少なくともいくつかのHTMLを含む例が見たいし、クリックできるリンクもあったらいいな。CSSで画像を含めることも示す価値があるかも。

xsltに不慣れな人への小さなコメント。著者はコメント[0]でワイルドカードルールに言及してるけど、それは本当だけど、アイデンティティ変換[1]を呼んでるんだ。アイデンティティ変換はxsltではとても一般的だよ。[0] https://github.com/Evidlo/xsl-website/blob/0dda1d82ce1eb01b7... [1] https://en.wikipedia.org/wiki/Identity_transform

ここでの2つの問題(クライアントサイドでのテンプレート読み込みとブラウザサポートの終了)を克服するために、PHPを混ぜて、弾力性のあるスタンダードで素晴らしいテンプレートソリューションを作れるよ: // XML $xml_doc = new DOMDocument(); $xml_doc->load("file1.xml"); // XSL $xsl_doc = new DOMDocument(); $xsl_doc->load("file.xsl"); // Proc $proc = new XSLTProcessor(); $proc->importStylesheet($xsl_doc); $newdom = $proc->transformToDoc($xml_doc); // 出力 print $newdom->saveXML(); XSLTに機能が足りない?問題なし、XSLT内でPHP関数を使えばいいよ:https://www.php.net/manual/en/class.xsltprocessor.php

あなたが説明してるのは、基本的にXSLTを中心にPHPとMySQLでまとめたCMS、Symphonyのことだね。 https://github.com/symphonycms/symphonycms 2019年以降は更新されてないと思う。XSLは本当に強力だったけど、学習曲線が急だったし、サーバーサイドのPHPとクライアントサイドのJSの方が直感的だったと思う。

これが1986年からSGML(またはXML)エンティティの最もシンプルなバリアントの動作だよ:]> こんにちは、世界!eの内容は:&e; HTMLは初めからSGMLの語彙として考えられていたんだ。SGMLの文書構成やその他の機能が、著作時にのみ使われていて、ブラウザが直接サポートしていなかったのは、最初のブラウザソフトウェアの非常に初期の段階によるものだったんだ([1])。HTML仕様が少なくともバージョン4から、HTMLを配信だけでなく著作のための言語として提示しているように、SGMLについても直接言及しているよ。ブラウザ開発者が1960年代から存在するすべての文書/マークアップ言語の一部であるテキストマクロのようなシンプルで論争のない機能のために、特異で複雑な解決策を考え出す必要は本当に無かったんだ。[1]: https://info.cern.ch/hypertext/WWW/MarkUp/MarkUp.html

外部エンティティがブラウザで有効になってほしいな()、今みたいに完全に無効になってるのは嫌だ。OPのシナリオでは、ヘッダー/フッター/スタイルシートの内容を別ファイルに持ってくることができて、CSSの絶対パスに依存しないシステムが作れるはずなんだ。()もちろん、最小限のディレクトリトラバーサルの注意を払ってね。「../」を使わないとか、「参照されるリソースのファイル名は参照するXSLファイル名で始まらなければならない」みたいな制限があれば、全然オッケーだよ。

XULRunner(Firefox、Thunderbird、Songbird、Miro、Joost、TomTom Homeなど)は、国際化やローカリゼーションのために言語特有のDTDでXML外部エンティティを悪用してたんだよね。 https://www-archive.mozilla.org/projects/intl/iuc15/paper/iu... https://en.wikipedia.org/wiki/XULRunner

これが1986年からSGML(またはXML)エンティティの最もシンプルなバリエーションの仕組みだよ:理論上はね。でも実際には、実際のSGMLパーサーを持ってるブラウザなんて一つもなくて、サポートされたこともなかった。

エンティティはXMLの悪評の大きな理由の一つでもあると思う。機密ファイルを漏らすために使われたり(XXE)、再帰的展開がDoSのベクターになったりして(大笑い)、XMLのセキュリティリスクとしての評判を固めちゃった。でもブラウザの文脈では、同一オリジンルールに従えばいいのにと思う。

20年前、EDIショップの痛い地獄から来た俺は、xmlとxsltの素晴らしさを見たんだ。クライアントにシンプルなデータを送って、余計な膨張なしでドキュメント全体を見れるって、これ以上美しいことはない。これがXSLTの目的だったんだよね:2025-08-23 John Doe 123 Sunny Boulevard Miami FL 33133 123456 何かのAppleガジェット 1 1234.56 1234.56 他のアイテムも... そのデータは何百万もの顧客に送られて、彼らはそれを開けて、XMLが人間が見やすい形式の請求書に完璧に変換されてた。肉体とシリコンが完璧に調和して幸せに暮らしてたんだ。でも、SOAPが来て、企業のスーツたちがそれをめちゃくちゃにして、余計な複雑さと苦しみを生み出したんだ。でもXML/XSLTはデータ変換のためには美しかったよ(ウェブページ用じゃなくてね)。

これをJSONに拡張すると、データファイルにJSLTソースを参照するための2行を追加するだけで、デフォルトのテンプレートシステム(ejs、mustache、handlebarsなど)を使ってブラウザで変換できるんだ。 { "JSLT": "1.0", "style": "/invoice.jsl", "data": { "invoice":{ "date": "2025-08-23", "customer": { "name": "John Doe", "address": { "line": "123 Sunny Boulevard", "city": "Miami", "state": "FL", "zip": "33133", }, }, "items": [ { "code": "123456", "description": "Some Apple gadget", "quantity": "1", "price": "1234.56", "total": "1234.56", }, { "code": "123457", "description": "Another Apple gadget", "quantity": "1", "price": "1234.57", "total": "1234.57", } ] } } } それからJSLTファイルはこうなる:請求書 日付 顧客 コード 説明 数量 価格 合計 これでXSLTを手放せるかもね。