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

[インデックス 15421] ファイルの概要

このコミットは、doc/articles/wiki/index.html ファイルに対する変更です。具体的には、Go言語のWikiコードラボにおけるテンプレートのパースに関する記述が修正されています。

コミット

  • コミットハッシュ: 052d845c5c79d716148fe88265bde33b3be9ebd3
  • Author: Andrew Gerrand adg@golang.org
  • Date: Tue Feb 26 08:31:47 2013 +1100
  • 変更ファイル: doc/articles/wiki/index.html (1ファイル)
  • 変更行数: 5行の追加、4行の削除

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/052d845c5c79d716148fe88265bde33b3be9ebd3

元コミット内容

doc: fix wiki codelab description of template parsing

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/7372048

変更の背景

このコミットは、Go言語の公式Wikiにあるコードラボ(おそらく「Go言語でWebアプリケーションを作成する」のようなチュートリアル)において、HTMLテンプレートのパース方法に関する説明が不正確であったため、それを修正することを目的としています。

元の記述では、テンプレートファイルをパースするために、テンプレート名の配列をforループとrangeステートメントでイテレートし、個別にパースするような誤解を招く表現が使われていました。しかし、Goのhtml/templateパッケージ(またはtext/templateパッケージ)のParseFiles関数は、複数のファイルパスを引数として直接受け取ることができ、一度にそれら全てをパースしてテンプレートセットを構築します。

この修正は、読者がGoのテンプレートシステムを正しく理解し、より効率的かつ慣用的な方法でテンプレートを扱うことができるようにするための、ドキュメントの正確性向上を意図しています。特に、ParseFiles関数の正しい使用法を明確にすることで、不必要なループ処理や複雑なコードを避けるよう促しています。

前提知識の解説

このコミットの変更内容を理解するためには、以下のGo言語の概念とパッケージに関する知識が必要です。

  1. Go言語のHTMLテンプレート (html/template): Go言語には、HTMLコンテンツを生成するための組み込みテンプレートエンジンが提供されています。これは主にhtml/templateパッケージ(または汎用的なtext/templateパッケージ)によって実現されます。これらのパッケージは、プレースホルダーや制御構造(条件分岐、ループなど)を含むテキストファイル(テンプレート)を定義し、プログラムからデータを注入して最終的な出力を生成する機能を提供します。 セキュリティ上の理由から、WebアプリケーションでHTMLを生成する際には、クロスサイトスクリプティング(XSS)攻撃を防ぐためにhtml/templateパッケージを使用することが強く推奨されます。このパッケージは、自動的にエスケープ処理を行い、安全なHTML出力を保証します。

  2. template.ParseFiles 関数: html/templateパッケージ(およびtext/templateパッケージ)には、ParseFilesという関数があります。この関数は、可変長引数として1つ以上のファイルパス(文字列)を受け取ります。指定されたすべてのファイルを読み込み、それらをパースして単一の*template.Templateオブジェクトにまとめます。 ParseFilesの重要な特徴は、各テンプレートファイルがそのベースファイル名(例: index.htmlであればindex)で名前付けされたテンプレートとして、返される*template.Templateオブジェクトの内部に登録される点です。これにより、後でExecuteTemplate関数などを使って、名前で特定のテンプレートを呼び出すことができます。 例えば、template.ParseFiles("header.html", "body.html", "footer.html")と呼び出すと、header.htmlbody.htmlfooter.htmlという3つのファイルがパースされ、それぞれheaderbodyfooterという名前でテンプレートオブジェクト内に登録されます。

  3. for ループと range ステートメント: Go言語のforループは、他の多くの言語のループ構造を統合したものです。rangeキーワードと組み合わせることで、配列、スライス、文字列、マップ、チャネルなどのコレクションを簡単にイテレートできます。 例えば、for _, name := range namesのように記述すると、namesスライス(または配列)の各要素を順に処理できます。 元のドキュメントの記述は、このforループとrangeステートメントを使ってテンプレート名をイテレートし、個別にパースするような印象を与えていましたが、これはParseFilesの設計意図とは異なります。

技術的詳細

このコミットの技術的な核心は、Goのhtml/templateパッケージにおけるParseFiles関数の正しいセマンティクスをドキュメントで明確にすることにあります。

変更前: 元のドキュメントでは、以下のような記述がありました。

<p>
A <code>for</code> loop is used with a <code>range</code> statement
to iterate over an array constant containing the names of the templates we want
parsed. If we were to add more templates to our program, we would add their
names to that array.
</p>

この記述は、テンプレートファイルをパースする際に、ファイル名のリストを配列として持ち、その配列をforループとrangeで回しながら、各ファイルを個別にパースするような印象を与えます。これは、template.ParseFilesの実際の使い方とは異なります。ParseFilesは、複数のファイルパスを一度に引数として受け取るように設計されており、開発者が手動でループを回して個別にパースする必要はありません。

変更後: 修正後のドキュメントでは、以下のように変更されました。

<p>
The <code>ParseFiles</code> function takes any number of string arguments that
identify our template files, and parses those files into templates that are
named after the base file name. If we were to add more templates to our
program, we would add their names to the <code>ParseFiles</code> call's
arguments.
</p>

この新しい記述は、ParseFiles関数の正しい使用法を正確に説明しています。

  1. 可変長引数: ParseFilesが「任意の数の文字列引数」を取ることを明確にしています。これにより、開発者は必要なテンプレートファイルのパスを直接引数として渡すだけでよいことがわかります。
  2. ベースファイル名による命名: パースされたテンプレートが「ベースファイル名にちなんで名付けられる」ことを説明しています。これは、ParseFilesindex.htmlをパースした場合、そのテンプレートがindexという名前でアクセス可能になるという重要な動作を指します。
  3. 追加時の対応: 新しいテンプレートを追加する際には、「ParseFiles呼び出しの引数にその名前を追加する」だけでよいことを示しており、配列を更新してループを回すという誤ったアプローチを否定しています。

この修正により、Goのテンプレートシステムを学習する開発者は、より効率的で慣用的なParseFiles関数の使い方を最初から学ぶことができます。これは、コードの簡潔さ、可読性、そしてGoの設計思想(「少ないコードでより多くを」)に合致するものです。

コアとなるコードの変更箇所

--- a/doc/articles/wiki/index.html
+++ b/doc/articles/wiki/index.html
@@ -544,10 +544,11 @@ can't be loaded the only sensible thing to do is exit the program.
 </p>
 
 <p>
-A <code>for</code> loop is used with a <code>range</code> statement
-to iterate over an array constant containing the names of the templates we want
-parsed. If we were to add more templates to our program, we would add their
-names to that array.
+The <code>ParseFiles</code> function takes any number of string arguments that
+identify our template files, and parses those files into templates that are
+named after the base file name. If we were to add more templates to our
+program, we would add their names to the <code>ParseFiles</code> call's
+arguments.
 </p>
 
 <p>

コアとなるコードの解説

変更されたのは、doc/articles/wiki/index.html ファイル内のHTMLの<p>タグで囲まれた説明文です。

  • 削除された行:

    A <code>for</code> loop is used with a <code>range</code> statement
    to iterate over an array constant containing the names of the templates we want
    parsed. If we were to add more templates to our program, we would add their
    names to that array.
    

    この部分は、テンプレートのパースにforループとrangeステートメントを使用し、テンプレート名の配列をイテレートするという、template.ParseFilesの実際の動作とは異なる説明をしていました。特に、「テンプレート名の配列に名前を追加する」という記述は、ParseFilesの可変長引数としての性質を無視していました。

  • 追加された行:

    The <code>ParseFiles</code> function takes any number of string arguments that
    identify our template files, and parses those files into templates that are
    named after the base file name. If we were to add more templates to our
    program, we would add their names to the <code>ParseFiles</code> call's
    arguments.
    

    この新しい部分は、template.ParseFiles関数の正しい使い方を明確に説明しています。

    • ParseFilesが「任意の数の文字列引数」を受け取ることを強調し、個別のファイルパスを直接渡せることを示しています。
    • パースされたテンプレートが「ベースファイル名にちなんで名付けられる」という重要な動作を説明しています。例えば、foo.htmlというファイルはfooという名前のテンプレートとして登録されます。
    • 新しいテンプレートを追加する際には、「ParseFiles呼び出しの引数にその名前を追加する」だけでよいことを示し、配列を介した間接的な方法ではなく、直接的な方法を推奨しています。

この変更により、Goのテンプレートに関するドキュメントの正確性が向上し、読者がより効率的でGoらしいテンプレートの扱い方を学ぶことができるようになりました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (html/template および text/template パッケージ)
  • Go言語のWikiコードラボに関する一般的な情報 (Web検索による)
  • Gitのコミットログと差分表示の解釈