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

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

このコミットは、Go言語のドキュメンテーションツールであるgodocのWebインターフェースにおけるタブタイトルの表示方法を改善するものです。特に、ブラウザのタブに表示されるタイトルが長すぎて情報が分かりにくくなる問題を解決するために、より短く、かつ関連性の高い情報が先頭に来るように変更されています。

コミット

commit cfd8b84f072e1799456ad3dc350bc1a486a0e280
Author: Robert Griesemer <gri@golang.org>
Date:   Wed Mar 21 11:29:30 2012 -0700

    godoc: use shorter titles for tabs

    In a browser with many open tabs, the tab titles become short
    and uninformative because they all start with the same prefix
    ("Package ", "Directory ", etc.).

    Permit use of shorter tab titles that start with the relevant
    information first.

    Fixes #3365.

    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5865056

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

https://github.com/golang/go/commit/cfd8b84f072e1799456ad3dc350bc1a486a0e280

元コミット内容

このコミットの目的は、godocが生成するHTMLページのブラウザタブタイトルを短く、より情報量の多いものにすることです。これまでのタイトルは「Package foo」や「Directory bar」のように、共通のプレフィックスで始まるため、多数のタブを開いた際に区別がつきにくくなっていました。この変更により、関連情報(パッケージ名、ディレクトリ名など)がタイトルの先頭に来るように調整され、ブラウザのタブバーでの視認性が向上します。

変更の背景

当時のgodocは、Go言語の公式ドキュメンテーションツールとして、ソースコードから自動的にドキュメントを生成し、Webブラウザで閲覧可能な形式で提供していました。しかし、生成されるHTMLページの<title>タグの内容が「Package <パッケージ名> - The Go Programming Language」や「Directory <ディレクトリ名> - The Go Programming Language」といった形式になっており、特に「Package 」や「Directory 」といった共通のプレフィックスが問題でした。

ユーザーが複数のgodocページをブラウザで開いた場合、ブラウザのタブにはタイトルの先頭部分しか表示されないことが多く、結果としてすべてのタブが「Package ...」や「Directory ...」のように見えてしまい、どのタブがどのパッケージやディレクトリに対応しているのかを一目で判別することが困難でした。

この問題は、GoのIssueトラッカーで「Issue 3365: godoc: use shorter titles for tabs」として報告されており、このコミットはその問題を解決するために作成されました。ユーザーエクスペリエンスの向上、特に多数のドキュメントページを同時に参照する開発者にとっての利便性向上が主な目的です。

前提知識の解説

  • godoc: Go言語のソースコードからドキュメントを生成し、Webサーバーとして提供するツールです。Goの標準ライブラリやサードパーティのパッケージのドキュメント閲覧に広く利用されます。
  • HTMLの<title>タグ: Webページのタイトルを定義するHTML要素です。このタイトルは通常、Webブラウザのタブやウィンドウのタイトルバーに表示され、ブックマークの名前としても使用されます。検索エンジンの結果にも影響を与える重要な要素です。
  • Goのhtml/templateパッケージ: Go言語でHTMLテンプレートを扱うための標準ライブラリです。データ構造をテンプレートに渡し、動的にHTMLを生成するために使用されます。このコミットでは、テンプレート内で使用される変数の変更(.Titleから.Tabtitleへの変更)が行われています。
  • http.ResponseWriterhttp.Request: Goの標準ライブラリnet/httpパッケージにおけるHTTPハンドラの基本的なインターフェースです。http.ResponseWriterはHTTPレスポンスを書き込むために使用され、http.Requestは受信したHTTPリクエストの情報を保持します。
  • servePage関数: godoc内でHTMLページをクライアントに提供するための共通ヘルパー関数です。この関数は、ページのタイトル、サブタイトル、検索クエリ、そして実際のコンテンツを受け取り、これらをHTMLテンプレートに埋め込んで最終的なHTMLを生成し、レスポンスとして書き出します。このコミットの主要な変更点の一つは、この関数のシグネチャと内部ロジックの変更です。

技術的詳細

このコミットの核心は、godocのWebサーバーがHTMLページを生成する際に、ブラウザのタブに表示されるタイトル(<title>タグの内容)と、ページ本体に表示されるタイトル(<h1>タグなどに相当)を分離し、それぞれに適切な情報を設定できるようにした点にあります。

具体的には、以下の変更が行われました。

  1. servePage関数のシグネチャ変更:

    • 変更前: func servePage(w http.ResponseWriter, title, subtitle, query string, content []byte)
    • 変更後: func servePage(w http.ResponseWriter, tabtitle, title, subtitle, query string, content []byte)
    • 新たにtabtitleという引数が追加されました。これにより、ブラウザのタブに表示されるタイトルを、ページ本体のタイトルとは独立して設定できるようになりました。
  2. godoc.htmlテンプレートの変更:

    • 変更前: {{with .Title}} <title>{{html .}} - The Go Programming Language</title> {{else}} <title>The Go Programming Language</title> {{end}}
    • 変更後: {{with .Tabtitle}} <title>{{html .}} - The Go Programming Language</title> {{else}} <title>The Go Programming Language</title> {{end}}
    • HTMLテンプレート内で、<title>タグの生成に使用される変数が.Titleから.Tabtitleに変更されました。これにより、servePage関数に渡されたtabtitleの値が直接ブラウザのタブタイトルとして使用されるようになります。
  3. servePage関数内のロジック変更:

    • servePage関数内で、tabtitleが空文字列の場合には、titleの値をtabtitleとして使用するフォールバックロジックが追加されました。これにより、既存のservePage呼び出し元がtabtitleを明示的に指定しない場合でも、以前と同様の動作が保証されます。
    • d := struct { ... } の定義に Tabtitle string フィールドが追加され、テンプレートに渡されるデータ構造に Tabtitle が含まれるようになりました。
  4. 各ハンドラ関数からのservePage呼び出しの変更:

    • src/cmd/godoc/codewalk.gosrc/cmd/godoc/godoc.gosrc/cmd/godoc/main.go内のservePageを呼び出している箇所がすべて更新され、新しいtabtitle引数が適切に渡されるようになりました。
    • 特にsrc/cmd/godoc/godoc.goServeHTTPメソッドでは、パッケージ、コマンド、ディレクトリなどの種類に応じて、tabtitletitleを個別に生成するロジックが導入されました。例えば、パッケージページではtabtitleにパッケージ名のみを、titleには「Package <パッケージ名>」を設定するといった具合です。
    • トップレベルのパッケージ/コマンドディレクトリ(/src/pkg/src/cmd)に対しては、tabtitleが「Packages」や「Commands」といったより一般的な名前に設定される特殊なケースも追加されました。

これらの変更により、godocはブラウザのタブに表示されるタイトルをより簡潔かつ情報量の多いものにすることが可能になり、ユーザーが多数のタブを開いている状況でも、目的のページを素早く見つけられるようになりました。

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

このコミットにおける主要なコード変更は以下のファイルに集中しています。

  • lib/godoc/godoc.html: HTMLテンプレートファイル。<title>タグの生成に使用されるテンプレート変数が.Titleから.Tabtitleに変更されました。
  • src/cmd/godoc/codewalk.go: コードウォーク機能に関連するハンドラ。servePage関数の呼び出しが新しいシグネチャに合わせて更新されました。
  • src/cmd/godoc/godoc.go: godocの主要なHTTPハンドラとページ生成ロジックが含まれるファイル。servePage関数のシグネチャが変更され、内部でtabtitletitleを個別に設定するロジックが追加されました。また、各ページタイプ(パッケージ、コマンド、ディレクトリなど)に応じたtabtitleの生成ロジックが詳細化されました。
  • src/cmd/godoc/main.go: godocアプリケーションのエントリポイント。エラーページ表示のためのserveError関数におけるservePageの呼び出しが更新されました。

コアとなるコードの解説

lib/godoc/godoc.html

-{{with .Title}}
+{{with .Tabtitle}}
   <title>{{html .}} - The Go Programming Language</title>

この変更は、HTMLテンプレートがブラウザのタブタイトルを生成する際に、Titleというデータフィールドではなく、新しく導入されたTabtitleというデータフィールドを使用するように指示しています。これにより、ページ本体のタイトルとは異なる、タブに特化した短いタイトルを設定できるようになります。

src/cmd/godoc/godoc.go

// ----------------------------------------------------------------------------
// Generic HTML wrapper

-func servePage(w http.ResponseWriter, title, subtitle, query string, content []byte) {
+func servePage(w http.ResponseWriter, tabtitle, title, subtitle, query string, content []byte) {
+	if tabtitle == "" {
+		tabtitle = title
+	}
 	d := struct {
+		Tabtitle  string
 		Title     string
 		Subtitle  string
 		SearchBox bool
@@ -556,6 +560,7 @@ func servePage(w http.ResponseWriter, title, subtitle, query string, content []b
 		Menu      []byte
 		Content   []byte
 	}{
+		tabtitle,
 		title,
 		subtitle,
 		*indexEnabled,

これはservePage関数の定義そのものの変更です。

  1. 新しい引数tabtitleが追加されました。
  2. tabtitleが空文字列の場合にtitleをフォールバックとして使用するロジックが追加され、既存の呼び出し元との互換性を保ちつつ、新しい機能を提供しています。
  3. テンプレートに渡すデータ構造dTabtitleフィールドが追加され、その値として新しいtabtitle引数が設定されています。
 	var tabtitle, title, subtitle string
 	switch {
 	case info.PAst != nil:
-		title = "Package " + info.PAst.Name.Name
+		tabtitle = info.PAst.Name.Name
+		title = "Package " + tabtitle
 	case info.PDoc != nil:
-		switch {
-		case info.IsPkg:
-			title = "Package " + info.PDoc.Name
-		case info.PDoc.Name == fakePkgName:
+		if info.PDoc.Name == fakePkgName {
 			// assume that the directory name is the command name
-			_, pkgname := pathpkg.Split(relpath)
-			title = "Command " + pkgname
-		default:
-			title = "Command " + info.PDoc.Name
+			_, tabtitle = pathpkg.Split(relpath)
+		} else {
+			tabtitle = info.PDoc.Name
+		}
+		if info.IsPkg {
+			title = "Package " + tabtitle
+		} else {
+			title = "Command " + tabtitle
 		}
 	default:
-		title = "Directory " + info.Dirname
+		tabtitle = info.Dirname
+		title = "Directory " + tabtitle
 		if *showTimestamps {
 			subtitle = "Last update: " + info.DirTime.String()
 		}
 	}

+	// special cases for top-level package/command directories
+	switch tabtitle {
+	case "/src/pkg":
+		tabtitle = "Packages"
+	case "/src/cmd":
+		tabtitle = "Commands"
+	}
+
 	contents := applyTemplate(packageHTML, "packageHTML", info)
-	servePage(w, title, subtitle, "", contents)
+	servePage(w, tabtitle, title, subtitle, "", contents)

この部分は、godocのメインHTTPハンドラであるServeHTTP関数内のロジックです。

  • tabtitletitleという2つの変数が導入され、それぞれに異なる値が設定されるようになりました。
  • info.PAst (パッケージの抽象構文木) や info.PDoc (パッケージドキュメント) の情報に基づいて、パッケージ名、コマンド名、ディレクトリ名などが適切にtabtitletitleに割り当てられます。
  • 特に、tabtitleにはパッケージ名やコマンド名のみが設定され、titleには「Package <パッケージ名>」のようなより詳細な情報が設定されることで、タブとページ本体のタイトルが区別されます。
  • /src/pkg/src/cmdといったトップレベルのディレクトリに対する特殊なケースも追加され、tabtitleが「Packages」や「Commands」といったより一般的な名前に設定されることで、これらのページもより分かりやすいタブタイトルを持つようになります。
  • 最終的に、servePage関数が新しいtabtitle引数とともに呼び出されています。

これらの変更により、godocはブラウザのタブに表示されるタイトルをより簡潔かつ情報量の多いものにすることが可能になり、ユーザーが多数のタブを開いている状況でも、目的のページを素早く見つけられるようになりました。

関連リンク

参考にした情報源リンク