[インデックス 14884] ファイルの概要
このコミットは、Go言語の標準ライブラリ html/template
パッケージにおけるドキュメントの記述を修正し、text/template
パッケージへの参照をより明確にすることを目的としています。これにより、html/template
が text/template
を基盤としていること、および両者の関係性について、ユーザーの誤解を防ぎ、理解を深めることが期待されます。
コミット
- コミットハッシュ:
1590be9e6f18a06734f84365589d3ab10ef79732
- 作者: Francesc Campoy campoy@golang.org
- コミット日時: Mon Jan 14 12:11:22 2013 +0000
- コミットメッセージ:
html/template: Clarifying references to "text/template" in the documentation. Fixes #4634. R=adg, kevlar CC=golang-dev https://golang.org/cl/7066053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/1590be9e6f18a06734f84365589d3ab10ef79732
元コミット内容
html/template: Clarifying references to "text/template" in the documentation.
Fixes #4634.
R=adg, kevlar
CC=golang-dev
https://golang.org/cl/7066053
変更の背景
この変更は、Go言語のIssue #4634 に対応するものです。Issue #4634 は、html/template
パッケージのドキュメントにおいて、text/template
パッケージとの関係性が不明瞭であるという問題提起でした。具体的には、html/template
が text/template
を内部的に利用しているにもかかわらず、その点がドキュメントで十分に説明されておらず、ユーザーが混乱する可能性がありました。
html/template
は、WebアプリケーションなどでHTMLコンテンツを安全に生成するために設計されたテンプレートエンジンです。クロスサイトスクリプティング (XSS) などのセキュリティ脆弱性を防ぐために、自動エスケープ機能を提供します。一方、text/template
は、任意のテキスト形式の出力を生成するための汎用的なテンプレートエンジンです。html/template
は text/template
の機能を拡張し、HTML特有のセキュリティ要件に対応しています。
このコミットは、ドキュメント内の曖昧な表現を修正し、html/template
が text/template
の「特殊化された」バージョンであること、および FuncMap
や Must
といった共通の概念が text/template
に由来することを明確にすることで、ユーザーの理解を促進し、誤用を防ぐことを目的としています。
前提知識の解説
Go言語のテンプレートパッケージ (text/template
と html/template
)
Go言語には、テキストベースのテンプレートを扱うための2つの主要なパッケージがあります。
-
text/template
:- これはGo言語の標準ライブラリに含まれる汎用的なテンプレートエンジンです。
- 任意のテキスト形式の出力を生成するために使用されます。例えば、設定ファイル、コード生成、メールの本文など、HTML以外の様々なテキスト形式に対応できます。
- テンプレート構文は、
{{.FieldName}}
のようなアクション(データへのアクセス、関数呼び出し、制御構造など)と、それ以外のリテラルテキストで構成されます。 - セキュリティに関する特別な考慮事項はありません。出力されるテキストは、テンプレートに与えられたデータがそのまま挿入されます。
-
html/template
:text/template
を基盤として構築されており、HTMLコンテンツを安全に生成するために特化しています。- 最も重要な機能は、自動エスケープです。テンプレートに挿入されるデータがHTMLコンテキストで安全でない場合(例: ユーザー入力に
<script>
タグが含まれる場合)、html/template
は自動的にそのデータをエスケープし、XSS攻撃などのセキュリティ脆弱性を防ぎます。 - 例えば、
{{.UserInput}}
のようにユーザー入力を表示する場合、html/template
は自動的に<script>
のように変換して出力します。 - これにより、開発者はセキュリティを意識することなく、動的なHTMLコンテンツを生成できます。
text/template
と同じテンプレート構文を使用しますが、HTMLのコンテキストを理解し、適切なエスケープ処理を行います。
FuncMap
と Must
関数
-
FuncMap
:- テンプレート内で呼び出すことができるカスタム関数を登録するためのマップです。キーは関数名、値は関数の実体(
interface{}
型)です。 text/template
とhtml/template
の両方に存在し、同じ概念を共有しています。- これにより、テンプレート内で複雑なロジックを実行したり、データを整形したりすることが可能になります。
- テンプレート内で呼び出すことができるカスタム関数を登録するためのマップです。キーは関数名、値は関数の実体(
-
Must
関数:- Go言語の慣用的なエラーハンドリングパターンの一つです。
(*Template, error)
のような戻り値を持つ関数(例:template.New
,template.Parse
) の結果をラップするために使用されます。- もしエラー(
err
がnil
でない)が発生した場合、Must
はpanic
を発生させます。 - これは通常、プログラムの初期化段階で、テンプレートのパースエラーなど、回復不可能なエラーが発生した場合に利用されます。これにより、エラーチェックのコードを簡潔に保ちつつ、問題が発生した場合には早期にプログラムを終了させることができます。
技術的詳細
このコミットは、src/pkg/html/template/template.go
ファイル内のコメントとドキュメント文字列を修正することで、html/template
パッケージが text/template
パッケージにどのように関連しているかを明確にしています。
具体的な変更点は以下の3箇所です。
-
Template
構造体の説明の明確化:- 変更前:
Template is a specialized template.Template that produces a safe HTML document fragment.
- 変更後:
Template is a specialized Template from "text/template" that produces a safe HTML document fragment.
- 変更前は単に
template.Template
と記述されていましたが、Go言語のパッケージ名と型名を区別するために、"text/template"
パッケージからのTemplate
型であることを明示しています。これにより、html/template.Template
がtext/template.Template
の拡張であることを明確に示しています。
- 変更前:
-
FuncMap
型の説明の明確化:- 変更前:
FuncMap has the same base type as template.FuncMap, copied here so clients need not import "text/template".
- 変更後:
FuncMap has the same base type as FuncMap in "text/template", copied here so clients need not import "text/template".
- ここでも同様に、
template.FuncMap
がtext/template
パッケージのFuncMap
であることを明示しています。html/template
のFuncMap
は、text/template
のFuncMap
と同じ基底型を持つことを強調し、ユーザーがtext/template
をインポートせずにhtml/template
のFuncMap
を利用できる理由を説明しています。
- 変更前:
-
Must
関数の説明の明確化と使用例の追加:- 変更前:
Must panics if err is non-nil in the same way as template.Must.
- 変更後:
Must is a helper that wraps a call to a function returning (*Template, error) and panics if the error is non-nil. It is intended for use in variable initializations such as var t = template.Must(template.New("name").Parse("html"))
- 変更前は
template.Must
との類似性のみを述べていましたが、変更後はMust
関数の具体的な役割((*Template, error)
を返す関数をラップし、エラー時にパニックするヘルパー)と、変数初期化における典型的な使用例(var t = template.Must(template.New("name").Parse("html"))
)が追加されています。これにより、Must
関数の目的と使い方がより明確になりました。
- 変更前:
これらの変更は、コードの動作には影響を与えませんが、ドキュメントの正確性と分かりやすさを大幅に向上させ、特にGoテンプレートパッケージに不慣れな開発者にとっての学習曲線が緩和されることが期待されます。
コアとなるコードの変更箇所
--- a/src/pkg/html/template/template.go
+++ b/src/pkg/html/template/template.go
@@ -14,8 +14,8 @@ import (
"text/template/parse"
)
-// Template is a specialized template.Template that produces a safe HTML
-// document fragment.
+// Template is a specialized Template from "text/template" that produces a safe
+// HTML document fragment.
type Template struct {
escaped bool
// We could embed the text/template field, but it's safer not to because
@@ -238,7 +238,8 @@ func (t *Template) Name() string {
// return values of which the second has type error. In that case, if the
// second (error) argument evaluates to non-nil during execution, execution
// terminates and Execute returns that error. FuncMap has the same base type
-// as template.FuncMap, copied here so clients need not import "text/template".
+// as FuncMap in "text/template", copied here so clients need not import
+// "text/template".
type FuncMap map[string]interface{}
// Funcs adds the elements of the argument map to the template's function map.
@@ -268,7 +269,10 @@ func (t *Template) Lookup(name string) *Template {
return t.set[name]
}
-// Must panics if err is non-nil in the same way as template.Must.
+// Must is a helper that wraps a call to a function returning (*Template, error)
+// and panics if the error is non-nil. It is intended for use in variable initializations
+// such as
+// var t = template.Must(template.New("name").Parse("html"))
func Must(t *Template, err error) *Template {
if err != nil {
panic(err)
コアとなるコードの解説
上記の差分は、src/pkg/html/template/template.go
ファイル内の3つの主要なドキュメントコメントの変更を示しています。
-
Template
構造体のコメント修正:- // Template is a specialized template.Template that produces a safe HTML
+ // Template is a specialized Template from "text/template" that produces a safe
+ // HTML document fragment.
template.Template
という曖昧な記述を、"text/template"
パッケージからのTemplate
型であると明示することで、html/template
がtext/template
の機能を拡張したものであることを明確にしています。
-
FuncMap
型のコメント修正:- // as template.FuncMap, copied here so clients need not import "text/template".
+ // as FuncMap in "text/template", copied here so clients need not import
+ // "text/template".
template.FuncMap
をFuncMap in "text/template"
と具体的に記述することで、html/template
のFuncMap
がtext/template
のFuncMap
と同じ基底型を持つことを強調し、なぜtext/template
をインポートせずに利用できるのかを説明しています。
-
Must
関数のコメント修正と使用例の追加:- // Must panics if err is non-nil in the same way as template.Must.
+ // Must is a helper that wraps a call to a function returning (*Template, error)
+ // and panics if the error is non-nil. It is intended for use in variable initializations
+ // such as
+ // var t = template.Must(template.New("name").Parse("html"))
Must
関数の役割をより詳細に説明し、具体的なコード例を追加することで、その利用方法と目的を明確にしています。これにより、開発者がMust
関数をどのように使うべきか、またどのような状況で使うべきかを一目で理解できるようになります。
これらの変更はすべてドキュメントの改善であり、Go言語のコードベースにおけるドキュメントの品質向上と、ユーザーエクスペリエンスの向上に貢献しています。
関連リンク
- Go Issue #4634: https://github.com/golang/go/issues/4634
- Go CL 7066053: https://golang.org/cl/7066053
参考にした情報源リンク
- Go言語の公式ドキュメント:
text/template
パッケージ: https://pkg.go.dev/text/templatehtml/template
パッケージ: https://pkg.go.dev/html/template
- Go言語のIssueトラッカー (GitHub): https://github.com/golang/go/issues
- Go Code Review (Gerrit): https://go.googlesource.com/go/+/refs/heads/master (CLリンクの元となるシステム)
- Go言語におけるエラーハンドリングの慣用句 (例:
Must
関数): 一般的なGo言語のプログラミングプラクティスに関する情報源。