Flask에서 기본적으로 사용되는 템플릿 엔진 중 하나입니다. Jinja2는 파이썬 기반의 강력하고 유연한 템플릿 엔진으로, HTML
과 함께 동적으로 데이터를 렌더링
하는 데 사용됩니다.
템플릿 상속
Jinja2에서는 기본 템플릿을 확장하고 확장된 템플릿에서 블록을 오버라이드하여 재사용 가능한 템플릿을 작성할 수 있습니다.
표현식 사용
{{ }}는 변수 출력, {% %}는 제어문과 블록 구조 등을 표현하는데 사용됩니다.
필터 및 함수
Jinja2는 변수나 표현식에 적용할 수 있는 다양한 필터를 제공하며, 사용자 정의 함수를 통해 템플릿에서 재사용 가능한 기능을 만들 수 있습니다.
조건문 및 반복문
if/else와 for 루프와 같은 기본적인 제어 구조를 제공하여 템플릿에서 로직을 수행할 수 있습니다.
💡 본 글은 예제 코드를 이용하여 설명합니다.
flask/source/my_app/views/board.py를 살펴보면 render_template
함수를 이용하여 출력할 템플릿 명을 전달하여 웹 브라우저에서 출력됩니다.
# 코드 생략
return render_template(
template_name_or_list="board/board.html",
posts=posts,
start_page=start_page,
end_page=end_page if end_page else 1,
prev_page=0 if prev_page < 1 else prev_page,
next_page=next_page,
form=form
)
하지만 템플릿 명만 전달한 것이 아닙니다. posts=posts 등과 같이 변수 이름=변수를 전달하였습니다.
이 변수는 템플릿에서 동적으로 처리하기 위해 HTML 파일에 Python 변수를 전달하는 방법입니다.
flask/source/my_app/templates/board/board.html을 살펴 보겠습니다.
13번, 34번, 38번 등 중첩된 중괄호({})가 사용된 것을 많이 확인할 수 있을겁니다.
HTML 파일에서 {{ 변수 명 }}
을 사용하게 되면 render_template으로 부터 전달 받은 변수나 global 변수 혹은 반복문 중 접근하는 변수들의 데이터를 출력할 수 있게 됩니다.
<!-- 코드 생략 -->
<td class="text-center align-middle">
{{ post.username }}
</td>
<td class="text-center align-middle">
{{ post.views }}
</td>
<td class="text-center align-middle text-nowrap">
{{ post.created }}
</td>
</tr>
flask/source/my_app/templates/board/board.html를 살펴보면 조건문
, 반복문
와 같은 제어 구조를 사용하는 예제입니다.
{% if condition %}...{% endif %}와 같이 중괄호({})와 백분율(%) 기호로 구성됩니다.
Python의 elif/else문은 {% elif condition %}/{% else %}으로 사용됩니다.
반복문도 {% for %}로 시작하여 {% endfor %}로 끝나야 합니다.
{% if posts.items|length >= 1 %}
{% for post in posts.items %}
<!-- 코드 생략 -->
{% endfor %}
{% else %}
<tr>
<td class="text-center" scope="row" colspan="5">작성된 글이 존재하지 않습니다.</td>
</tr>
{% endif %}
flask/source/my_app/templates/board/board.html를 살펴보면 변수|함수
형식을 사용한 것을 확인할 수 있습니다.
아래의 예제는 posts.items의 길이를 반환하는 필터를 적용한 내용입니다.
{% if posts.items|length >= 1 %}
Template Designer Documentation에서 기본적으로 제공되는 필터 목록을 확인할 수 있습니다.
기본적으로 제공되는 필터로 부족하다면 사용자 정의 필터를 정의 후 등록하여 사용할 수도 있습니다.
웹 애플리케이션에서 사용자에게 일회성 메시지나 경고를 전달하는 데 사용되는 기능입니다.
주로 사용자에게 성공적인 작업 완료, 오류 메시지, 경고 또는 다른 유용한 정보를 표시할 때 유용합니다.
flask/source/my_app/templates/base.htm는 메시지 플래싱을 사용한 예제입니다.
메시지가 존재한다면 Javascript의 alert를 이용하여 메시지를 출력하도록 합니다.
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<script>alert("{{ message }}")</script>
{% endfor %}
{% endif %}
{% endwith %}
메시지를 발생시키는 방법은 flask/source/my_app/views/index.py에서 나와 있는 것과 같이 flash()
에 전달할 메시지를 입력하면 됩니다.
def login():
# 코드 생략
else:
for _, values in form.errors.items():
for value in values:
flash(message=value)
템플릿이 위치해야할 디렉토리 명은 기본적으로 templates
여야 합니다. 디렉토리 명을 변경하고자 한다면 Flask 객체를 생성할 때, template_folder 인자에 디렉토리 명을 전달하면 됩니다.
flask/source/my_app/templates/base.html를 살펴보면 block
을 사용하였고, content라는 이름으로 지정하였습니다.
따라서, 해당 템플릿을 상속받고자 한다면, 자식 템플릿은 content라는 이름을 사용하여 부모 템플릿의 content 위치에 렌더링할 수 있습니다.
<body>
{% block content %}{% endblock %}
</body>
flask/source/my_app/templates/user/login.html을 살펴보면 extends
을 사용하였고, content라는 이름으로 블록을 사용하였습니다.
Flask에서 login.html을 반환하면 부모 템플릿(base.html)을 상속받은 상태로 login.html이 렌더링되게 됩니다.
{% extends "base.html" %}
{% block content %}
flask/source/my_app/templates/board/board.html를 살펴보면 include
를 사용한 것을 볼 수 있습니다. include를 사용하면 뒤에 전달되는 템플릿을 불러오게 되며 재사용성을 높힙니다.
<div class="container-fluid">
{% include "nav.html" %}