• 회원가입
  • 로그인
  • 구글아이디로 로그인

[template] Jinja - 템플릿 - 템플릿 상속 ★★★ (Template - Template Inheritance)

목차
  1. 기본 템플릿 (Base Template)
  2. 자식 템플릿 (Child Template)
  3. 슈퍼 블럭 (Super Blocks)
  4. 중접 확장 (Nesting extends)
  5. 명명된 블록 종료 태그 (Named Block End-Tags)
  6. 블록 중첩 및 범위 (Block Nesting and Scope)
  7. 필수 블록 (Required Blocks)
  8. 템플릿 객체 (Template Objects)

 

기본 템플릿 (Base Template)

 

  • 기본템플릿(Base Template)은 base.html 파일명 갖으며 HTML 기본 뼈대를 정의함.
  • 자식템플릿(Child Templates)은 기본템플릿의 빈 블록들을 콘텐츠로 채우는 역할 함.

 


[예제]

 

<!DOCTYPE html>

<html lang="en">

<head>

    {% block head %}

    <link rel="stylesheet" href="style.css" />

    <title>{% block title %}{% endblock %} - My Webpage</title>

    {% endblock %}

</head>

<body>

    <div id="content">{% block content %}{% endblock %}</div>

    <div id="footer">

        {% block footer %}

        &copy; Copyright 2012 by <a href="http://homzzang.com/">홈짱닷컴</a>.

        {% endblock %}

    </div>

</body>

</html>

 


PS. 코드 해설

 

  • 위 예에서 {% block %} 태그는 자식템플릿이 채울 수 있는 4개의 블록을 정의함. block 태그 역할은 자식템플릿이 템플릿의 해당 자리 표시자를 재정의할 수 있음을 템플릿 엔진에 알리는 것뿐임
  • 블록 태그는 if와 같은 다른 블록 안에 있을 수 있지만 if 블록이 실제로 렌더링되는지 여부에 관계없이 항상 실행됨.

 

 

자식 템플릿 (Child Template)

[예제]

 

{% extends "base.html" %}

{% block title %}Index{% endblock %}

{% block head %}

    {{ super() }}

    <style type="text/css">

        .important { color: blue; }

    </style>

{% endblock %}

{% block content %}

    <h1>Index</h1>

    <p class="important">

      Welcome to Homzzang.com

    </p>

{% endblock %}

 


 

1.

  • {% extends %} 부분이 핵심인데, 이는 템플릿 엔진에게 이 템플릿이 다른 템플릿을 확장(=상속)함을 알림. 즉, 템플릿엔진이 이 템플릿 평가 시 먼저 부모 템플릿을 찾음.
  • extends 태그는 템플릿의 첫 번째 태그여야 함. 이 태그 앞에 뭔가 있을 경우 정상적으로 로드 되어 혼란 야기할 수 있음.
  • 이 동작과 이를 활용하는 방법에 대한 자세한 내용은 Null-Default Fallback을 참조. 
  • 또한 블록은 주변 조건이 참인지 거짓인지에 관계없이 항상 채워짐.

 

2.

템플릿의 파일 이름은 템플릿 로더에 좌우됨. 예를 들어, FileSystemLoader 사용하면 파일 이름을 제공하여 다른 템플릿에 접근 가능. 슬래시 사용해 하위 디렉터리의 템플릿에 접근 가능.

 

{% extends "layout/default.html" %}

 

그러나 이 동작은 Jinja를 포함하는 애플리케이션에 따라 달라질 수 있음. 자식 템플릿은 footer 블록을 정의하지 않으므로 부모 템플릿의 값이 대신 사용됨.

 

3.

  • 동일한 템플릿에서 동일한 이름을 가진 여러 개의 {% block %} 태그를 정의할 수 없음. (∵ block 태그가 "양쪽" 방향으로 작동하기 때문임. 즉, block 태그는 자리 표시자 역할 뿐만 아니라 부모의 자리 표시자를 채우는 콘텐츠도 정의함. 템플릿에 비슷한 이름의 {% block %} 태그가 두 개 있는 경우 해당 템플릿의 부모는 블록의 콘텐츠 중 어떤 것을 사용할지 알 수 없음.)
  • 단, self 변수로 해당 블록을 여러 번 호출해 출력 가능.


<title>{% block title %}{% endblock %}</title>

<h1>{{ self.title() }}</h1>

{% block body %}{% endblock %}

 

 

슈퍼 블럭 (Super Blocks)

※ super() 호출하면 부모 블록의 내용을 렌더링 가능.

 

{% block sidebar %}

    <h3>Table Of Contents</h3>

    ...

    {{ super() }}

{% endblock %}

 

 

중접 확장 (Nesting extends)

※ {% extenses %} 수준이 중첩적일 때, 바로 위 부모 템플릿을 건너뛰고 그 보다 상위 템플릿을 상속해야 할 경우 super.super() 같이 체인화.

 

# parent.tmpl

body: {% block body %}Hi from parent.{% endblock %}


# child.tmpl

{% extends "parent.tmpl" %}

{% block body %}Hi from child. {{ super() }}{% endblock %}

{# 렌더링 결과: Hi from child. Hi from parent. #}

 

# grandchild1.tmpl

{% extends "child.tmpl" %}

{% block body %}Hi from grandchild1.{% endblock %}

{# 렌더링 결과: Hi from grandchild1. #}

 

# grandchild2.tmpl

{% extends "child.tmpl" %}

{% block body %}Hi from grandchild2. {{ super.super() }} {% endblock %}

{# 렌더링 결과: Hi from grandchild2. Hi from parent. #}

 


명명된 블록 종료 태그 (Named Block End-Tags)

※ 가독성 ↑

 

{% block sidebar %}

    {% block inner_sidebar %}

        ...

    {% endblock inner_sidebar %}

{% endblock sidebar %}

 

PS. endblock 태그 뒤 이름은 block 태그 뒤 이름과 일치해야 함.

 

블록 중첩 및 범위 (Block Nesting and Scope)

 

1. 

블록은 더 복잡한 레이아웃을 위해 중첩될 수 있음. 그러나 기본적으로 블록은 외부 범위의 변수에 접근 못 함.


{% for item in seq %}

    <li>{% block loop_item %}{{ item }}{% endblock %}</li>

{% endfor %}

 

위 예제 경우, 블록 내에서 item을 사용할 수 없기 때문에 빈 <li> 아이템들을 출력함. 그 이유는 블록이 하위 템플릿으로 대체되면 블록에 정의되지 않았거나 컨텍스트에 전달된 변수가 나타날 수 있기 때문임.

 

2. 

Jinja 2.2부터 블록 선언에 scoped 수정자 추가해 블록을 "scoped"로 설정해 블록에서 외부범위의 변수를 사용 가능할 수 있음을 명시적으로 지정 가능.

 

{% for item in seq %}

    <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li>

{% endfor %}

 

3.

블록을 재정의할 때 scoped 수정자를 제공할 필요가 없음.

 

 

필수 블록 (Required Blocks)

 

1.

블록에 required 수정자 추가 가능함. 블록은 어느 시점에선 재정의되어야 하나, 반드시 직계 하위 템플릿에 의해 재정의될 필요는 없음. required 블록에는 공백과 주석만 포함될 수 있으며 직접 렌더링할 수 없음.

 

page.txt

{% block body required %}{% endblock %}

 

issue.txt

{% extends "page.txt" %}

 

bug_report.txt

{% extends "issue.txt" %}

{% block body %}버스 시연 단계 제공.{% endblock %}

 

page.txt 또는 issue.txt 렌더링하면 body 블록을 재정의 안 해서 TemplateRuntimeError 발생함. bug_report.txt 렌더링은 블록을 재정의하므로 성공함.

 

2.

scoped 수정자와 함께 사용 시 반드시 required 수정자는 scoped 수정자 뒤에 와야 함. (아래는 유효한 몇 가지 예임.)

{% block body scoped %}{% endblock %}

{% block body required %}{% endblock %}

{% block body scoped required %}{% endblock %}

 

 

템플릿 객체 (Template Objects)

 

extends, include, import 는 로드할 템플릿 이름 대신 템플릿 객체 사용 가능함. Python 코드 사용해 템플릿을 먼저 로드하고 이를 렌더링에 전달할 수 있으므로 이는 일부 고급 상황에서 유용할 수 있음.

 

if debug_mode:

    layout = env.get_template("debug_layout.html")

else:

    layout = env.get_template("layout.html")


user_detail = env.get_template("user/detail.html")

return user_detail.render(layout=layout)

 

{% extends layout %}

 

PS. 위 파란색 코드 경우, extends가 문자열 대신 템플릿 객체 변수 이용해 렌더링 함에 주목. 



분류 제목
filters Jinja - select() 필터 - 지정 테스트 통과한 요소만 필터링 (= select필터 = 실렉트필터…
filters Jinja - selectattr() 필터 - 지정 속성에 대한 테스트 통과한 아이템만 필터링 (= sele…
filters Jinja - slice() 필터 - 집합을 지정 개수로 쪼개기 (= slice필터 = 슬라이스필터) ※ 지…
filters Jinja - sort() 필터 ★ - 정렬 (= sort필터 = 소트필터) ※ 오름차순/내림차순
filters Jinja - string() 필터 - 문자열로 변환 (= string필터 = 스트링필터)
filters Jinja - striptags() 필터 ★ - 태그 제거 (= striptags필터 = 스트립태그스필터)
filters Jinja - sum() 필터 - (합계/합산/총합/총계) 구하기 (= sum필터 = 섬필터)
filters Jinja - title() 필터 - 각 단어의 첫글자를 대문자로 나머지는 소문자로 변환. (= title필…
filters Jinja - tojson() 필터 - JSON 문자열로 직렬화 (= tojson필터 = 투제이슨필터)
filters Jinja - truncate() 필터 - 문자열을 지정 길이로 자르기 (= truncate필터 = 트런케이…
filters Jinja - unique() 필터 - 고유 아이템으로 구성된 반복자 반환 (= unique필터 = 유니크필…
filters Jinja - upper() 필터 - 대문자로 변환 (= upper필터 = 어퍼필터) ※ 문자열 전체를 대문…
filters Jinja - urlencode() 필터 - URL 주소나 또는 쿼리에 적합한 문자열로 변환 (= urlen…
filters Jinja - urlize() 필터 ★ - 텍스트 URL을 클릭 가능한 링크로 변환 적용 (= urlize필…
filters Jinja - wordcount() 필터 - 문자열의 단어 개수 세기 (= wordcount필터 = 워드카운…
filters Jinja - wordwrap() 필터 - 문자열을 지정 길이 단위로 쪼개기 (= wordwrap필터 = 워…
filters Jinja - xmlattr() 필터 - dict의 아이템 기반으로 SGML/XML 속성 문자열 생성 (= …
tests Jinja - boolean() 테스트 - boolean 타입인지 체크 (= boolean테스트 = 불리언테…
tests Jinja - callable() 테스트 - 호출 가능한지 체크 (= callable테스트 = 콜러블테스트)
tests Jinja - defined() 테스트 ★ - 변수 정의되었는지 여부 체크 (= defined테스트 = 디파…
6/9
목록
찾아주셔서 감사합니다. Since 2012