Flask についてまとめ4　テンプレートエンジンを利用

ルーティングを利用する
前回　前々回記事では

https://qiita.com/TaichiEndoh/items/ca306560b928eddfc222

https://qiita.com/TaichiEndoh/items/7b7f82134a0333f8c8b9

https://qiita.com/TaichiEndoh/items/2d010ce586fc07c0a212

ubuntu でpython仮想環境を利用し
アプリケーションルートがflaskbook
になるように変化しました

```
flaskbook
- .env
- apps
  - minimalapp
- venv
```

### ルーティングの実施
ルーティングとは、リクエスト先のURI　と実際に処理する関数を
紐付ける作業のことです

詳しく説明すると　

リクエスト先のURL（Uniform Resource Locator）とは、
Webサイトやファイルなどのインターネット上での場所・情報

と

実際に処理する関数

を紐づける作業のことを指します

Flaskでは、
関数の先頭にデコーダー（暗号化されたデータを復号する）と呼ばれる関数@app.route()を追加することで
ルート（経路）　を追加できます

まずapp.pyにルートの追加をします
```
#flask クラスをimport
from flask import Flask

#Flask クラスをインスタンス化する
app = Flask(__name__)

#URLと実行する関数をマッピングする
@app.route("/")
def index():
    return "Hello, Flask book like CEML"

# ルーティング
@app.route("/hello")
def hello_world():
    return "Hello world"
```

右のローカルホスト上で　http://127.0.0.1:5000/hello

Hello world

と表示されると思われます
### ルーティング情報の確認
flask routes コマンドでルーティング情報の確認ができます

```
Endpoint     Methods  Rule
-----------  -------  -----------------------
hello_world  GET      /hello
index        GET      /
static       GET      /static/<path:filename>
```

### Flask の Endpoint に名前をつける
Endpointは通常は、APIにアクセスするためのURI　のことを指します
FlaskではURIと紐付けられた関数名または関数につけた名前　のことを指します
それではEndpoint 名 を　endpoint="hello-endpoint"に変更してみます
app.py　のファイルを変更します

```
#flask クラスをimportします
from statistics import mean
from flask import Flask

#Flask クラスをインスタンス化する
app = Flask(__name__)

#URLと実行する関数をマッピングする
@app.route("/")
def index():
    return "Hello, Flask book like CEML"

#ルーティング
@app.route("/hello",
           methods=["GET"],
           endpoint="hello-endpoint"
           )

#endpoint を指定しない場合は　関数名がendpoint 名となる
#許可するHTTPメソッドをGETとPOSTにする場合
#methods=["GET","POST"]となる

def hello_world():
    return "Hello world"
```
以下のように成ります
```
Endpoint        Methods  Rule
--------------  -------  -----------------------
hello-endpoint  GET      /hello/<name>
index           GET      /
static          GET      /static/<path:filename>
```

### デコレーターのRuleに変数を指定できる
@app.route デコレーターのRuleに変数を指定できる
変数は＜変数名＞の形式で指定する

デコレータは関数やクラスの前後に特定の処理を追加できる機能です
関数やクラス宣言の前に @デコレータ名  を記述することで実現できます

app.py　のファイルを変更
```
#flask クラスをimport
from statistics import mean

from flask import Flask

#Flask クラスをインスタンス化する
app = Flask(__name__)

#URLと実行する関数をマッピングする
@app.route("/")
def index():
    return "Hello, Flask book like CEML"

#ルーティング
@app.route("/hello/<name>",
           methods=["GET"],
           endpoint="hello-endpoint"
           )

#endpoint を指定しない場合は　関数名がendpoint 名となる
#許可するHTTPメソッドをGETとPOSTにする場合
#methods=["GET","POST"]となる


def hello(name):
    #python3.6から導入されたf-stringで文字列を定義
    return f"Hello world,{name}!!!!!"
def hello_world():
    return "Hello world"
```
を実行すると

右のローカルホスト上で　http://127.0.0.1:5000/hello/ceml
で　　Hello world,ceml!!!!!
の表示が確認できると思います

### テンプレートエンジンを利用する
テンプレートエンジンはテンプレートと呼ばれる　ひな形
と　データを合成して成果ドキュメントを出力するソフトウェアです

Flaskのテンプレートエンジンは、Jinja2です

テンプレートエンジンjinjaを使うと、Pythonを使ってHTMLファイルを生成することができます

https://ymgsapo.com/2019/09/18/flask-jinja/
```
#flask クラスをimport
from statistics import mean

from flask import Flask, render_template

#Flask クラスをインスタンス化する
app = Flask(__name__)

#URLと実行する関数をマッピングする
@app.route("/")
def index():
    return "Hello, Flask book like CEML"

#ルーティング
@app.route("/hello/<name>",
           methods=["GET"],
           endpoint="hello-endpoint"
           )

#endpoint を指定しない場合は　関数名がendpoint 名となる
#許可するHTTPメソッドをGETとPOSTにする場合
#methods=["GET","POST"]となる


def hello(name):
    #python3.6から導入されたf-stringで文字列を定義
    return f"Hello world,{name}!!!!!"
def hello_world():
    return "Hello world"

# show_name エンドポイントを作成する
@app.route("/name/<name>")
def show_name(name):
    #変数をテンプレートエンジンに渡す
    return render_template("index.html",name=name)
```

以下のhtmlファイルを作成

テンプレート　app/minimalapp/templates/index.html
を作成

```
<!doctype html>
<html lang="ja">

<head>
    <title>Ceml</title>
    <meta charset="utf-8" />
    <title>name</title>
</head>

<body>
    <h1>{{name}}</h1>
</body>

</html>
```


右のローカルホスト上で　http://127.0.0.1:5000/name/ceml
確認できます

### FlaskでAddress already in use errorとなったときの対処法

https://yusuke-ujitoko.hatenablog.com/entry/2018/07/14/144227

https://qiita.com/rasedevapp/items/8a5df9e865da829deed9


使用しているプロセスを調べる
 sudo lsof -i:5000
プロセスを殺す　使用しているプロセスのPIDを入力
 sudo kill -9 （使用しているプロセスのPID）

flask run　を実行

### HTMLを変更して動作チェック

https://developer.mozilla.org/ja/docs/Web/HTML/Element/Heading_Elements

テンプレート　app/minimalapp/templates/index.html
を変更

```
<!doctype html>
<html lang="ja">

<head>
    <title>name</title>
    <meta charset="utf-8" />
    <title>name</title>
</head>

<body>
    <h1>Toward the widespread use of clinical engineers and machine learning.</h1>
    　　<h2>Studying Flask</h2>
    <h1>{{name}}</h1>
</body>

</html>
```

プロセスをkillしてから再度　実施すると反映されました

使用しているプロセスを調べる
 sudo lsof -i:5000
プロセスを殺す　使用しているプロセスのPIDを入力
 sudo kill -9 （使用しているプロセスのPID）

flask run　を実行

右のローカルホスト上で　http://127.0.0.1:5000/name/ceml
確認できます


### テンプレートエンジンを使用することのメリット
上記のようにテンプレート　app/minimalapp/templates/index.html
の内容を切り替えることで

枠組み　を　HTML　で記載し



    <h1>Toward the widespread use of clinical engineers and machine learning.</h1>
    　　<h2>Studying Flask</h2>
表示
------
Toward the widespread use of clinical engineers and machine learning.
Studying Flask
------

の枠組みを固定でき

その下の　変数　name　の部分は任意の文字列に変更することがができます

たとえば右のローカルホストにアクセスすると　http://127.0.0.1:5000/name/ceml_like
以下のテンプレートにあった　変数を呼び出すことができ
```
<h1>{{name}}</h1>
```
表示
------
ceml_like
------


右のローカルホスト名を変更すると　http://127.0.0.1:5000/name/ceml_like!!!!!!!!
以下のテンプレートにあった　変数をの内容が
ceml_like　から　ceml_like!!!!!!!!　に変わり
```
<h1>{{name}}</h1>
```
表示
------
ceml_like!!!!!!!!
------

となります

次回はテンプレートエンジンの　if 　と　for文　の使い方について記載していく予定です