TIL 220111

Zoey·2022년 1월 11일
0

TIL

목록 보기
2/7

이번에 프로젝트를 진행하면서 jinja2라는 걸 처음 써보게됐다.
너무 초면이라서 공부를 할 겸 벨로그에 적어본다.

jinja2 는 뭘까?

jinja2(이하 jinja)는 파이썬에서 가장 많이 사용되는 템플릿 엔진 중 하나로 Django에서 영감을 얻었지만 현재는 더 강력한 언어로 성장했다! 또한 보안이 중요한 애플리케이션을 위해 샌드박스 실행 및 선택적 자동 이스케이프를 추가한다.

흠 여기까지 봤을 때도 무슨 소리인지 모르겠다.

더 자세히 알아보기 전에~ flask 템플릿 이란 뭘까?

Flask 템플릿 렌더링방법

  • 기본적으로 flask는 애플리케이션 폴더 안에 위치한 templates 서브폴더에서 템플릿을 검색한다
  • 그 곳에 위치한 HTML 파일을 이용하여 렌더링한다.

렌더링이 뭘까 ?
- 변수들을 실제 값으로 바꾸고 최종 응답 문자열을 리턴하는 프로세스

from flask import Flask, render_template

❓템플릿 엔진이 뭔데용❓

  • 서버에서 받아온 데이터를 효과적으로 보여줄 중간 매체
  • 템플릿 엔진을 사용하면 비교적 간략한 표현을 통해 효과적으로 데이터를 가공하여 웹페이지를 보여줄 수 있다.

그래서 템플릿 엔진 왜 쓰나요?
1. 재사용성이 높다
같은 모양에서 데이터만 바뀌는 경우가 많은 웹페이지들이 많은데 한 페이지를 템플릿 엔진으로 만들어놓고 데이터만 바꿔가면서 렌더링해주면 효율적으로 페이지들을 관리할 수 있다!

  1. 유지보수에 용이하다.
    동일한 템플릿을 사용한다는 전제하에 템플릿과 넘겨주는 데이터만 수정하면 된다.
  2. 코드를 간략하게 쓸 수 있다.
    대부분의 템플릿 엔진은 기존의 html에 비해서 간단한 문법을 사용한다.

Jinja2의 기본 문법

사용의 예시

변수

{{ 변수명 }}
  • jinja는 어떤 타입의 변수라도 인식한다 (😮)
  • 이 변수를 템플릿 내에서 파이썬 함수처럼 filter 기능으로 처리하는 방법도 있다. {{ 변수명 | 필터 }}와 같은 식으로 써주면 된다.
<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

{% macro render_comment(comment) %}
	<li>{{ comment }}</li>
{% endmacro %}

<ul>
	{% for comment in comments %}
		{{ render_comment(comment) }}
	{% endfor %}
</ul>

-Jinja2에서는 매크로를 제공한다 ! (wow)
매크로는 파이썬 코드의 함수와 기능적으로 유사

-매크로를 재사용하기 위해서 독립적인 파일에 저장해두고 필요할 때 import하면 된다! 😲

macro import하기
{% import 'macros.html' as macros %}
<ul>
	{% for comment in comments %}
		{{ render_comment(comment) }}
	{% endfor %}
</ul>

include

여러 위치에 반복되어야 하는 템플릿 코드 부분은 별도의 파일에 저장하고 필요한 템플릿을 include하여 불필요한 반복을 줄이자! (완전히 개꿀)

{% include 'common.html' %}

템플릿 상속

웹 사이트 레이아웃의 일관성을 유지하거나, header와 footer를 여러곳에 사용하기 위해서는 템플릿 상속 기능을 사용하면 된다.

  • 부모문서를 만들고, 자식문서가 들어갈 부분에 {% block content %} {% endblock %}라고 작성한다.
  • 자식문서 윗부분에 {% extends 부모문서이름 %}라고 명시한 후 {% block content %}와 {% endblock %}사이에 내용을 작성한다.

예를 들어 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코드 안에서 동적으로 변하게 할 수 있다는 게 아주 매력적인 언어인 것 같당!
열심히 공부해서 코드를 반의반의반으로 줄여보자!!!

profile
한 걸음씩 단단하게 !

0개의 댓글