이번에 프로젝트를 진행하면서 jinja2라는 걸 처음 써보게됐다.
너무 초면이라서 공부를 할 겸 벨로그에 적어본다.
jinja2(이하 jinja)는 파이썬에서 가장 많이 사용되는 템플릿 엔진 중 하나로 Django에서 영감을 얻었지만 현재는 더 강력한 언어로 성장했다! 또한 보안이 중요한 애플리케이션을 위해 샌드박스 실행 및 선택적 자동 이스케이프를 추가한다.
흠 여기까지 봤을 때도 무슨 소리인지 모르겠다.
더 자세히 알아보기 전에~ flask 템플릿 이란 뭘까?
렌더링
이 뭘까 ?
- 변수들을 실제 값으로 바꾸고 최종 응답 문자열을 리턴하는 프로세스
from flask import Flask, render_template
❓템플릿 엔진이 뭔데용❓
그래서 템플릿 엔진 왜 쓰나요?
1. 재사용성이 높다
같은 모양에서 데이터만 바뀌는 경우가 많은 웹페이지들이 많은데 한 페이지를 템플릿 엔진으로 만들어놓고 데이터만 바꿔가면서 렌더링해주면 효율적으로 페이지들을 관리할 수 있다!
사용의 예시
{{ 변수명 }}
<h1> Hello, {{ name|capitalize }}</h1>
<!-- name 변수의 첫 문자를 대문자로 하는 필터-->
변수에서 사용하는 필터
safe: 이스케이프를 적용하지 않고 값 렌더링
capitalize: 값의 첫 번째 문자를 대문자로 만들고 나머지는 소문자
lower, upper: 값을 소문자/대문자로
title: 값의 각 단어들을 대문자화
trim: 앞 뒷 부분에 공백 문자 제거
striptags: 렌더링 전 값에 존재하고 있는 HTML 태그 제거
{% if문 %} 괄호 안에 조건문을 써주고, {% endif %}로 마무리하면 된다. 예를 들면 이렇게.
{% if template_variable == "Hello" %}
<p>{{ template_variable }}, World!</p>
{% endif %}
elif와 else도 파이썬에서 직접 사용하는 것과 같은 문법으로 사용할 수 있다.
{% if template_variable < 20 %}
<p>{{ template_variable }}은 20보다 작다.</p>
{% elif template_variable > 20 %}
<p>{{ template_variable }}은 20보다 크다.</p>
{% else %}
<p>{{ template_variable }}은 20이다.</p>
{% endif %}
{% for문 %} 괄호 안에 반목문을 써주고, {% endfor %}로 마무리하면 된다. 예를 들면 이렇게.
<ul>
{% for x in range(10) %}
<li>{{ x }}</li>
{% endfor%}
</ul>
딕셔너리도 당근 활용 가능!
<ul>
{% for key, value in template_dict.items() %}
<li>{{ key }} : {{ value }}</li>
{% endfor%}
</ul>
dictsort 필터를 사용할 때는 (뒤에 굳이 .items()를 붙여주지 말고) 이런 식으로 써야한다.
<ul>
{% for key, value in template_dict | dictsort %}
<li>{{ key }} : {{ value }}</li>
{% endfor%}
</ul>
{% macro render_comment(comment) %}
<li>{{ comment }}</li>
{% endmacro %}
<ul>
{% for comment in comments %}
{{ render_comment(comment) }}
{% endfor %}
</ul>
-Jinja2에서는 매크로를 제공한다 ! (wow)
매크로는 파이썬 코드의 함수와 기능적으로 유사
-매크로를 재사용하기 위해서 독립적인 파일에 저장해두고 필요할 때 import하면 된다! 😲
{% import 'macros.html' as macros %}
<ul>
{% for comment in comments %}
{{ render_comment(comment) }}
{% endfor %}
</ul>
여러 위치에 반복되어야 하는 템플릿 코드 부분은 별도의 파일에 저장하고 필요한 템플릿을 include하여 불필요한 반복을 줄이자! (완전히 개꿀)
{% include 'common.html' %}
웹 사이트 레이아웃의 일관성을 유지하거나, header와 footer를 여러곳에 사용하기 위해서는 템플릿 상속 기능을 사용하면 된다.
예를 들어 base.html이라는 부모문서를 이렇게 작성하고
<html>
<head>
<title>내 웹사이트</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
예를 들어 index.html이라는 이름으로 자식 문서를 만들면) 자식문서에는 이렇게 적어준다.
{% extends "base.html" %}
{% block content %}
<p>자식문서에 포함될 내용</p>
{% endblock %}
!! 블록 안 내용을 새로 정의하고 싶다면? !!
==> 베이스 템플릿에 기존 내용이 존재하기 때문에 원래 내용을 유지하기 위해 super()를 사용
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
<p> want food </p>
{% endblock %}
실제로 index.html이라는 문서를 render_template("index.html")와 같이 렌더링 해서 확인하면 아래와 같이 구성이 된다.
<html>
<head>
<title>내 웹사이트</title>
</head>
<body>
<p>자식문서에 포함될 내용</p>
</body>
</html>
jinja2는 html코드 안에서 동적으로 변하게 할 수 있다는 게 아주 매력적인 언어인 것 같당!
열심히 공부해서 코드를 반의반의반으로 줄여보자!!!