概要
- 2000年頃からWeb開発 を経験し、様々なテンプレートエンジンや言語を試行
- Zig言語向けテンプレートライブラリzt を開発、型安全性と高速性を重視
- HTMLエスケープやXSS対策 がデフォルトで組み込まれている
- テンプレートエラーはZigのコンパイルエラー として検出可能
- Dustyやhtmxとの連携 でSPA開発も可能
20年以上にわたるWeb開発経験とZigへの転機
- 2000年頃からWeb開発 に従事、PHP 3.0リリース直後から活動開始
- HTML生成手法 として、生PHP、Pythonの文字列連結、Smarty(PHP)、Template Toolkit(Perl)、Jinja/Django(Python)などを活用
- SPAやJavaScriptフレームワークの台頭 以降、フロントエンドから一時的に離脱
- 2年前にZigを習得 し、低レベル言語でもWeb開発が現実的であることを発見
ZigでのWeb開発とテンプレートエンジンへの要望
- zioやDusty など独自エコシステムを構築、APIバックエンド向けにJSONやMessagePack出力を実装
- アリーナアロケータの活用 により、文字列のメモリ管理が容易に
- Zigのcomptime機能 で高レベルなインターフェースと高パフォーマンスを両立
- htmxやDatastar により、JavaScript/TypeScriptを使わずにSPA構築が可能
- テンプレートエンジンには以下の要件 を設定
- 型安全性:全入力がコンパイル時に型チェック
- 高速性:アロケーションなし、中間状態なし、std.Io.Writerへ直接出力
- セキュアなデフォルト:XSS対策として全入力をデフォルトでエスケープ
- HTMLライクな記述感:Zig独自DSLを強要しない
ZiexやTemplから着想を得たztの誕生
- Ziex(Zig向けJSXライクテンプレート) の存在に驚愕
- GoのTempl を参考に、Zig向けにアダプトした zt を開発
- テンプレートはzig build時にパース・トランスパイル され、アプリコードから直接import可能
- テンプレートとアプリの相互import が可能で、パラメータは完全に型安全
- 生成コードはstd.Io.Writerへの出力のみ、バッファやソケットへの柔軟な書き込みが可能
ztテンプレートのサンプルと特徴
- テンプレート例 (Userモデルを利用したLayoutとHomePage)
- Zig構文とHTML記法を融合
- @childrenによるレイアウトの継承実現
- Zigコードからの呼び出し例
- 型安全な引数渡し
- 出力先の柔軟な選択(バッファ、stdoutなど)
- Dustyとの連携 でHTMLページのレンダリングも容易
セキュリティと型安全性の徹底
- 全動的値はデフォルトでHTMLエスケープ
- テキスト・属性ともに自動処理
- hrefやsrc属性は危険なスキームをチェック
- 生HTML出力は{!value}で明示的に指定
- 全要素の閉じタグ必須 で壊れたマークアップを防止
- テンプレートエラーはZigのコンパイルエラー として発見可能
- フィールド名のtypoや型不一致も即時検出
コンポーネント化と制御フローの柔軟性
- 再利用可能なコンポーネント や @childrenによるレイアウト継承 が可能
- if/for/switch等の制御フロー はZigそのままの構文で記述
- すべての処理はstd.Io.Writerへの逐次書き出し、アロケーション不要
現状の課題と今後の展望
- 制御フロー構文の曖昧さ (if, for, switchの行頭記述)については改善検討中
- RazorやTwirlに倣い@if, @for, @switchの導入を検討
- プロジェクトはまだ未成熟、フィードバックやバグ報告を歓迎
- GitHub issueやZig Discordでの連絡を推奨
まとめ
- Zigにおける型安全・高速・セキュアなテンプレートエンジンzt の紹介
- Web開発の新しい可能性 として、低レベル言語でも快適なテンプレート記述体験を実現