[インデックス 10726] ファイルの概要
このコミットは、Go言語の公式ドキュメントツール兼サーバーであるgodoc
に、OpenSearch Description Document (OSDD) を追加するものです。これにより、godoc
の検索機能をWebブラウザの検索バーやその他のOpenSearch対応アプリケーションに統合できるようになります。ユーザーはブラウザから直接godoc
のドキュメントを検索できるようになり、利便性が向上します。
コミット
- コミットハッシュ:
ecf4a9216edfdcc48327382697fed5d98d7faf46
- Author: Christoph Hack christoph@tux21b.org
- Date: Mon Dec 12 18:01:06 2011 -0500
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ecf4a9216edfdcc48327382697fed5d98d7faf46
元コミット内容
godoc: added an opensearch description document.
R=golang-dev, r, tux21b, rsc
CC=golang-dev
https://golang.org/cl/5479062
変更の背景
godoc
はGo言語のパッケージドキュメントを生成し、Webサーバーとして提供するツールです。以前から検索機能は備わっていましたが、その検索機能はgodoc
のWebインターフェース内でのみ利用可能でした。
この変更の背景には、ユーザーがより手軽にgodoc
のドキュメントを検索できるようにしたいというニーズがありました。OpenSearchは、Webサイトの検索機能を標準的なXML形式で記述し、Webブラウザや他のアプリケーションがその検索機能を利用できるようにする技術です。OpenSearch Description Documentを提供することで、ユーザーはgodoc
のWebサイトを訪問することなく、ブラウザの検索バーから直接Goのドキュメントを検索できるようになります。これにより、開発者のワークフローが効率化され、Goドキュメントへのアクセス性が向上します。
前提知識の解説
godocとは
godoc
は、Go言語のソースコードからドキュメントを抽出し、HTML形式で表示するツールです。Goのコードは、コメントの書き方によって自動的にドキュメントとして認識される仕組みがあり、godoc
はそのコメントを解析して整形されたドキュメントを生成します。また、godoc
は単なるドキュメント生成ツールとしてだけでなく、ローカルでドキュメントサーバーを起動する機能も持っています。これにより、開発者は自分のマシン上でGoの標準ライブラリやサードパーティライブラリのドキュメントを簡単に参照できます。
OpenSearchとは
OpenSearchは、Webサイトの検索機能を記述するためのXMLベースの標準フォーマットです。これにより、Webサイトの検索機能をWebブラウザやデスクトップアプリケーション、その他の検索アグリゲーターなどのクライアントアプリケーションに統合することが可能になります。ユーザーは、OpenSearchに対応したブラウザの検索バーにキーワードを入力するだけで、特定のWebサイトの検索結果を直接取得できるようになります。
OpenSearch Description Document (OSDD) の役割
OpenSearch Description Document (OSDD) は、OpenSearchの核となる部分です。これはXML形式のファイルで、Webサイトの検索機能に関するメタデータ(サイト名、説明、検索クエリの送信方法、検索結果のURLテンプレートなど)を記述します。Webブラウザは、Webページ内に埋め込まれたOSDDへのリンクを検出すると、そのサイトの検索機能をブラウザの検索エンジンリストに追加するオプションをユーザーに提供できます。
OSDDには以下のような主要な要素が含まれます。
<ShortName>
: 検索エンジンの短い名前(ブラウザの検索エンジンリストに表示される名前)。<Description>
: 検索エンジンの詳細な説明。<Url>
: 検索クエリを送信するためのURLテンプレート。{searchTerms}
のようなプレースホルダーを使用して、ユーザーが入力した検索キーワードがどこに挿入されるかを示します。<Image>
: 検索エンジンに関連付けられたアイコンのURL。<InputEncoding>
/<OutputEncoding>
: 入力および出力の文字エンコーディング。
Webブラウザとの連携
多くのモダンなWebブラウザ(Firefox, Chrome, Edgeなど)はOpenSearchをサポートしています。WebページがOSDDへの<link>
タグをHTMLの<head>
セクションに含んでいる場合、ブラウザはそのOSDDを自動的に検出し、ユーザーにそのサイトの検索機能をブラウザの検索エンジンに追加するオプションを提示します。一度追加されると、ユーザーはブラウザの検索バーから直接そのサイトのコンテンツを検索できるようになります。
技術的詳細
このコミットでは、godoc
のWebサーバー機能にOpenSearchのサポートを追加するために、以下の主要な変更が行われています。
-
OpenSearch Description Document (
opensearch.xml
) の追加:lib/godoc/opensearch.xml
という新しいファイルが追加されました。このXMLファイルは、godoc
の検索機能に関するOpenSearchのメタデータを定義しています。ShortName
は「godoc」Description
は「The Go Programming Language」Tags
は「go golang」Url
テンプレートは{{.BaseURL}}/search?q={searchTerms}
となっており、godoc
の検索エンドポイント/search
にクエリパラメータq
として検索キーワードが渡されることを示しています。{{.BaseURL}}
は、godoc
サーバーのベースURLが動的に挿入されることを意味します。Image
は/favicon.ico
が指定されており、godoc
のファビコンが検索エンジンのアイコンとして使用されます。
-
HTMLへのOpenSearchリンクの追加:
lib/godoc/godoc.html
に、OpenSearch Description Documentへの<link>
タグが追加されました。{{if .SearchBox}} <link rel="search" type="application/opensearchdescription+xml" title="godoc" href="/opensearch.xml" /> {{end}}
この
<link>
タグは、godoc
のテンプレートエンジンによってSearchBox
変数がtrue
の場合にのみレンダリングされます。これにより、検索ボックスが表示されるページでのみOpenSearchの機能が提供され、不要な場合にリンクが追加されるのを防ぎます。type="application/opensearchdescription+xml"
は、このリンクがOpenSearch Description Documentであることをブラウザに伝えます。href="/opensearch.xml"
は、OSDDが/opensearch.xml
というパスで提供されることを示します。 -
godoc
サーバーでのOpenSearch Description Documentの提供:src/cmd/godoc/godoc.go
に、OpenSearch Description DocumentをHTTP経由で提供するための新しいハンドラとテンプレート処理ロジックが追加されました。registerPublicHandlers
関数内で、/opensearch.xml
パスに対する新しいHTTPハンドラserveSearchDesc
が登録されました。mux.HandleFunc("/opensearch.xml", serveSearchDesc)
- テンプレート変数を管理する
var
ブロックに、searchDescXML *template.Template
が追加されました。これはopensearch.xml
の内容をパースしたテンプレートを保持します。 readTemplates
関数内で、lib/godoc/opensearch.xml
ファイルが読み込まれ、searchDescXML
テンプレート変数に格納されます。searchDescXML = readTemplate("opensearch.xml")
serveSearchDesc
関数が新しく実装されました。この関数は、/opensearch.xml
へのリクエストを処理します。
この関数は、まずレスポンスのfunc serveSearchDesc(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/opensearchdescription+xml") data := map[string]interface{}{ "BaseURL": fmt.Sprintf("http://%s", r.Host), } if err := searchDescXML.Execute(w, &data); err != nil { log.Printf("searchDescXML.Execute: %s", err) } }
Content-Type
ヘッダをapplication/opensearchdescription+xml
に設定し、ブラウザがこれをOpenSearch Description Documentとして認識するようにします。次に、テンプレートに渡すデータとしてBaseURL
を動的に生成します。r.Host
からリクエストのホスト名を取得し、http://
を付加することで、godoc
が実行されている実際のURLをBaseURL
としてOSDDテンプレートに渡します。これにより、OSDD内のUrl
テンプレートが正しく解決され、godoc
サーバーのベースURLが反映された検索URLが生成されます。最後に、searchDescXML
テンプレートを実行し、生成されたXMLをレスポンスとして書き込みます。エラーが発生した場合はログに出力します。
これらの変更により、godoc
はOpenSearchに対応した検索機能を提供できるようになり、Webブラウザとの連携が強化されました。
コアとなるコードの変更箇所
lib/godoc/godoc.html
--- a/lib/godoc/godoc.html
+++ b/lib/godoc/godoc.html
@@ -12,6 +12,9 @@
<link rel="stylesheet" href="/doc/ie.css" type="text/css">
<![endif]-->
<script type="text/javascript" src="/doc/godocs.js"></script>
+{{if .SearchBox}}
+<link rel="search" type="application/opensearchdescription+xml" title="godoc" href="/opensearch.xml" />
+{{end}}
</head>
<body>
<div id="container">
lib/godoc/opensearch.xml
(新規ファイル)
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>godoc</ShortName>
<Description>The Go Programming Language</Description>
<Tags>go golang</Tags>
<Contact />
<Url type="text/html" template="{{.BaseURL}}/search?q={searchTerms}" />
<Image height="15" width="16" type="image/x-icon">/favicon.ico</Image>
<OutputEncoding>UTF-8</OutputEncoding>
<InputEncoding>UTF-8</InputEncoding>
</OpenSearchDescription>
src/cmd/godoc/godoc.go
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -105,6 +105,7 @@ func registerPublicHandlers(mux *http.ServeMux) {
mux.HandleFunc("/doc/codewalk/", codewalk)
mux.HandleFunc("/search", search)
mux.Handle("/robots.txt", fileServer)
+ mux.HandleFunc("/opensearch.xml", serveSearchDesc)
mux.HandleFunc("/", serveFile)
}
@@ -600,7 +601,8 @@ var (
packageHTML,
packageText,
searchHTML,
- searchText *template.Template
+ searchText,
+ searchDescXML *template.Template
)
func readTemplates() {
@@ -615,6 +617,7 @@ func readTemplates() {
packageText = readTemplate("package.txt")
searchHTML = readTemplate("search.html")
searchText = readTemplate("search.txt")
+ searchDescXML = readTemplate("opensearch.xml")
}
// ----------------------------------------------------------------------------
@@ -809,6 +812,16 @@ func serveFile(w http.ResponseWriter, r *http.Request) {
fileServer.ServeHTTP(w, r)
}
+func serveSearchDesc(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("Content-Type", "application/opensearchdescription+xml")
+ data := map[string]interface{}{
+ "BaseURL": fmt.Sprintf("http://%s", r.Host),
+ }
+ if err := searchDescXML.Execute(w, &data); err != nil {
+ log.Printf("searchDescXML.Execute: %s", err)
+ }
+}
+
// ----------------------------------------------------------------------------
// Packages
コアとなるコードの解説
lib/godoc/godoc.html
の変更
この変更は、godoc
のWebページがブラウザに読み込まれた際に、OpenSearch Description Documentの存在をブラウザに通知するためのものです。<link rel="search" ...>
タグは、このページが検索機能を提供しており、その詳細がhref
属性で指定されたXMLファイルにあることを示します。{{if .SearchBox}}
というGoテンプレートの条件分岐は、godoc
のWebインターフェースで検索ボックスが表示される場合にのみ、このOpenSearchリンクをHTMLに含めるようにしています。これにより、不必要なリソースの読み込みや、検索機能がないページでの誤ったOpenSearchの検出を防ぎます。
lib/godoc/opensearch.xml
の新規追加
このファイルは、godoc
の検索機能に関するOpenSearchの標準的なメタデータを定義しています。
<ShortName>
と<Description>
は、ブラウザの検索エンジンリストに表示されるgodoc
の識別情報を提供します。<Tags>
は、検索エンジンを分類するためのキーワードです。<Url>
要素は最も重要で、godoc
の検索エンドポイント(/search
)と、ユーザーが入力する検索キーワード({searchTerms}
)がどのようにURLに組み込まれるかを定義しています。{{.BaseURL}}
は、godoc
サーバーが実行されている実際のベースURLに置き換えられるプレースホルダーであり、これによりOSDDがどの環境でも正しく機能するようになります。<Image>
は、ブラウザの検索エンジンリストに表示されるアイコンを指定します。<InputEncoding>
と<OutputEncoding>
は、検索クエリと結果の文字エンコーディングがUTF-8であることを示します。
src/cmd/godoc/godoc.go
の変更
このファイルはgodoc
サーバーの主要なロジックを含んでいます。
- ハンドラの登録:
mux.HandleFunc("/opensearch.xml", serveSearchDesc)
は、/opensearch.xml
へのHTTPリクエストがserveSearchDesc
関数によって処理されるようにルーティングを設定しています。これにより、ブラウザがOSDDを要求した際に、godoc
サーバーがそれを提供できるようになります。 - テンプレート変数の追加と読み込み:
searchDescXML *template.Template
が宣言され、readTemplates
関数内でopensearch.xml
ファイルがGoのhtml/template
パッケージによってパースされ、この変数に格納されます。これにより、opocsearch.xml
が単なる静的ファイルとしてではなく、動的なデータ(BaseURL
など)を埋め込むことができるテンプレートとして扱われます。 serveSearchDesc
関数の実装: この関数は、/opensearch.xml
へのリクエストを処理する責任を負います。w.Header().Set("Content-Type", "application/opensearchdescription+xml")
は、レスポンスのMIMEタイプを正しく設定し、クライアント(ブラウザ)が受信したコンテンツをOpenSearch Description Documentとして解釈するように指示します。data := map[string]interface{}{"BaseURL": fmt.Sprintf("http://%s", r.Host)}
は、opensearch.xml
テンプレートに渡すデータを準備します。r.Host
はHTTPリクエストのHostヘッダから取得され、godoc
サーバーが現在どのホスト名でアクセスされているかを正確に反映します。これにより、OSDD内のUrl
テンプレートの{{.BaseURL}}
が、godoc
サーバーの実際のURL(例:http://localhost:6060
やhttp://go.dev
)に置き換えられます。searchDescXML.Execute(w, &data)
は、パース済みのopensearch.xml
テンプレートに動的に生成したBaseURL
データを適用し、その結果をHTTPレスポンスライターw
に書き込みます。これにより、クライアントは完全に解決されたOpenSearch Description Documentを受け取ることができます。エラーが発生した場合は、log.Printf
でログに出力されます。
これらの変更により、godoc
はOpenSearchの仕様に準拠した検索機能を提供し、Webブラウザとのシームレスな統合を実現しています。
関連リンク
- Go言語公式ドキュメント: https://go.dev/doc/
godoc
コマンドのドキュメント (Go言語公式): https://pkg.go.dev/cmd/godoc- OpenSearch.org: https://opensearch.org/
- OpenSearch 1.1 Specification: https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md
参考にした情報源リンク
- OpenSearch 1.1 Specification (GitHub): https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md
- Go言語の
html/template
パッケージドキュメント: https://pkg.go.dev/html/template - Go言語の
net/http
パッケージドキュメント: https://pkg.go.dev/net/http - Go言語の
fmt
パッケージドキュメント: https://pkg.go.dev/fmt - Go言語の
log
パッケージドキュメント: https://pkg.go.dev/log