TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 웹개발>

[파이썬] 플라스크(Flask) - 템플릿

by 기록자_Recordian 2024. 7. 14.
728x90
반응형
시작에 앞서
해당 내용은 <가장 빠른 풀스택을 위한 Flask & FastAPI>, Dave Lee 지음. BJ Public 출판.
내용을 토대로 작성되었습니다. 보다 자세한 사항은 해당 교재를 참고하시기 바랍니다.

템플릿

 

템플릿: 웹 페이지의 구조나 레이아웃을 미리 정의해 놓은 파일

 

플라스크에서는 Jinja2(진자2) 라는 템플릿 엔진을 사용하는데, Jinja2는 파이썬 코드를 HTML 파일에 삽입하여 웹페이지를 동적으로 생성할 수 있게 해준다.

 

Jinja2는 Python에서 사용되는 빠르고 표현력 있는 템플릿 엔진이다. 이 엔진은 템플릿 안에 Python과 유사한 문법을 사용하여 코드를 작성할 수 있게 해준다.

 

플라스크 애플리케이션 폴더 내에 templates 라는 디렉터리를 생성하고, 이곳에 HTML 파일을 저장한다.

<!DOCTYPE html>
<html>
<head>
    <title>Hello</title>
</head>
<body>
    <h1>Hello, {{name}}! </h1>
</body>
</html>

▶ HTML 파일에서 {{name}} 부분은 Jinja2의 템플릿 문법이다. 이 위치에 파이썬 변수를 삽입할 수 있다.

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/hello/<name>')
def hello(name):
    return render_template('hello.html', name=name)

위 코드는 http://127.0.0.1:5000/hello/[이름] 형태의 URL을 통해 접속하면 Hello, [이름]! 이라는 응답을 준다.

render_template() 함수는 특정 경로에 해당하는 HTML 파일을 전달해주는 함수이다.


변수와 제어문

 

Jinja2 템플릿 엔진은 단순히 변수를 삽입하는 것뿐만 아니라, 제어문(If, For 등)도 사용할 수 있다.

 

★ 제어문에 대해 궁금하다면?!

[파이썬] 파이썬기초: 제어문 - if문

[파이썬] 파이썬기초: 제어문 - while문
[파이썬] 파이썬기초: 제어문 - for문

 

아래와 같은 방식으로 조건에 따라 다른 내용을 출력할 수 있다.

{% if name %}
	<hi>Hello, {{name}}!</h1>
{% else %}
	<hi>Hello, World!</h1>
{% endif %}

 


필터

 

필터는 변수의 값을 출력하기 전에 처리하여 변형하는 기능을 제공한다.

예. 입력한 문자열을 대문자로 변환, 날짜 형식 변경 등

Jinja2에서는 다양한 내장 필터를 제공하며, 필요에 따라 사용자 정의 필터도 추가할 수 있다.

<p>{{ user_name|capitalize}}</p> <!-- 첫 글자를 대문자로 변환>
-->
<p>{{ story|truncate(100) }}</p> <!-- 문자열을 100자로 제한>
-->
<p>{{ timestamp|date("Y-m-d H:i") }}</p> <!-- 날짜 형식을 지정된 형태로 변환>
-->

 

[필터 옵션]

  • safe: HTML 태그를 이스케이핑 하지 않는다.
  • capitalize: 문자열의 첫 글자를 대문자로 만든다
  • lower: 문자열을 소문자로 만든다
  • upper: 문자열을 대문자로 만든다
  • title: 문자열의 각 단어의 첫 글자를 대문자로 만든다
  • trim: 문자열의 앞뒤 공백을 제거한다
  • striptags: 문자열에서 HTML 태그를 제거한다
  • truncate: 문자열을 특정 길이로 줄인다
  • date: datetime 객체를 문자열로 포맷한다.

※ 이스케이핑:  어떤 문자가 그것에 부여된 특정한 의미, 기능으로 해석되는 게 아니라 그냥 단순한 문자 하나로 해석되도록 하는 것


반복문

 

Jinja2에서는 for 반복문을 사용하여 리스트나 딕셔너리 같은 컬렉션의 요소들을 순회하며 출력할 수 있다.

 

먼저, 단순한 fruits 리스트를 화면에 나열하는 HTML 템플릿을 만들어본다.

templates 디렉터리 안에 fruits_list.html 파일을 생성하고 아래 코드를 입력한다.

<!-- templates/fruits_list.html-->
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset="UTF-8>"
    <title>Fruits List</title>
</head>
<body>
    <h1>Fruits List</h1>
    <ul>
    {% for fruit in fruits %}
        <li>{{ fruit }}</li>
    {% endfor %}
    </ul>
</body>
</html>

 

이제 플라스크 애플리케이션(app.py)에서 fruits_list.html 템플릿을 사용하는 뷰 함수를 만든다.

이 함수에서는 fruits 라는 변수에 과일의 이름이 담긴 리스트를 넣고 템플릿으로 전달한다.

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/fruits')
def show_fruits():
    # 테스트할 과일 목록을 넣는다
    fruits = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry']
    return render_template('fruits_list.html', fruits=fruits)

http://127.0.0.1:5000/fruits 로 접속하면

위에서 정의한 과일 목록이 웹페이지에 나열되어 보인다.


매크로

 

매크로를 사용하는 것은 파이썬에서 함수를 정의하고 호출하는 것과 아주 유사하다.

웹페이지에서 반복해서 사용되는 HTML 요소들을 매크로로 정의해두면, 여러 곳에서 필요할 때마다 그 매크로를 호출하여 재사용할 수 있다.

 

플라스크 프로젝트에서 templates 디렉터리 안에 매크로를 포함한 HTML 파일을 저장한다. (macros.html)

<!-- templates/macors.html-->
{% macro display_message(message) %}
<p>{{ message }}</p>
{% endmacro %}

▶ 여기서 정의된 display_message 매크로는 메시지라는 단 하나의 매개변수를 받아서 단순히 <p> 태그 안에 그 메시지를 출력한다.

 

그리고 templates/messages.html 파일을 만들어 이 매크로를 사용해본다.

<!-- templates/messages.html-->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8>"
    <title>Simple Message Example</title>
</head>
<body>
    {% from "macros.html" import display_message %}
    <!-- 매크로 호출-->
    {{ display_message('환영합니다! 여기가 우리 사이트입니다.') }}
    {{ display_message('주의해 주세요, 에러가 발생했습니다.') }}
    {{ display_message('성공! 당신의 작업이 성공적으로 완료되었습니다.')}}
</body>
</html>

{% from "mcros.html" import display_message %} 구문을 통해 macros.html에서 display_message 매크로를 가져와서 사용한다.

 

마지막으로, 플라스크 애플리케이션에서 이 두 파일을 사용하는 뷰 함수를 만든다.

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/messages')
def show_messages():
    return render_template('messages.html')

 

이제 http://127.0.0.1:5000/messages 로 접속하면

messages.html에 정의된 매크로를 통해 세 가지 타입의 메시지를 표시하는 웹페이지를 볼 수 있다.

 

이 구조를 사용하면 매크로를 한곳에 모아서 관리할 수 있으며, 다른 HTML 템플릿에서 쉽게 재사용할 수 있다.

이는 코드의 중복을 줄이고 유지보수성을 향상시키는 효과적인 방법이다.


템플릿 상속

 

템플릿 상속(template inheritance)을 이용하면 기본 레이아웃을 정의한 '부모' 템플릿을 만들고, 이를 '자식' 템플릿들이 상속받아서 이용할 수 있다.

이 방법은 웹페이지의 일관된 레이아웃을 유지하면서 코드의 반복을 피하고자 할 때 유용하다.

 

[템플릿 상속의 핵심 구성 요소]

  • {% block 블록명 %}: 이 구문은 자식 템플릿에서 재정의 가능한 블록 영역을 설정한다. 블록명은 해당 블록의 고유한 식별자이다
  • {% endblock %}: 이 태그는 블록의 종료를 나타낸다. 각각의 block 선언은 반드시 이 태그로 종결되어야 한다
  • {% extends 파일명 %}: 자식 템플릿에서 이 구문을 사용하여 특정 부모 템플릿을 상속받을 것임을 명시한다

 

[템플릿 구성요소 예시]

먼저 기본 레이아웃을 정의한다. (base.html)

base.html은 다른 HTML 파일이 상속받을 수 있는 템플릿으로, 웹사이트의 기본적인 구조를 정의한다.

<!-- templates/baes.html-->
<!DOCTYPE html>
<html lang='kr'>
<head>
    <!-- 'block'은 자식 템플릿이 재정의할 수 있는 플레이스홀더-->
    <!-- 'pagetitle'은 블록의 이름으로, 이 이름을 가진 블록을 자식 템플릿이 재정의-->
    <title>{% block pagetitle %} 기본 웹사이트 {% endblock pagetitle %}</title>
</head>
<body>
    <header>
        <h1>나의 웹사이트 방문을 환영합니다!</h1>
    </header>

    <!-- 여기서 정의한 'maincontent' 블록은 자식 템플릿에서 내용을 채워 넣기 위한 표시자-->
     {% block maincontent %}
    <!-- 이 부분은 자식 템플릿에서 구체적으로 채워질 내용-->
    <!-- 'maincontent' 블록 안에 내용을 추가하여 기본 레이아웃을 확장-->
        {% endblock maincontent %}

        <footer>
            <p>&copy; 나의 웹사이트</p>
        </footer>
</body>
</html>

 

그리고 개별 내용을 추가하기 위한 자식 템플릿을 만든다. (about.html)

자식 템플릿은 base.html의 레이아웃을 상속받아서 특정 내용을 추가한다.

<!-- templates/about.html-->
<!-- 'extends' 태그를 사용하여 'base.html'을 상속받겠다고 선언-->
<!-- 이는 'about.html'이 'base.html'의 블록을 재정의할 수 있음을 의미-->
{% extends 'base.html' %}

<!-- 'pagetitle' 블록을 재정의하여 이 페이지의 타이틀을 정의-->
<!-- 타이틀은 'About - 나의 웹사이트' 로 설정-->
{% block pagetitle %} About - 나의 웹사이트 {% endblock pagetitle %}

<!-- 'maincontent' 블록을 재정의하여 '우리에 대해서' 섹션 추가-->
{% block maincontent %}
    <h2> 우리에 대해서 </h2>
    <p>이 페이지는 나의 웹사이트에 관한 정보를 제공합니다</p>
{% endblock maincontent %}

 

마지막으로 플라스크에서 템플릿을 랜더링한다.

플라스크 애플리케이션에서는 render_template() 함수를 사용하여 특정 경로에 해당하는 HTML 템플릿을 랜더링한다.

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/about')
def about_page():
    # 'render_template' 함수를 사용하여 'about.html' 템플릿을 랜더링
    # 플라스크는 'about.html'과 함께 이 템플릿이 상속하는 모든 부모 템플릿('base.html')을
    # 랜더링하여 최종 HTML을 생성
    return render_template('about.html')

http://127.0.0.1:5000/about 에 접속하면 about.html 페이지가 표시된다.

▶ about.html은 base.html에 정의된 레이아웃을 기반으로 하되, pagetitle과 maincontent 블록에 about.html에서 정의한 내용이 채워져 있어 페이지별로 고유한 정보를 제공하면서도 일관된 구조를 유지할 수 있다.

 

참고로, pagetitle 부분은 웹페이지 타이틀로 보통 아래와 같이 웹 브라우저 탭에 표시된다.

 

728x90
반응형