ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 플라스크(Flask) ; Jinja2 템플릿 엔진 기본문법
    개발/python 2016. 8. 26. 00:50

     플라스크에서는 템플릿을 이용하여 html을 구성한다는 설명을 지난 포스팅에서 했었습니다.

     그렇다면 이 템플릿을 해석하는 템플릿 엔진인 Jinja2의 기본적인 문법에 대해서도 조금 알아야겠다 싶어 포스팅합니다.


     우선 죄송하게도 모든 문법을 다 설명드리지는 못한다는 것을 말씀드립니다. 만일 더 상세한 지식이 필요하신다면 아래쪽의 링크를 걸어둔 Jinja Docs를 참조하시면 좋을 것 같습니다.


    Jinja2 Docs 첫 번째 링크

    Jinja2 Docs 두 번째 링크


     우선 예제 코드를 적어보겠습니다. 단순히 이런식으로 사용된다는 것을 보여주기 위한 예제이므로, 깊게 이해하시기 보다는 이러한 형태를 가지고 있구나라고 생각해 주세요.


    <!DOCTYPE HTML>
    <html lang="en">
    <head>
         <title>My Webpage</title>
    </head>
    <body>
         <ul id="navigation">
              {% for item in navigation %}
              <li><a href="{{ item.href }}">{{ item['caption'] }}</a></li>
              {% endfor}
         <ul>
         <h1>My Webpage</h1>
         {{ a_variable }}
    </body>
    </html>
    


     예제를 보시면 여러가지 형태의 문법들이 있지만 아래 두 가지부터 설명드리겠습니다.


     {{ ... }} : 변수나 표현식의 결과를 출력하는 구분자(delimeter)

     {% ... %} : if문이나 for문 같은 제어문을 할당하는 구분자(delimeter)


     일단 구분자라는 것은 그냥 jinja 템플릿 문법임을 구분하는 용도로 쓰이기 때문에 그런 용어를 쓴다는 정도로 이해하시면 됩니다. 크게는 위 두개를 생각하시면 되고, 아래쪽에 몇 개의 문법들을 소개하겠습니다.


     {{ ... }} 의 형태의 경우, 위 예제에서 보시면 {{ item.href }} 와 {{ item['caption'] }} 의 두가지 형태로 변수를 사용하고 있습니다. 이 둘은 기본적으로 같다고 보시면 됩니다. 다만 차이가 있다면 점(.)으로 접근하는 경우 item 객체 내에서 속성(여기서는 href)을 먼저 찾는데 반해서, 작은 따옴표(')로 접근하는 경우는 객체(여기서는 capture)를 먼저 찾는다는 점입니다.

     조금 더 설명하자면, 만약 item.href 로 접근하는 경우에는 item 객체 내에서 href 라는 속성이 있는지 먼저 확인한 후, 없을 경우 href 라는 객체가 있는지 확인합니다. 반면에 item['href'] 로 접근하는 경우에는 item 객체 내에서 href 라는 객체가 있는지 먼저 확인한 후, 없을 경우에 href 라는 속성이 있는지 확인합니다.


     이제 {% ... %} 의 형태를 확인하기에 앞서 몇 가지를 더 보겠습니다.


     {# ... #} : 주석

     {%- ... %}, {%+ ... %}, {% ... -%} ... : 공백 제거 혹은 유지

     {% raw %} ... {% endraw %} : 이스케이프


     보시면 아시겠지만, 가장 위의 주석의 경우 템플릿을 "주석" 처리하고싶을 때 사용합니다. {# {% ... %} #} 와 같은 식으로 사용하면 됩니다.


     두번째의 "공백 제거 혹은 유지"라고 되어있는 것은 간단히 말해서 trim 기능입니다. 기본적으로 jinja 템플릿 엔진은 템플릿 줄 끝의 개행문자를 제외한 나머지 공백은 그대로 출력합니다. 어떤 템플릿을 작성했던 부분이 공백으로 처리되는 것입니다. 그러나 실제로 보이는 화면에는 이러한 공백을 제외하고싶을 수 있습니다. 이런 경우에 앞뒤에 템플릿 태그 앞뒤에 +나 -를 붙여 +를 붙이면 공백 유지, -를 붙이면 공백 제거의 형태가 되는 것입니다. 이는 템플릿에서 수정하는 방법이고, 애플리케이션에서 설정을 적용하는 방법도 있지만, 이에 대한 내용은 추후 기회가 있으면 설명하도록 하겠습니다.


     마지막으로 "이스케이프"의 경우 우리가 템플릿 형태와 동일한 "텍스트" 를 출력하고자 할 때 사용합니다. {% raw %} 와 {% endraw %} 사이에 이스케이프할 문자들을 넣습니다. 그러나 {{ '{{' }} 와 같이 따옴표로 간단하게 이스케이프 할 수도 있습니다. 작은 문자열의 경우는 이런식으로 사용하는 편이 좋겠죠.


     이제, 간단한 설명을 들었으니 마지막으로 {% ... %} 의 형태중에서 대표적인 제어문인 반복문(for)와 조건문(if)에 대해서 설명하겠습니다.

     우선 for 의 경우 위의 예시 코드에서 보시면 아래와 같이 사용하고 있습니다.



    반복문( for ~ in ... )


    {% for item in navigation %}
    <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
    {% endfor %}
    


     for ~ in 문의 사용법은 파이썬 문법과 동일하다고 생각하시면 편합니다. navigation이라는 리스트의 각 변수(혹은 객체를) item 변수에 담아서 안쪽에서 해당 값을 이용하며 시작시에는 for 종료시에는 endfor를 이용합니다.


    {% for <개별요소> in <리스트> %}
    <실행코드>
    {% endfor %} 
    


     추가적으로 for 구문 안에서는 템플릿 엔진이 제공하는 변수를 사용할 수 있는데, 이는 아래와 같습니다.


    변    수

    설    명

      loop.index

      for 구분이 반복된 횟수(1부터 세기 시작) 

      loop.index0

      for 구문이 반복된 횟수(0부터 세기 시작) 

      loop.first

      반복이 처음일 경우 True, 아닐 경우 False 

      loop.last

      마지막 반복일 경우 True, 아닐 경우 False 

      loop.length

      전체 반복 횟수 

      loop.cycle

      loop.cycle()에서 안에 넣는 인자를 순서대로 전달.

      loop.cycle('1', '2', '3') 처럼 사용하면 반복문이 돌 때마다 순서대로 '1', '2', '3' 을 출력. 


     이외에도 loop.revindex와 loop.revindex0 와 같은 변수도 있는데, 이에 대한 설명이나 예시를 명확하게 찾지 못하여 적지는 않았습니다. 공식 문서를 보면 아마도 남은 반복 횟수를 말하는 것처럼 보입니다. 역시나 loop.revindex 는 1부터 세기 시작하고, revindex0 는 0부터 세기 시작하는 변수입니다.



    제어문( if )


     if 문의 경우는 아래와 같은 형태로 사용합니다. 다른 문법체게와 유사하게 elseif (또는 elif)와 else도 사용 가능합니다. 구조는 아래와 같습니다.


    {% if <조건> %}
        <실행코드>
    {% elif <조건> %}
        <실행코드>
    {% else %}
        <실행코드>
    {% endif %}
    

     구조만 보시면 어렵지 않게 따라하실 수 있겠죠? 그리고 if문의 경우는 다른 구문에서 인라인으로 사용가능합니다.

     예를 들면 아래와 같은 구조로 사용 가능합니다.


    {% <실행코드> if <조건> else <거짓일때 실행코드> %}
    


     실제 값으로 예시를 들어보면 아래처럼 users의 값이 None이 아니면 for 구문을 수행합니다.


    {% for user in users if users %}
        <li>{{ user.username }}</li>
    {% endfor %}
    


     이외에도 많은 문법적 요소들이 있지만, 여기에 모두 설명하기 어렵기도 하고, 제가 모르는 부분도 많기 때문에 여기까지만 적겠습니다.




    댓글

Designed by Tistory.