[インデックス 12028] ファイルの概要
このコミットは、Go言語の標準ライブラリである html/template
パッケージ内のドキュメントにおいて、非推奨となった template.Set
の参照を、現在の *template.Template
の使用方法に置き換えるものです。これにより、ドキュメントが最新のAPI利用方法に準拠し、ユーザーが誤った情報に基づいてコードを記述するのを防ぎます。
コミット
commit 701fb580bd1d199027126b00f1a2aee2f65afd97
Author: Rob Pike <r@golang.org>
Date: Sat Feb 18 16:02:51 2012 +1100
html/template: replace obsolete reference to template.Set
Fixes #3053.
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5656094
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/701fb580bd1d199027126b00f1a2aee2f65afd97
元コミット内容
html/template: replace obsolete reference to template.Set
Fixes #3053.
R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5656094
変更の背景
Go言語の html/template
パッケージは、ウェブアプリケーションでHTMLコンテンツを安全に生成するために設計されています。このパッケージは、クロスサイトスクリプティング(XSS)などの脆弱性から保護するための自動エスケープ機能を提供します。
初期のGo言語のバージョンでは、テンプレートの集合を管理するために template.Set
という型が存在していました。しかし、Go 1.0のリリース前後で、この Set
型は非推奨となり、その機能は *template.Template
型に直接統合されました。これにより、テンプレートの管理と利用がよりシンプルかつ直感的になりました。
このコミットは、html/template
パッケージのドキュメントファイル src/pkg/html/template/doc.go
内に残っていた古い template.Set
の使用例を、新しい template.New("name").Parse(...)
および *template.Template
インスタンスの直接利用に更新することを目的としています。これは、ドキュメントが実際のAPIの変更に追従し、ユーザーが最新かつ正しい方法で html/template
を利用できるようにするために必要でした。また、この変更はIssue #3053を修正するものです。
前提知識の解説
Go言語の text/template
および html/template
パッケージ
Go言語には、テキストベースの出力やHTML出力を生成するためのテンプレートエンジンが組み込まれています。
text/template
: 任意のテキスト形式の出力を生成するための汎用テンプレートパッケージです。html/template
:text/template
をベースにしていますが、HTMLコンテンツを生成する際に特にセキュリティを強化しています。具体的には、出力されるデータがHTMLコンテキストに応じて自動的にエスケープされ、XSS攻撃などのインジェクション脆弱性を防ぐように設計されています。
これらのパッケージでは、テンプレートは文字列として定義され、Parse
メソッドなどを使って解析されます。解析されたテンプレートは、データ構造(通常はGoの構造体やマップ)を引数として Execute
メソッドに渡すことで、最終的な出力が生成されます。
template.Set
の廃止と *template.Template
への統合
Go言語の初期の設計では、複数のテンプレートをグループ化して管理するために template.Set
という概念が存在しました。これは、例えば複数のHTMLファイルから構成されるウェブページ全体を一つの単位として扱う場合に便利でした。
しかし、Go 1.0の安定化プロセスにおいて、template.Set
の機能は *template.Template
型自体に統合されることになりました。これにより、template.New
で作成された *template.Template
インスタンスが、複数の名前付きテンプレートを内部的に保持できるようになりました。例えば、template.ParseFiles
や template.ParseGlob
を使用すると、返される *template.Template
オブジェクトは、指定されたファイル内のすべてのテンプレート(名前付きテンプレートを含む)を管理します。また、tmpl.Parse
を繰り返し呼び出すことで、既存の *template.Template
インスタンスに新しいテンプレートを追加することも可能です。
この変更の意図は、APIのシンプル化と一貫性の向上にありました。Set
という独立した概念をなくすことで、ユーザーは *template.Template
オブジェクト一つでテンプレートの解析、管理、実行のすべてを行えるようになりました。
技術的詳細
このコミットの技術的な核心は、html/template
パッケージのドキュメント src/pkg/html/template/doc.go
内のコード例を、非推奨となった template.Set
の使用から、現在の *template.Template
の標準的な使用方法に更新することです。
具体的には、以下の2つの主要な変更が行われています。
-
テンプレートの初期化方法の変更:
- 変更前:
set, err := new(template.Set).Parse(...)
これは、template.Set
の新しいインスタンスを作成し、そのParse
メソッドを呼び出してテンプレートを解析していました。 - 変更後:
tmpl, err := template.New("name").Parse(...)
これは、template.New
関数を使って新しい*template.Template
インスタンスを作成し、そのParse
メソッドを呼び出してテンプレートを解析しています。"name"
はテンプレートの名前を指定します。これにより、複数のテンプレートを同じ*template.Template
インスタンス内で管理できるようになります。
- 変更前:
-
テンプレートの実行方法の変更:
- 変更前:
err = set.Execute(out, "Foo", data)
template.Set
インスタンスのExecute
メソッドを呼び出してテンプレートを実行していました。 - 変更後:
err = tmpl.Execute(out, "Foo", data)
*template.Template
インスタンスのExecute
メソッドを呼び出してテンプレートを実行しています。
- 変更前:
これらの変更は、Go言語のテンプレートAPIが進化し、template.Set
が *template.Template
に統合されたことを反映しています。ドキュメントのコード例を更新することで、ユーザーは最新かつ推奨されるAPIの利用方法を学ぶことができます。
コアとなるコードの変更箇所
src/pkg/html/template/doc.go
ファイルの以下の部分が変更されました。
--- a/src/pkg/html/template/doc.go
+++ b/src/pkg/html/template/doc.go
@@ -17,11 +17,11 @@ Introduction
This package wraps package text/template so you can share its template API
to parse and execute HTML templates safely.
- set, err := new(template.Set).Parse(...)\n
+ tmpl, err := template.New("name").Parse(...)\n
// Error checking elided\n
- err = set.Execute(out, "Foo", data)\n
+ err = tmpl.Execute(out, "Foo", data)\n
\n-If successful, set will now be injection-safe. Otherwise, err is an error\n
+If successful, tmpl will now be injection-safe. Otherwise, err is an error\n
defined in the docs for ErrorCode.\n
\n HTML templates treat data values as plain text which should be encoded so they\n
コアとなるコードの解説
変更された doc.go
は、html/template
パッケージのドキュメントの一部です。このファイルには、パッケージの目的、使い方、およびコード例が記述されています。
変更前は、テンプレートの初期化と実行の例として template.Set
を使用したコードが示されていました。
set, err := new(template.Set).Parse(...)
// Error checking elided
err = set.Execute(out, "Foo", data)
このコードは、template.Set
の新しいインスタンスを作成し、その Parse
メソッドでテンプレートを解析し、Execute
メソッドで実行するという流れを示していました。
変更後は、この例が *template.Template
を直接使用するように更新されました。
tmpl, err := template.New("name").Parse(...)
// Error checking elided
err = tmpl.Execute(out, "Foo", data)
この新しいコード例では、template.New("name")
を使って名前付きの新しい *template.Template
インスタンス tmpl
を作成し、その Parse
メソッドでテンプレートを解析しています。そして、tmpl.Execute
を使ってテンプレートを実行しています。
また、それに伴い、ドキュメント内の説明文も set
から tmpl
へと変数名が変更されています。
-If successful, set will now be injection-safe. Otherwise, err is an error
+If successful, tmpl will now be injection-safe. Otherwise, err is an error
この変更により、html/template
パッケージのドキュメントは、現在のGo言語のテンプレートAPIのベストプラクティスを正確に反映するようになりました。これは、ユーザーが最新のGo言語の機能と推奨されるパターンを理解し、安全で効率的なHTMLテンプレートを記述するために非常に重要です。
関連リンク
- Go Change List 5656094: https://golang.org/cl/5656094
- Go Issue 3053: このコミットが修正するIssue #3053は、Goの公式Issueトラッカーで確認できますが、直接的なリンクはコミットメッセージには含まれていません。しかし、コミットメッセージの文脈から、
template.Set
の非推奨化とドキュメントの更新に関連するものであると推測されます。
参考にした情報源リンク
- Go言語
html/template
パッケージのドキュメント: https://pkg.go.dev/html/template - Go言語
text/template
パッケージのドキュメント: https://pkg.go.dev/text/template - Stack Overflow: "html/template.Set is obsolete"に関する議論 (Web検索結果より)
- https://stackoverflow.com/questions/tagged/go-html-template (具体的な質問は検索結果から特定できませんでしたが、関連する情報源として)
- Go言語のリリースノートや変更履歴(Go 1.0周辺の変更点)
- Go 1 Release Notes: https://go.dev/doc/go1 (直接的な言及は少ないが、APIの安定化に関する情報が含まれる)