OpenResty에서의 Lua 템플릿 렌더링 기법

템플릿 기반 동적 페이지 생성

웹 애플리케이션 개발에서 동적 컨텐츠 생성은 핵심 요소입니다. 예를 들어, 상품 정보 페이지처럼 복잡한 데이터 구조를 포함하는 시나리오에서는 템플릿 엔진이 필수적입니다. OpenResty 환경에서는 lua-resty-template라는 고성능 템플릿 엔진을 활용할 수 있으며, 이는 LuaJIT과 함께 사용 시 매우 빠른 렌더링 성능을 제공합니다.

이 템플릿 엔진은 자바 웹 기술인 JSP와 유사하게 작동하며, 최종적으로는 템플릿 코드가 Lua 스크립트로 변환되어 실행됩니다. 이후 ngx.print 또는 ngx.say를 통해 결과를 응답으로 전달합니다.

주요 기능

  • 템플릿 위치 지정: 템플릿 파일의 검색 경로를 설정
  • 변수 출력 및 안전 처리: 일반 출력 또는 HTML 인코딩된 출력 지원
  • 제어 구문: 조건문, 반복문, 함수 호출 등 복잡한 로직 처리
  • 내부 포함: 다른 템플릿을 포함하여 재사용성 확보
  • 비구문 영역: 특정 영역을 해석하지 않고 순수 텍스트로 처리

라이브러리 설치

wget https://github.com/bungle/lua-resty-template/archive/v1.9.tar.gz
tar -xvzf v1.9.tar.gz

압축을 해제한 후 lib/resty/template.lua 파일을 사용하고, template.lua 외 추가 파일들은 /usr/openResty/lualib/resty/ 디렉터리에 복사합니다.

템플릿 위치 설정

템플릿의 위치는 여러 방법으로 정의할 수 있습니다. 우선순위는 다음과 같습니다:

  1. $template_location 변수를 통해 ngx.location.capture로 동적으로 로드
  2. $template_root로 지정된 경로에서 파일 직접 읽기
  3. root 지시어로 지정된 document_root 사용 (권장되지 않음)

예시 구성:

set $template_location "/templates";
set $template_root "/usr/openResty/templates";

location /templates {
    internal;
    alias /usr/openResty/templates2;
}

이 경우 먼저 /usr/openResty/templates2를 확인하고, 없으면 /usr/openResty/templates를 탐색합니다.

템플릿 렌더링 방식

두 가지 주요 렌더링 방식이 존재합니다:

  • template.render(): 즉시 출력
  • template.compile(): 컴파일된 함수를 얻어 후속 처리 가능

예제: 기본 렌더링

local template = require("resty.template")
template.caching(true)

local context = { title = "예제 제목" }
template.render("t1.html", context)

예제: 컴파일 후 출력

local func = template.compile("t1.html")
local output = func(context)
ngx.say(output)

템플릿 문법

템플릿 내에서 다음 문법을 사용할 수 있습니다:

  • {* expression *}: 표현식 평가 및 출력 (안전하지 않음)
  • {{ expression }}: HTML 엔티티 인코딩 후 출력 (안전함)
  • {% code %}: Lua 코드 블록 삽입
  • {# comment #}: 주석 (렌더링 시 제거됨)
  • {-raw-}...{-raw-}: 중간 내용을 무시하고 순수 텍스트로 출력
  • {(include_file)}: 다른 템플릿 포함

실제 템플릿 예시 (t3.html)

<html>
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    이름: {* string.upper(name) *}<br/>
    설명: {{description}}<br/>
    나이: {* age + 1 *}<br/>
    취미:
    {% for i, v in ipairs(hobby) do %}
      {% if i > 1 then %},{% end %}
      {* v *}
    {% end %}<br/>

    점수:
    {% local i = 1; %}
    {% for k, v in pairs(score) do %}
      {% if i > 1 then %},{% end %}
      {* k *} = {* v *}
      {% i = i + 1 %}
    {% end %}<br/>

    점수2:
    {% for i = 1, #score2 do local t = score2[i] %}
      {% if i > 1 then %},{% end %}
      {* t.name *} = {* t.score *}
    {% end %}<br/>

    원본 콘텐츠: {-raw-}{(file)}{-raw-}
  </body>
</html>

서버 구성 예시

location /lua_template_3 {
    default_type 'text/html';
    lua_code_cache on;
    content_by_lua_file /usr/openResty/lua/test_template_3.lua;
}

이 설정을 통해 http://127.0.0.1/lua_template_3에 접근하면 템플릿이 렌더링된 결과를 확인할 수 있습니다.

태그: OpenResty Lua lua-resty-template nginx template rendering

6월 13일 16:50에 게시됨