Sphinxにひっそり存在するビルダー "dirhtml"の使い勝手を知る
ドキュメンテーションビルダーのSphinxは、組み込みで結構な数のビルドターゲットが存在します。
いくつか例を挙げると、このようにバラエティもかなりありますね。
- スタンダードなHTMLを出力する、
html
- 電子書籍スタイルの、
epub
- Texと連動してPDFを生成できる、
latexpdf
- ドキュメント内にあるリンク先の健全性のチェックができる、
linkcheck
そんな中で、html
の影にひっそり存在しているビルダーに気づきました。
今回は、このdirhtml
ビルダーについての、特徴・使用感などの検証や紹介をしていきます。
dirhtmlビルダーとは
Sphinx組み込みのビルダーです。
標準的なHTMLファイル群を生成するhtml
ビルダーと違って、 全てのドキュメントを{ページ名}/index.html
というファイルパスで生成する ことができます。
組み込みビルダーであるため、よく使うmake html
からmake dirhtml
に変えるだけですぐに出力できます。
挙動の特徴
出力のファイル名ルールが変わる
例えば、以下のような構造のソースがあるとします。
- index.rst
- hello.rst
- demo1/
- sub1.rst
html
ビルダーを用いると、このようなファイル出力をします。
- index.html
- hello.html
- demo1/
- sub1.html
一方、dirhtml
ビルダーでは、このようなファイル出力をします。
- index.html
- hello/
- index.html
- demo1/
- sub1/
- index.html
見ての通り、{ページ名}.rst
から{ページ名}.html
を出力するhtml
に対して、{ページ名}.rst
から{ページ名}/index.html
を出力しています。
このように、「ページ名からはディレクトリを生成して、ディレクトリ内にindex.html
を出力する」振る舞いが、dirhtml
となっています。
もちろんですが、「html
ビルドでのhello.html
」と「dirhtml
ビルドでのhello/index.html
」はコンテンツとしての中身は同じです。
ページ名.rst
vs ページ名/index.rst
は後者が優先される?
index.rst
はindex.html
へ出力されます。hello.rst
はhello/index.html
へ出力されます。
dirhtml
を利用した際に、次の2ファイルがある場合、どのような挙動をするでしょうか。
hello.rst
hello/index.rst
この2ファイルは、dirhtml
での出力先としてはどちらもhello/index.html
になります。
手元で試す感じでは、最終的に出力内容として残るのはhello/index.rst
をソースとするものでした。
おそらくですが、次の2.5点から起きていると考えています。(細かくは見ていない)
- 出力先に何かあっても、基本的には上書き出力する
- ページ一覧を取りまとめた後に、辞書順に出力処理をする
- ページ一覧としては拡張子を無視するため、
hello
->hello/index
の順が固定になっている
- ページ一覧としては拡張子を無視するため、
ページ間リンクは、何の問題もなく機能する
Sphinxにはドキュメント間のリファレンス用の文法として:doc:
が提供されています。
この文法を利用すると、例えばhello.rst
内で:doc:`demo1/sub1`
と書いてビルドすると、「demo1/sub1.rst
から生成されたファイル」へのリンクを生成します。
これはhtml
ビルドでもdirhtml
ビルドでも正しく機能します。当たり前ではあるのですが。
検証を飛ばしましたが、同類の:ref:
もおそらく問題なくリンクできるでしょう。
dirhtml
ビルド
実用面で考えるここからは、html
ビルドとdirhtml
ビルドの生成物を、ホスティング観点で考えてみます。
静的サイトとしての機能自体は大きな差はない
2ビルダーの違いは実質的に「ページ生成におけるファイルの出力先」のみと考えて良いでしょう。
どちらにしても静的サイトとしての生成となることから、基本機能としては変わりません。
そのため、ただただ配信することだけに着目スル分には、html
ビルド・dirhtml
ビルドの好きな方を使えばよいでしょう。
後方互換性の向上が見込める
前提として、多くのWebサーバーではディレクトリとなる/
へのアクセスに対して、何を返すかを指定できます。
ApacheなどではDirectory Indexディレクティブで設定でき、よく設定されているものがindex.html
となっています。
Firebase Hostingなどのような静的サイト配信基盤でもこのあたりは変わらず、/
に対してはindex.html
を探して返します。
dirhtml
ビルドも主体としてはDirectory側にあります。
そのため、上記で説明したサイト内のページ内リンクは../index.html
といったファイル指定ではなく../
というディレクトリ形式のリンクになっています。
つまり、dirhtml
ビルドを行ったサイトを配信すると、index.html
というファイル名を意識することがなくなります。
これは、「Webサイトの後方互換性」という観点を考えると、非常に有効になります。
ディレクトリ形式のURLが前提になるということは、URLがファイル名・さらには拡張子に依存しなくなることを意味します。
このため、よりよいURLでのサイト提供が出来るという初動のメリットがあると同時に、サイトジェネレーターの変更にも強くなれます。
この点を今回は「Webサイトの後方互換性が高い」と表現できるでしょう。
RTDもdirhtmlをサポートしている
Sphinxドキュメントのホスティングサービスである、Read the Docsはビルド時のビルダーが制限されています。
HTML系統に属するもののうち一部のみに対応しているのですが、幸いdirhtml
はサポート対象のビルダーに含まれています。
そのため、自作ライブラリのドキュメントをdirhtml形式で配信をすることは非常に簡単となっています。
実際に切り替えるには(実例つき)
作業コストに対してメリットがそれなりに高い物となっています。そうなると「じゃあ試してみようか」と考える人もいるでしょう。
実際に、Sphinxとablogで生成している自分の個人サイトをdirhtml化してみたのですが、その際の注意点と特定環境での実例を紹介します。
出力方式のまとめ
-
html
ビルドでhello.rst
->hello.html
だった箇所が、全てhello.rst
->hello/index.html
になる - 出力されるHTMLにおけるページ間遷移については、
/
形式へのリンクが正しく設定される -
_static
(js/cssのような静的ファイル群)フォルダに関しては変わらない
Webサーバーとして何をしておく必要があるか
もともとhtml
ビルドを配信していたものをdirhtml
ビルドで配信するときに気をつける点は、上記まとめのうち最初の1つのみです。
この出力に対して、次のようなリダイレクト処理を施す必要があります。
-
**/hello.html
といったページへのリクエストは、**/hello/
のように「拡張子箇所の削除と/
を追加」したURLへのリダイレクトをさせる - ただし、
**/index.html
を直接指定したリクエストは、**/
へのリダイレクトをさせる
※もし、検索エンジンなどのことを無視していいのであれば、放置でも別に平気です。
Firebase Hostingでの例
Firebase Hostingでは、リダイレクト周りの挙動をfirebase.json
内に記述できます。
{
"hosting": {
"redirects": [
{
"regex": "^(.*?)(\\/index)?\\.html$",
"destination": ":1:3/",
"type": 302
}
]
}
}
上記は自サイトでの例ですが、このような記述で以前のページのブックマークなどに対して適切なリダイレクトを返せるようになっています。
振り返り
自サイトをdirhtml
化してからしばらく経過してますが、運用上はトラブルらしいトラブルにはなっていません。
もし、「個人サイトをSphinxで管理している(したい)」「けどURLにhtmlが常時つくのは気になる」という方は、切り替えに挑戦してみてはいかがでしょう。
Discussion