웹디자인 (HTML,JS)

Jinja2 템플릿 언어 동작원리 이해와 간단한 웹 화면 구성

날으는물고기 2023. 12. 19. 00:49

우선 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를 사용하여 간단한 웹 페이지를 동적으로 생성하는 예제입니다.

  1. 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)
  2. 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>
  3. 동작 방식 설명
    • Flask 애플리케이션은 /hello/<name> URL에 대한 요청을 처리합니다.
    • 해당 요청은 hello 함수로 전달되고, 함수 내에서는 render_template 함수를 통해 hello.html 템플릿을 렌더링합니다.
    • hello.html 템플릿은 user_name 변수와 items 리스트를 사용하여 동적인 HTML을 생성합니다.
    • 사용자가 '/hello/John'과 같은 URL로 접속하면, "Hello, John!"과 함께 리스트 아이템이 포함된 웹 페이지가 생성됩니다.
  4. 실행 및 결과 확인
    • Flask 애플리케이션을 실행하고 웹 브라우저에서 http://localhost:5000/hello/YourName에 접속하여 결과를 확인합니다.

이 예제에서는 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/로 접속하여 게시판을 확인하고 글을 작성해보세요. 게시글을 클릭하면 상세 내용이 나타나며 조회수가 표시됩니다.

728x90