프로그래밍 언어/Python

웹 UI 개발을 위한 Flask 템플릿 엔진 Jinja2 조건문과 템플릿 구조 가이드 - Flask #3

eco7T 2025. 4. 10. 08:01
반응형

Flask 웹 개발 입문자 및 실무자를 대상으로 템플릿 엔진 Jinja2의 기본 개념과 문법을 익히고, 이를 웹 UI로 구성할 수 있도록 정리합니다. Jinja2는 Flask 개발에서 HTML과 Python 간의 연결을 자연스럽게 처리하는 핵심 도구이며, 조건문, 반복문, 템플릿 상속 및 레이아웃 구성 같은 기능을 통해 웹페이지의 구조화, 재사용성, 유지보수에 있어서 효율성이 높습니다.

Flask 템플릿 엔진 Jinja2
Flask 템플릿 엔진 Jinja2

 

반응형

 

Flask 템플릿 엔진 Jinja2의 이해와 활용

  Jinja2 문법 기초

웹 개발에서는 서버의 데이터를 사용자의 브라우저에 보여주기 위해 HTML에 동적으로 값을 삽입하는 경우가 많습니다.

예를 들어 사용자의 이름이나 게시글 목록 등을 표시하려면 단순한 정적 HTML만으로는 부족하죠. 이때 사용하는 것이 템플릿 엔진입니다. Jinja2는 Flask에서 기본으로 사용하는 템플릿 엔진으로, Python 코드와 HTML을 자연스럽게 연결해 주는 역할을 합니다.

HTML에 Python 데이터를 쉽게 삽입하거나, 조건에 따라 다른 내용을 보여줄 수 있도록 합니다.

 

변수 출력과 기본 연산

Jinja2에서 가장 기본적인 기능은 변수 출력입니다. 서버에서 넘긴 데이터를 HTML에 표시하고 싶을 때  {{ 변수명 }}  문법을 사용합니다. 이중 중괄호( {{ }} )는 "여기에 값을 삽입하라"는 의미입니다.

예를 들어 사용자의 이름을 출력하고 싶다면 다음과 같이 작성합니다.

# app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html', name='홍길동')

 

 

 

 

 

 

<!-- templates/index.html -->
<h1>안녕하세요, {{ name }}님!</h1>

이 코드를 실행하고 브라우저에서 접속하면 “안녕하세요, 홍길동님!”이라는 문장이 나타납니다.

또한, 기본적인 연산도 가능합니다. 예를 들어  {{ 5 + 3 }} 은 8을 출력하고,  {{ "안녕" + "하세요" }} 는 “안녕하세요”를 만듭니다.

 

 

필터 사용법

Jinja2에서는 출력 전에 데이터를 가공할 수 있는 필터(filter) 기능도 제공합니다. 필터는 파이프 기호  | 를 사용하여 적용합니다. 예를 들어 사용자의 이름을 모두 대문자로 바꾸고 싶다면 다음과 같이 작성합니다.

<p>{{ name | upper }}</p>

자주 사용되는 필터로는 다음과 같은 것들이 있습니다:

- `upper`: 대문자 변환 - `lower`: 소문자 변환 - `length`: 길이 반환 - `default`: 값이 없을 경우 기본값 지정

<p>이름 길이: {{ name | length }}</p>
<p>{{ greeting | default('안녕하세요') }}</p>

 default  필터는 변수가  None 이거나 정의되지 않았을 때 기본값을 출력해주기 때문에, 실무에서 종종 유용하게 쓰입니다.

 

 

 

 

 

 

  조건문, 반복문, 템플릿 상속

조건문으로 동적인 콘텐츠 제어

웹 페이지에서는 사용자의 상태나 조건에 따라 콘텐츠가 달라져야 하는 경우가 많습니다. Jinja2는 이런 경우를 위해 조건문을 지원합니다. 기본 문법은 다음과 같습니다.

{% if user_logged_in %}
    <p>환영합니다, {{ username }}님!</p>
{% else %}
    <p>로그인해주세요.</p>
{% endif %}

 {% %}  구문은 제어문(논리 구조)에 사용되며,  {{ }}  구문과 구분됩니다. 조건문 안에서는 파이썬과 유사하게  == != < 같은 비교 연산자를 사용할 수 있습니다.

 

 

반복문으로 리스트나 딕셔너리 출력

Jinja2의 반복문은 `for` 구문을 활용합니다. 서버에서 넘겨준 리스트나 딕셔너리를 순회하며 반복 출력할 수 있습니다.

@app.route('/posts')
def posts():
    post_list = ['첫 번째 글', '두 번째 글', '세 번째 글']
    return render_template('posts.html', posts=post_list)

 

 

 

 

 

 

<ul>
{% for post in posts %}
    <li>{{ post }}</li>
{% endfor %}
</ul>

딕셔너리의 경우에는 다음과 같이 키와 값을 함께 사용할 수 있습니다.

{% for key, value in user_info.items() %}
    <p>{{ key }}: {{ value }}</p>
{% endfor %}

 

 

템플릿 상속을 통한 코드 재사용

웹사이트에서는 모든 페이지에 공통적으로 들어가는 헤더나 푸터가 있습니다. 이를 매번 복사해서 넣는 방식은 비효율적이고 유지보수가 어렵습니다. Jinja2는 템플릿 상속 기능을 제공해 이런 문제를 해결합니다.

<!-- templates/base.html -->
<html>
<head><title>내 사이트</title></head>
<body>
    <header>공통 헤더</header>
    {% block content %}{% endblock %}
    <footer>공통 푸터</footer>
</body>
</html>
<!-- templates/index.html -->
{% extends 'base.html' %}
{% block content %}
    <h1>홈페이지에 오신 걸 환영합니다!</h1>
{% endblock %}

상속을 이용하면 공통 구조는  base.html 에 작성하고, 개별 페이지는 필요한 부분만 작성할 수 있어 코드가 간결해지고 유지보수도 쉬워집니다.

 

 

  블록 구조와 레이아웃 구성

블록(block)은 템플릿 상속에서 가장 핵심적인 구성 요소입니다. 부모 템플릿에서  {% block 이름 %}{% endblock %}  구문을 통해, 자식 템플릿이 채워야 할 부분을 정의합니다.

예를 들어 다음처럼 여러 블록을 지정할 수 있습니다.

<!-- templates/base.html -->
<head>
    {% block styles %}{% endblock %}
</head>
<body>
    {% block content %}{% endblock %}
    {% block scripts %}{% endblock %}
</body>

자식 템플릿에서는 필요한 블록만 선택적으로 오버라이드하면 됩니다.

 

효율적인 레이아웃 설계는 재사용성과 유지보수성을 고려해야 합니다.

예를 들어 블로그 페이지를 만든다면, 기본 레이아웃에 사이드바와 본문 영역을 나누어 정의한 뒤, 실제 페이지에서는 본문 내용만 변경하는 식으로 구성할 수 있습니다.

반응형