Flaskでツールチップの実装

本記事では、PythonのWebアプリケーションフレームワークであるFlaskでwebアプリ等を作る際に、ツールチップ機能を実装する方法について記述します。
ツールチップとは、難しい意味の単語がweb上に書かれている際にその単語や単語付近のアイコンにカーソルを合わせると、詳細な意味が書かれた吹き出しが表示されるweb機能の一種です。

以下画像が今回作成したものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709441/0d33cf3c-7be1-4325-18cc-1f99309664e2.png)

今回はよくWebサイトで見られるように、文字の近くにクエスチョンのアイコンを設け、そのアイコンにカーソルを合わせると吹き出しが表示される機能を実装しました。


# 環境
+ MacBook Air
+ Python3.7.6
+ Flask 1.1.1
+ Bootstrap 4

# 実装方法

### ディレクトリ構成
ディレクトリは以下の様に構成します。今回はBootstrapというCSSのフレームワークを用います。
Flaskで作るWebアプリケーションにBootstrapを適用する場合は以下のように __static__ ディレクトリと __css__ ディレクトリの中にそれぞれ対応したcssファイルとjsファイルを配置しておく必要があります。
.
├─ app.py
├─ static
│   ├─css
│   │  　　 └ bootstrap.min.css
│   └─ js
│    　　　├ bootstrap.bundle.min.js
│    　　　 └ jquery-3.5.1.min.js
└─ templates
         　　　　 └ test_tooltip.html


### コード

__app.py__ と __test_tooltip.html__ の内容について、今回はツールチップの書き方のみを説明するためその他は極めて間便なものとします。
まず __app.py__ は以下のように作成しました。Bootstrapを適用するといっても特別なモジュールをimportする必要はありません。
```app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def test():
    return render_template('test_tooltip.html')

if __name__ == "__main__":
    app.run(port=5000)
```

<br>

次に __test_tooltip.html__ は以下のように作成しました。

```test_tooltip.html
<link rel="stylesheet" href="/static/css/bootstrap.min.css">

<script src="/static/js/jquery-3.5.1.min.js"></script>
<script src="/static/js/bootstrap.bundle.min.js"></script>

<script>
(function() {
  window.addEventListener("load", function() {
    $('[data-toggle="tooltip"]').tooltip();
  });
})();
</script>
```
まずはBootstrapのcssとjsファイルを適用し、その後 __script__ タグでツールチップを表示するための関数を記述します。
addEventListenerとはマウスやキーボードからのイベントを処理するためのメソッドであり、第一引数に __load__ を指定することでページが読み込まれた際に、tooltip関数が自動で実行される様になります。
tooltip関数の中身についてはBootstarpに組み込まれているので特に記述の必要はありません。

```test_tooltip.html
<h4 class="my-3">
  <h4>
    ツールチップテスト
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-question-circle" viewBox="0 0 16 16" data-toggle="tooltip" data-placement="right" title="このようにカーソルを合わせることで単語の説明が表示されます">
      <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
      <path d="M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z"/>
    </svg>
  </h4>
</h4>
```
次にツールチップの部分について、まず用語の部分を通常通り記述します。「ツールチップテスト」とします。
今回はこの単語にカーソルを合わせた際ではなく隣接するクエスチョンアイコンにカーソルを合わせた際に表示されるようにしたいので、該当部分を __svg__ タグで記述して、アイコンの大きさや色、ツールチップとして表示される文章を指定し、 __path__ タグでクエスチョンマークの詳細な形状を指定します。
__path__ タグでアイコンの形状を指定する方法については後述します。
<br>
以上のapp.pyとhtmlファイルを用いることで、任意の単語にツールチップ機能を搭載することができました。

### アイコンの探し方
アイコンの探し方は、まず[Bootstrapの公式ページが提供しているアイコン一覧のページ](https://icons.getbootstrap.com/)にアクセスし、スクロールして好みのアイコンを探してクリックします。
今回はクエスチョンマークを用いたかったのでイメージのデザインと近かった __question-circle__ アイコンをクリックしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709441/b2bae45a-47ad-8462-c63b-d11b87230824.png)

以下の右下の __Copy HTML__ に __path__ タグで記述すべき内容が書かれているので、そのままコピー&ペーストすれば好きなアイコンをweb上に表示することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709441/b97690da-5a6a-43b4-df36-3bfa30b7f9f2.png)

クエスチョンマークのアイコンは他にも10種類以上あるので、好みに合わせて使い分けることができます。


# 参考文献
[Bootstrap公式](https://getbootstrap.jp/)
[Bootstrapのアイコン一覧（公式）](https://icons.getbootstrap.com/)
[【JavaScript】addEventListenerの使い方](https://qiita.com/mzmz__02/items/873118fbd8723c44956d)