SSR을 이용하는 Django, Flask, Spring 프레임워크들을 사용해보면서 HTML 템플릿 엔진은 정말 편한 것 같다. 개발의 생산성도 높여주고 무엇보다 개발자의 수고로움을 확 줄여주기 때문에 대부분의 사람들이 사용하나 보다.
jinja2는 HTML 템플릿 엔진이다. Flask를 설치하면 같이 설치되어서 따로 설치를 안 해줘도 된다.
참고
파이참 Preferences(Settings)에 Languages & Frameworks의 Template Language를 jinja2로 설정해주면 자동완성과 highliting 기능을 사용할 수 있다.
Owlbot Dictionary API를 사용하려고 하는데 이를 사용하기 위해서는 Token을 받아야 한다. 사이트에서 Get a token 버튼을 누르면 입력한 이메일로 Token 번호가 온다.
@app.route('/detail/<keyword>')
def detail(keyword):
r = requests.get(f"https://owlbot.info/api/v4/dictionary/{keyword}", headers={"Authorization": "Token [이메일로 받은 토큰]"})
result = r.json()
print(result)
return render_template("detail.html", word=keyword)
예를 들어 url에 /detail/apple 이라는 주소로 요청이 보내지면 apple이라는 문자열이 word 변수에 담겨 detail.html로 보낸다.
detail.html은 word 변수를 사용하기 위해서
<h2>받은 단어는 {{ word }}</h2>
{{ 변수 }} 이런 식으로 사용한다.
만약에 html에서 jinja2 템플릿 엔진으로 조건문이나 반복문을 사용하고 싶다면
{% set test = [1, 2, 3, 4, 5] %}
{% for t in test %}
{% if word == "hi" %}
<h2>{{ t }}</h2>
{% endif %}
{% endfor %}
이런 식으로 사용하면 된다. 연산은 {{ }} 대신에 {% %}을 사용한다.
for나 if가 끝나면 endfor, endif 이렇게 표시한다.
localhost:5000/detail/hi
jinja2 템플릿 엔진을 사용할 때 {{ }} 안에 변수 다음에 파이프(|) 기호가 올 수 있다. 필터를 사용할 때 이 파이프 기호로 구분한다.
변수 필터에는 여러 가지가 있는데 그 중 몇 가지는 아래와 같다.
safe : 자동 이스케이프가 활성화된 환경에서 이 변수가 이스케이프 되지 않는다.
이스케이프 - 예를 들어 < 를 &l t; 로 변환시켜 HTML로 못 읽게 하는 것
capitalize : 첫 번째 문자는 대문자이고 나머지는 모두 소문자
lower : 소문자로 변환
upper : 대문자로 변환
title : 값의 각 단어들을 capitalize 한다.
trim : 기본적으로 공백 문자를 제거한다.
striptags : SGML/XML, HTML 태그를 제거하고 인접한 공백을 하나의 공백으로 바꾼다.
이외 필터는 공식 문서 참고
회색 글씨를 보면 특수문자로 깨져 있는 것을 볼 수 있다.
{{ 변수.encode('ascii', 'ignore').decode('utf-8')|safe }}
ASCII로 인코딩하는데 ASCII로 인코딩할 수 없는 애들은 무시하고, 그 후에 다시 utf-8로 디코딩하는 코드다. 이를 사용하면 깨진 특수문자가 사라진다.
일단 DTL(Django Template Language)이랑 크게 다르다고 느껴지지 않아서 어색하지 않았다. 물론 다른 프레임워크에서 HTML 템플릿 엔진을 사용해봤다면 크게 어려움이 없을 것이라고 생각한다. 그리고 중복 되는 코드도 줄어든 거 같다. HTML에서 연산 작업을 할 수 있다는 게 얼마나 행복한지... 😌
url에 localhost:5000/detail/hi?status_give=new
이렇게 ?key=value 형태로 되어 있을 때 key의 value 값을 불러와 변수에 저장하고 싶을 때가 있다. 이럴 때는 request.args.get()을 사용하면 된다.
localhost:5000/detail/hi?status_give=new 이런 요청이 왔을 때
status_receive = request.args.get("status_give")
이 코드를 사용하게 되면 new(문자열)라는 value가 status_receive 변수에 담기게 된다.