Jinja2 템플릿 언어 동작원리 이해와 간단한 웹 화면 구성
우선 Jinja2에 대해 간단하게 설명하겠습니다.
1. Jinja2는 무엇인가요?
Jinja2는 Python에서 사용되는 템플릿 엔진 중 하나입니다. 템플릿 엔진은 정적인 부분과 동적인 데이터를 결합하여 동적인 결과물을 생성하는 도구입니다.
2. 어떤 역할을 하는 건가요?
Jinja2의 주된 역할은 HTML과 같은 문서를 만들 때, 문서의 일부를 동적으로 변환하는 데 있습니다. 정적인 부분은 그대로 두고, 특정 부분을 변경하거나 반복되는 패턴을 생성할 수 있도록 도와줍니다.
3. 어떻게 동작하나요?
Jinja2는 템플릿 안에 삽입된 특별한 문법을 해석하여 동적인 부분을 채워넣습니다. 중괄호({{ }}
) 안에 변수를 넣으면 해당 변수의 값으로 치환되고, 중괄호와 퍼센트({% %}
) 사이에는 제어 구조(반복문, 조건문 등)를 쓸 수 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ page_title }}</title>
</head>
<body>
<h1>Hello, {{ user_name }}!</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
이 템플릿은 page_title
, user_name
, 그리고 items
라는 변수에 의존적입니다. 이 변수들을 템플릿 엔진에 전달하면, 실제 HTML 문서로 변환됩니다.
4. 어떤 상황에서 사용하나요?
Jinja2는 주로 웹 프레임워크인 Flask와 함께 사용됩니다. 웹 애플리케이션에서 동적인 웹 페이지를 생성하거나 데이터를 효과적으로 표시할 때 유용합니다.
간단히 말하면, Jinja2는 개발자가 동적인 웹 페이지를 쉽게 만들 수 있게 도와주는 도구입니다.
Jinja2를 Flask에서 활용하는 샘플
아래는 Flask와 Jinja2를 사용하여 간단한 웹 페이지를 동적으로 생성하는 예제입니다.
- Flask 애플리케이션 설정
from flask import Flask, render_template app = Flask(__name__) @app.route('/hello/<name>') def hello(name): items = ['Item 1', 'Item 2', 'Item 3'] return render_template('hello.html', user_name=name, items=items) if __name__ == '__main__': app.run(debug=True)
- Jinja2 템플릿 (hello.html)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Hello, {{ user_name }}!</title> </head> <body> <h1>Hello, {{ user_name }}!</h1> <ul> {% for item in items %} <li>{{ item }}</li> {% endfor %} </ul> </body> </html>
- 동작 방식 설명
- Flask 애플리케이션은
/hello/<name>
URL에 대한 요청을 처리합니다. - 해당 요청은
hello
함수로 전달되고, 함수 내에서는render_template
함수를 통해hello.html
템플릿을 렌더링합니다. hello.html
템플릿은user_name
변수와items
리스트를 사용하여 동적인 HTML을 생성합니다.- 사용자가 '/hello/John'과 같은 URL로 접속하면, "Hello, John!"과 함께 리스트 아이템이 포함된 웹 페이지가 생성됩니다.
- Flask 애플리케이션은
- 실행 및 결과 확인
- Flask 애플리케이션을 실행하고 웹 브라우저에서
http://localhost:5000/hello/YourName
에 접속하여 결과를 확인합니다.
- Flask 애플리케이션을 실행하고 웹 브라우저에서
이 예제에서는 URL 파라미터를 받아와서 동적으로 웹 페이지를 생성하는 간단한 상황을 시뮬레이션하였습니다. 실제 프로젝트에서는 데이터베이스 쿼리 결과를 가져와서 동적으로 웹 페이지를 구성하는 등 다양한 활용이 가능합니다.
게시판 애플리케이션을 Flask와 SQLite를 사용하여 만들어 보겠습니다. 여러 단계를 거쳐 구현해보겠습니다.
1. Flask 애플리케이션 생성
pip install Flask
# app.py
from flask import Flask, render_template, request, redirect, url_for
import sqlite3
app = Flask(__name__)
app.config['DATABASE'] = 'board.db'
# 데이터베이스 초기화
def init_db():
with app.app_context():
db = get_db()
with app.open_resource('schema.sql', mode='r') as f:
db.cursor().executescript(f.read())
db.commit()
# 데이터베이스 연결
def get_db():
if not hasattr(app, 'db'):
app.db = sqlite3.connect(app.config['DATABASE'])
app.db.row_factory = sqlite3.Row
return app.db
# 데이터베이스 종료
def close_db(e=None):
db = getattr(app, 'db', None)
if db is not None:
db.close()
# 템플릿에서 사용할 함수 등록
app.jinja_env.globals.update(get_db=get_db)
# 애플리케이션 종료 시 데이터베이스 종료
app.teardown_appcontext(close_db)
# 홈페이지 - 글 목록 표시
@app.route('/')
def index():
db = get_db()
cursor = db.execute('SELECT * FROM posts ORDER BY created_at DESC')
posts = cursor.fetchall()
return render_template('index.html', posts=posts)
# 글 작성 폼 표시
@app.route('/write')
def write():
return render_template('write.html')
# 글 작성 처리
@app.route('/write', methods=['POST'])
def write_post():
title = request.form['title']
content = request.form['content']
db = get_db()
db.execute('INSERT INTO posts (title, content) VALUES (?, ?)', (title, content))
db.commit()
return redirect(url_for('index'))
# 글 상세보기
@app.route('/post/<int:post_id>')
def post(post_id):
db = get_db()
cursor = db.execute('SELECT * FROM posts WHERE id = ?', (post_id,))
post = cursor.fetchone()
return render_template('post.html', post=post)
if __name__ == '__main__':
app.run(debug=True)
2. 데이터베이스 스키마 정의
-- schema.sql
DROP TABLE IF EXISTS posts;
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
views INTEGER DEFAULT 0
);
3. 템플릿 생성
- templates/index.html
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>게시판</title>
</head>
<body>
<h1>게시판</h1>
<ul>
{% for post in posts %}
<li><a href="{{ url_for('post', post_id=post['id']) }}">{{ post['title'] }}</a></li>
{% endfor %}
</ul>
<a href="{{ url_for('write') }}">글 작성</a>
</body>
</html>
- templates/write.html
<!-- templates/write.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>글 작성</title>
</head>
<body>
<h1>글 작성</h1>
<form action="{{ url_for('write_post') }}" method="post">
<label for="title">제목:</label>
<input type="text" id="title" name="title" required><br>
<label for="content">내용:</label>
<textarea id="content" name="content" required></textarea><br>
<button type="submit">작성 완료</button>
</form>
<a href="{{ url_for('index') }}">돌아가기</a>
</body>
</html>
- templates/post.html
<!-- templates/post.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ post['title'] }}</title>
</head>
<body>
<h1>{{ post['title'] }}</h1>
<p>{{ post['content'] }}</p>
<p>조회수: {{ post['views'] }}</p>
<a href="{{ url_for('index') }}">목록으로 돌아가기</a>
</body>
</html>
4. 애플리케이션 실행 및 테스트
터미널에서 애플리케이션을 실행합니다.
python app.py
웹 브라우저에서 http://localhost:5000/
로 접속하여 게시판을 확인하고 글을 작성해보세요. 게시글을 클릭하면 상세 내용이 나타나며 조회수가 표시됩니다.