この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。サービスグループの武田です。
先日、Sphinxで国際化対応をする手順を確認しました。
各言語ごとにドキュメントが生成されるため、これらをWebサーバーやS3などにデプロイすることで公開できます。さてそうなると次は、各言語の切り替えがしたくなります。URLを直接変更してもらうのは、あまり現実的ではありませんね。というわけで、手軽に言語切り替えするためのボタン(プルダウン)を実装してみました。
なお、前回作成したもの(上記のリンク先参照)を拡張する形で実装します。実際に試してみたい方はそちらを参考にプロジェクトの作成などを行ってください。
今回のゴール
ゴールはもちろん切り替えボタンの実装ですが、それに伴いいくつかの前提を設けます。
まず、ドキュメント公開後のURLですが、ベースURLの後にパスとして次のような言語コードを含めるものとします。言い換えれば、ja/
やen/
がドキュメントのルートになります。
- https://docs.example.com/ja/index.html
- https://docs.example.com/en/index.html
- https://docs.example.com/ko/index.html
ローカルでも同じ構成にしたいので、buildディレクトリの構成を次のようにします。
$ tree -L 2 build/
build/
└── html
├── en
├── ja
└── ko
切り替えボタンを実装してみる
実現したい要件を書き出してみます。
- サポートしている言語がプルダウン表示される
- 言語を選択するとその言語のページに切り替わる(ページ遷移する)
- 現在選択中の言語がプルダウンで選択済みとなっている
さてページのどこに切り替えボタンを配置するかですが、今回はフッタ部分に置きます(細かい調整はしません)。Sphinxではテンプレートの上書きがサポートされているため、使用しているテーマごとに編集するファイルは異なります。今回はデフォルトのAlabasterです。Alabasterではフッタは独立ファイルではなくlayout.html
の一部で定義されています。まずはこれをコピーします。
$ cp .venv/lib/python3.7/site-packages/alabaster/layout.html source/_templates/
さっそく修正していきたいところですが、その前にconf.py
で、ドキュメントがサポートしている言語一覧を辞書として定義しておきます。キーを言語コード、値を言語名とします。定義した値はテンプレートに渡されるため、それを利用してプルダウンを定義します。
source/conf.py
@@ -61,3 +61,11 @@ html_theme = 'alabaster'
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
+
+html_context = {
+ 'support_languages': {
+ 'ja': '日本語',
+ 'en': 'English',
+ 'ko': '한국어'
+ }
+}
次にlayout.html
を次のように修正します。
source/_templates/layout.html
@@ -86,6 +86,18 @@
{%- block footer %}
<div class="footer">
+ <div>
+ <select name="lang" onchange="location.href=value;">
+ {%- for code, display in support_languages.items() %}
+ <option value="{{ pathto('../' + code + '/', 1) }}{{ pathto(pagename, 0, '.') }}"
+ {%- if code == language %}
+ selected
+ {%- endif %}
+ >{{ display }}</option>
+ {%- endfor %}
+ </select>
+ </div>
+
{% if show_copyright %}©{{ copyright }}.{% endif %}
{% if theme_show_powered_by|lower == 'true' %}
{% if show_copyright %}|{% endif %}
selectタグのonchange="location.href=value;"
は、プルダウンで選択した際のイベントハンドラを定義しています。選択された項目のvalueをURLに指定することで自動的なページ遷移を実現します。
次のforループは、先ほどconf.py
で定義したhtml_context
の値がテンプレートに渡されているためここでoptionタグに展開します。code
にはja
などの言語コードが、display
には日本語
などの言語名が代入されます。
{{ pathto('../' + code + '/', 1) }}{{ pathto(pagename, 0, '.') }}
が何をしているのかわかりにくいのですが……。ざっくりいうと言語コードだけ変えた現在ページへの相対パスを生成しています(/ja/index.html
に対する../en/index.html
など)。
{%- if code == language %} selected
は、language
が生成するドキュメントの言語設定が入っているので、同じであれば選択済みとします。
これで言語切り替えボタンの実装は完了です。
Makefileを修正して出力先を変更する
ビルド→本番サーバーにコピー(デプロイ)を各言語ごとに行うのであれば、ここの作業は特に必要ありません。というのも、初期設定のままだと、build/html
にビルドしたドキュメントが生成されるので、言語の指定だけ変更して再ビルドすると上書きされます。そのため、次の言語でビルドする前にコピーを済ませておく必要があります。これはビルドおよびデプロイプロセスの話なのでまぁいいんですが、ローカルで確認するときに不便ですね。というわけで、Makefileを修正して、各言語のドキュメント生成を一括でかつ独立して生成されるようにしましょう。
次のようにMakefileを修正します。html_%
はワイルドカードを使用したターゲットで、言語設定および出力先をターゲットで指定できます。html
はデフォルトのターゲットを上書きするもので、対応する言語を依存先として指定しています。こうしておけばhtml
を指定するだけで各言語のドキュメントが生成されます。
Makefile
@@ -14,6 +14,13 @@ help:
.PHONY: help Makefile
+html_%:
+ @$(SPHINXBUILD) -D language="$*" -b html "$(SOURCEDIR)" "$(BUILDDIR)/html/$*" $(0)
+
+# orverride default html target
+html: html_ja html_en html_ko
+ @
+
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
切り替えを試してみる
これで準備できました!さっそくビルドして試してみましょう。
$ pipenv run make html
$ open build/html/ja/index.html
日本語ページ。
英語ページ。
韓国語ページ。
プルダウンの選択で切り替わりますし、選択済みの言語も変わっていますね!
まとめ
Sphinxドキュメントに言語切り替えボタンを実装してみました。今回はデフォルトのAlabasterのままシンプルに実装しましたが、CSSで見栄えをきれいにもできます。配置する場所も融通がききますので、好きなところに配置してみてください。