Python Flask - Templates
Python Flask의 Templates는 대표적인 예시로 Bootstrap (테마 템플릿) 보여지는 부분과 처리(Python 로직)처리 부분을 보다 쉽고 깔끔하게 나누기 위해 사용합니다.
Templates는 'templates" 디렉터리에 저장되어 URL로 직접 참조가 불가능합니다.
반면, css와 js 파일들은 "static" 디렉터리에 저장되며 URL로 직접 참조가 가능합니다.
또한 사용하기 위해 Flask "render_template()" 함수를 사용하고, JinJa2 Template 엔진을 사용하여 HTML내에 Code를 넣어 작동시킬 수 있습니다.
dongdonge@dongdonge$ ls -la
total 32
drwxr-xr-x 4 root root 4096 Jul 3 21:15 .
drwxr-xr-x 4 root root 4096 Jul 1 22:19 ..
-rw-r--r-- 1 root root 1807 Jul 3 21:17 app.py
-rw-r--r-- 1 root root 89 Jul 2 00:49 run.wsgi
drwxr-xr-x 2 root root 4096 Jul 2 22:44 static # CSS 및 js 파일 저장 디렉토리
drwxr-xr-x 2 root root 4096 Jul 3 21:20 templates # HTML Code 템플릿 저장 디렉토리
Web Root Directory 하위에서 "templates"와 "static" 생성
<!DOCTYPE HTML>
<html>
<head>
<title>DongDongE - Title</title>
</head>
<body>
<h1>Hello, World!!</h1>
</body>
</html>
/templates/index.html
templates 디렉터리에 "index.html" 파일을 작성하여 아래 "app.py"에서 분리된 html 파일을 가져오도록 하겠습니다.
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html")
/app.py
render_template("index.html")
render_template 함수가 인자로 "index.html"을 전달하고 있습니다.
templates/index.html 파일을 불러와 브라우저에 출력하게 됩니다.
template를 불러와 정상적으로 브라우저에 출력이 되었습니다.
이번에는 template를 불러올때 인자를 전달하여 전달된 인자가 출력되도록 하겠습니다.
<!DOCTYPE HTML>
<html>
<head>
<title>DongDongE - Title</title>
</head>
<body>
<h1>Hello, {{ name }}!!</h1>
</body>
</html>
/templates/index.html
index.html 파일의 "{{ name }}!!" 부분을 보면, name이라는 변수를 "{{" 와 "}}"에 의해 출력 됩니다.
자세한건 아래 예시를 통해 확인 해보도록 하겠습니다.
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template("index.html", name = "DongDongE")
/app.py
Code를 확인해보면 render_template 함수가 "index.html"를 불러오고, name 변수에 "DongDongE" 문자열이 전달되어 브라우저에 출력이 됩니다.
이번에는 사용자가 전달한 파라미터의 값에 따라 동적으로 로직을 처리하고, 조건에 맞게 각각 다르게 출력되도록 구현해보겠습니다.
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/<score>")
def index(score):
return render_template("index.html", tmp=int(score))
/app.py
<!DOCTYPE HTML>
<html>
<head>
<title>DongDongE - Title</title>
</head>
<body>
{% if tmp > 50 %}
<h1> result is Pass!! {{ tmp }} </h1>
{% else %}
<h1> result is Fail!! </h1>
{% endif %}
</body>
</html>
/templates/index.html
또한 "/templates/index.html"에서 JinJa2 템플릿 엔진을 사용하여 HTML 문서내 Code를 삽입하여 웹 페이지를 동적으로 생성한 부분을 볼 수 있습니다.
아래는 JinJa2는 아래와 같이 구분 기호를 사용합니다.
-
{% ~ %} Statements, 구문 작성 (if, for 등 관련 로직 처리)
-
{{ ~ }} Expressions, print to template output (출력 및 템플릿 가져오기)
-
# ~ # Line Statements
-
{# ~ #} Comments, 주석
위 4가지 태그를 사용할 수 있습니다.
다음으로 아래 예시는 여러개의 값을 전달하여 표를 출력 해보도록 하겠습니다.
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
data = {"ABC":100, "DEF":250, "GHI":550}
return render_template("index.html", result = data)
/app.py
data 변수에 dictionary Type으로 3개의 데이터가 저장되어 있습니다. data 변수를 result에 담아 render_template() 함수에 인자로 전달합니다.
<!DOCTYPE HTML>
<html>
<head>
<title>DongDongE - Title</title>
</head>
<body>
<table border = 1>
{% for key, value in result.iteritems() %}
<tr>
<th> {{ key}} </th>
<th> {{ value}}</th>
</tr>
{% endfor %}
</table>
</body>
</html>
/templates/index.html
"{%" 구문을 통해 내부 로직을 처리하고, "{{" 구문으로 변수 key와 value를 출력합니다.
이번에는 "layout.html"와 "index.html"를 분리시켜 템플릿에서 동적으로 생성해보도록 하겠습니다.
from flask import Flask, redirect, url_for, request, render_template
app = Flask(__name__)
@app.route("/")
def i_index():
return render_template("index.html")
/app.py
<!DOCTYPE HTML>
<html lang="kr">
<head>
<meta charset="utf-8">
<title>Flask - Test</title>
</head>
<body>
<h1>layout - 1</h1>
<br>
<h1>layout - 2</h1>
<br>
{% block content %}{% endblock %}
<br>
<h1>layout - 3</h1>
</body>
</html>
/templates/layout.html
"layout.html" 파일은 사이트에서 동일한 구성요소 (상단바, 하단바, 등)는 해당 파일에 두고, 나머지는 상속을 받아 처리합니다.
즉, "layout.html" 파일을 바탕으로 상속 받을 "login.html", "register.html", "main.html" 등.. 상속 받아 사용할 수 있습니다.
{% block <이름> %}
{% endblock %}
위 Code는 상속 받은 템플릿 ("index.html" 등.)에서 사용할 수 있는 공간을 정의합니다.
{% extends 'layout.html' %}
{% block content %}
<div>
<p>index - start</p>
<h1>index.html</h1>
<p>index - end</p>
</div>
{% endblock %}
/templates/index.html
"extends"로 상속 선언을 합니다.
초록색 박스 부분은 "index.html"이며, index.html은 부모 "layout.html"를 상속받아 코드가 합쳐져 실행됩니다.