Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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.ParseFilestemplate.ParseGlob を使用すると、返される *template.Template オブジェクトは、指定されたファイル内のすべてのテンプレート(名前付きテンプレートを含む)を管理します。また、tmpl.Parse を繰り返し呼び出すことで、既存の *template.Template インスタンスに新しいテンプレートを追加することも可能です。

この変更の意図は、APIのシンプル化と一貫性の向上にありました。Set という独立した概念をなくすことで、ユーザーは *template.Template オブジェクト一つでテンプレートの解析、管理、実行のすべてを行えるようになりました。

技術的詳細

このコミットの技術的な核心は、html/template パッケージのドキュメント src/pkg/html/template/doc.go 内のコード例を、非推奨となった template.Set の使用から、現在の *template.Template の標準的な使用方法に更新することです。

具体的には、以下の2つの主要な変更が行われています。

  1. テンプレートの初期化方法の変更:

    • 変更前: set, err := new(template.Set).Parse(...) これは、template.Set の新しいインスタンスを作成し、その Parse メソッドを呼び出してテンプレートを解析していました。
    • 変更後: tmpl, err := template.New("name").Parse(...) これは、template.New 関数を使って新しい *template.Template インスタンスを作成し、その Parse メソッドを呼び出してテンプレートを解析しています。"name" はテンプレートの名前を指定します。これにより、複数のテンプレートを同じ *template.Template インスタンス内で管理できるようになります。
  2. テンプレートの実行方法の変更:

    • 変更前: 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 の非推奨化とドキュメントの更新に関連するものであると推測されます。

参考にした情報源リンク