nikkie-ftnextの日記

イベントレポートや読書メモを発信

SphinxでビルドしたHTMLの中の外部リンクを、ブラウザの新しいタブで開くように設定する拡張 sphinx-new-tab-link を公開しました!🎉

はじめに

聞いて聞いて! nikkieです。

このたびPyPIにちょっとしたSphinx拡張をリリースしました!
この記事ではそのライブラリについて紹介していきます。

目次

前提:SphinxでHTMLをビルドする

ドキュメンテーションツールSphinxは多様な入力・出力形式をサポートしています。
入力はreStructuredText(reST)やMarkdownなど、出力はHTML、PDF、EPUBなどなど。
reSTやMarkdownで原稿を書いて、SphinxでHTMLに変換するシーンは多いのではないでしょうか(私は結構やります1)。

SphinxでビルドしたHTMLはブラウザで閲覧でき、内部のリンクをリファレンスとしてたどったり、外部のサイトへ遷移2したりできます。
「外部のサイトへの遷移」は、HTMLを開いていたブラウザのタブが遷移します。
新しいタブで開くわけではありません。

今回公開したライブラリは、外部のサイトへのリンクを新しいタブで開くように自動で設定するものです。
好みの問題だと思いますが、リンク先とリンク元を見比べたいことが多く、私は新しいタブでリンクが開くサイトが好きです。

必要な手順は2ステップ、簡単に使えます!

(1) PyPIからインストール:pip install sphinx-new-tab-link

(2) お手元のSphinxプロジェクトのconf.pyextensionssphinx-new-tab-linkを有効にしてください。

extensions = [
    "sphinx_new_tab_link",
]

これだけです!!

reST中に書いた外部のサイトへのリンクは、ビルドされたHTMLではブラウザの新しいタブで開くようになっています。

`Example <https://example.com/>`_ は新しいタブで開きます。

直接リンクを書くケース https://example.com/ もサポートしています。

ブラウザの新しいタブで開くリンクの仕組み

リンクを表すaタグにはtarget属性があります。
この属性に"_blank"という値を渡すと、リンク先のページはブラウザの新しいタブで開きます3

ただし、(ブラウザのバージョンによりますが、)<a href="..." target="_blank">だけでは懸念があります。

target="_blank"属性を使用して別のサイトのページにリンクすると、サイトのパフォーマンスとセキュリティに問題が発生する可能性があります。

上記サイトによると懸念は2つです。

  • 「あなたのページのパフォーマンスが低下する可能性」
  • 「他のページがあなたのページを悪意のあるURLにリダイレクトする可能性」

この対処がaタグのrel属性の指定です。

rel="noopener"またはrel="noreferrer"をあなたのtarget="_blank"リンクに追加することで、これらの問題を回避できます。

こちらが1つの解決法です:<a href="..." target="_blank" rel="noopener noreferrer">

今回公開したSphinx拡張は、外部のサイトのリンクのaタグにtarget属性とrel属性を一緒に設定してくれるんです!
この仕組みを毎回調べなくても、この拡張を有効にするだけで、新しいタブで開くリンクのできあがりです。

なお、JavaScriptを使って、外部のサイトへのリンクにtargetrel属性を付与する方法もあるようです。

なぜこのSphinx拡張を作った?

SphinxでビルドしたHTML中の外部のサイトへのリンクをブラウザの新しいタブで開きたい」
この実現方法には以下のStackOverflowを参考にしました。

この質問にはいくつかの実装方法が載っています。
「すばらしい回答があるのだから誰かライブラリにしているんじゃないか」と感じ、少し調べて見たのですが、それらしいものは見つけられませんでした。
ただ私としては毎回自分で(仕組みを思い出して)書くよりも、インストールと設定だけで済むライブラリが喉から手が出るほどほしいのです。
そこで自作し、このたび公開しました。

「StackOverflowの回答を参考に各自が書くよりも、より簡単に正しい方法で扱えるようになったかな」と小さい達成感を感じています。

こんなところで使われています

GitHub Pagesの例を2つ紹介します。

(1) このライブラリの使い方ガイドのページでは、早速使ってみました(ドッグフーディング!)

(2)「Python Boot Campで全国にPythonの環を広げよう!」のページ4でも、外部のサイトへのたくさんのリンクをどれも新しいタブで開くHTMLを実現するために使っています。

開発過程としては、pycampのページを作っているなかで、外部のサイトへのリンクを別のタブで開くように実装しました。
私が他のリポジトリでも・他の方も同じ実装を使えるようライブラリとしてPyPIに公開した次第です。

もしよろしければこちらのライブラリを使ってみてください。
「私のこのサイトで使っています!」や「こういう機能があるともっと嬉しい」などフィードバックをお寄せいただけると大変嬉しいです。

終わりに

自作したSphinx拡張sphinx-new-tab-linkを紹介しました。
「自分は絶対使う!」というライブラリで、簡単な設定で使えて個人的には大満足です。

この一年ほど、簡単な設定という点を伸びしろとして自覚していました。
自動化して自分は楽になっていて、他の方も同じ恩恵を受けられると自負しているのですが、なかなか使ってもらえないぞと。
使ってもらえない理由の仮説が「正しいんだけど簡単じゃないから」です。
今回のライブラリは小さな成功体験です。
引き続き「正しい使い方を簡単に、誤った使い方を困難に」に取り組んでいきます!

現状reSTはサポートしていると思うのですが、Markdownなど私があまり使わない入力形式は未検証です。
Markdownサポートしているなら使うよ」って方はいそうなので、次はMarkdownサポートかなと思っています。
ただ使っている方の声を優先したいので、ちょっとしたことでも(※(伸びしろだけでなくぜひぜひよい点も))フィードバックをお待ちしています!

私、アスタリスクが好きなんですが、スター🌟をいただいても嬉しいです!


  1. SphinxでビルドしたHTMLは、GitHub Pages(をはじめとする静的サイトホスティングサービス)を使って、Webに公開できます。私もこれまでいくつものGitHub Pagesを公開してきました。GitHub Pagesの公開をしやすくするため、GitHub Actionも自作しました:sphinx-revealjsで作ったスライドをGitHub Pagesで公開する - nikkie-ftnextの日記
  2. タイトルの「外部リンク」は「外部のサイトへのリンク」を指します。
  3. https://developer.mozilla.org/ja/docs/Web/HTML/Element/a#attr-target