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.rsthello/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