Study/Html

[Freemarker 프리마커] FTL (Freemarker Template Language) 문법

LoonyHyun 2020. 12. 11. 01:03
반응형

참조 : freemarker.apache.org/

 

What is Apache FreeMarker™?

Java template engine; generates HTML web pages, e-mails, configuration files, source code, etc. from template files and the data your application provides.

freemarker.apache.org

 

assign

- 프리마커 템플릿에서 변수를 사용하고 싶을 때 사용.

- JSTL 의 set 값과 비슷

<#assign name1=value1 name2=value2 ... nameN=valueN>

<#assign same as above ... in namespacehash>

<#assign name>
	capture this
</#assign>

<#assign name in namespacehash>
	capture this
</#assign>

 

attempt

- 변수 사용 시 오류가 났을 경우 대체 표시 문구 설정

---------------------------------------------
TEMPLATE
---------------------------------------------
Primary content
<#attempt>
  Optional content: ${thisMayFails}
<#recover>
  Ops! The optional content is not available.
</#attempt>
Primary content continued

---------------------------------------------
output : thisMayFails 값이 없을 경우 (not exist)
---------------------------------------------
Primary content
  Ops! The optional content is not available.
Primary content continued

---------------------------------------------
output : thisMayFails 값이 있을 경우 (exist)
---------------------------------------------
Primary content
  Optional content: 123
Primary content continued

 

autosec

- 오토 이스케이핑 기능

- XML 또는 HTML 같은 문서 출력 시, 이스케이핑 처리를 위함

- 변수 하나에 대한 이스케이핑 처리 시 변수 뒤에 esc 를 붙여준다.

  (예) ${expression} 을 이스케이핑 => ${expression?esc}

-----------------------------------------------
TEMPLATE
-----------------------------------------------
<#ftl output_format="XML" auto_esc=false>
${"&"}
<#autoesc>
  ${"&"}
  ...
  ${"&"}
</#autoesc>
${"&"}

-----------------------------------------------
output
-----------------------------------------------
&
  &amp;
  ...
  &amp;
&

 

compress

- 불필요한 공백 문제 제거

-----------------------------------------------
TEMPLATE
-----------------------------------------------
<#assign x = "    moo  \n\n   ">
(<#compress>
  1 2  3   4    5
  ${moo}
  test only

  I said, test only

</#compress>)

-----------------------------------------------
OUTPUT
-----------------------------------------------
(1 2 3 4 5
moo
test only
I said, test only)

 

flush

- 프리마커 템플릿 엔진이 처리한 결과는 output writer 로 전송된다.

- 문제는 템플릿의 매 구문마다 바로바로 output 으로 전송되는 것이 아니라, 성능을 위해서 버퍼링을 하는데에 있다.

- 대부분 이런 버퍼링과 플러쉬는 적당한 때에 자동으로 발생한다.

- 템플릿의 특정 부분에서 명시적으로 플러쉬하고 싶을 때 사용한다.

- java.io.Writer 의 flush() 와 같다.

<#flush>

 

ftl

- 프리마커 템플릿 파일의 제일 첫 부분에서 사용되는 디렉티브

- 템플릿 파일에 대한 정보를 프리마커 엔진에 알려주는 역할

- parameter로 encoding, strip_whitespace, strip_text 등이 있다.

<#ftl param1=value1 param2=value2 ... >

 

function, return

- 템플릿 파일 내부에서 사용할 함수를 정의

------------------------------------------
TEMPLATE
------------------------------------------
<#function avg x y>
  <#return (x + y) / 2>
</#function>
${avg(10, 20)}

------------------------------------------
OUTPUT
------------------------------------------
15


------------------------------------------
TEMPLATE
------------------------------------------
<#function avg nums...>
  <#local sum = 0>
  <#list nums as num>
    <#local sum += num>
  </#list>
  <#if nums?size != 0>
    <#return sum / nums?size>
  </#if>
</#function>
${avg(10, 20)}
${avg(10, 20, 30, 40)}
${avg()!"N/A"}

------------------------------------------
OUTPUT
------------------------------------------
15
25
N/A

 

 

global

- 전역 변수

- assign 디렉티브와 비슷한 역할

- assign 디렉티브는 namespace 에서 보이게 되나, global 디렉티브로 정의한 변수는 모든 namespace 에서 보이게 된다.

- assign 디렉티브와 global 디렉티브 에 동일한 name의 변수일 시 assign 디렉티브에서 정의한 변수가 보이게 된다.

<#global name=value>
or
<#global name1=value1 name2=value2 ... nameN=valueN>
or
<#global name>
  capture this
</#global>

 

if, else, elseif

- 조건문

<#if condition>
  ...
<#elseif condition2>
  ...
<#elseif condition3>
  ...
...
<#else>
  ...
</#if>

 

import

- 다른 템플릿을 현재 템플릿에 추가

<#import path as hash>

- path에 해당하는 템플릿을 불러와 hash 라는 이름의 namespace로 만들어 줌

---------------------------------------
TEMPLATE
----------------------------------------
<#import "/libs/commons.ftl" as com>
<@com.copyright date="1999-2002"/>

 

include

- 다른 템플릿을 현재 템플릿에 추가

- import와 다른점은 include 디렉티브를 이용하면 불러오는 템플릿의 변수와 매크로를 공유

- 같은 namespace 를 가지게 됨

- options 값으로 encoding, parse, ignore_missing 을 설정할 수 있음

<#include path>
or
<#include path options>

 

 

list, else, items, sep, break, continue

- 반복문

- sep = 구분자 : 마지막 항목에서는 자동으로 구분자를 빼준다.

- JSTL 의 foreach 와 비슷

<#list sequence as item>
    Part repeated for each item
</#list>

<#list sequence as item>
    Part repeated for each item
<#else>
    Part executed when there are 0 items
</#list>

<#list sequence>
    Part executed once if we have more than 0 items
    <#items as item>
        Part repeated for each item
    </#items>
    Part executed once if we have more than 0 items
<#else>
    Part executed when there are 0 items
</#list>
--------------------------------
TEMPLATE
--------------------------------
<#list users as user>
  <p>${user}
</#list>
--------------------------------
OUTPUT
--------------------------------
  <p>Joe
  <p>Kate
  <p>Fred

--------------------------------
TEMPLATE
--------------------------------
<#list products as name, price>
  <p>${name}: ${price}
</#list>
--------------------------------
OUTPUT
--------------------------------
  <p>apple: 5
  <p>banan: 10
  <p>kiwi: 15

--------------------------------
TEMPLATE
--------------------------------
<#list users as user>
  <p>${user}
<#else>
  <p>No users
</#list>
--------------------------------
OUTPUT
--------------------------------
  <p>No users

--------------------------------
TEMPLATE
--------------------------------
<#list users>
  <ul>
    <#items as user>
      <li>${user}</li>
    </#items>
  </ul>
</#list>
--------------------------------
OUTPUT
--------------------------------
  <ul>
      <li>Joe</li>
      <li>Kate</li>
      <li>Fred</li>
  </ul>

--------------------------------
TEMPLATE
--------------------------------
<#list 1..10 as x>
  ${x}
  <#if x == 3>
    <#break>
  </#if>
</#list>
--------------------------------
OUTPUT
--------------------------------
  1
  2
  3

--------------------------------
TEMPLATE
--------------------------------
<#list 1..5 as x>
  <#if x == 3>
    <#continue>
  </#if>
  ${x}
</#list>
--------------------------------
OUTPUT
--------------------------------
  1
  2
  4
  5

--------------------------------
TEMPLATE
--------------------------------
<#list users>
  <table>
    <#items as user>
      <tr class="${user?item_parity}Row">
        <td>${user?counter}
        <td>${user}
    </#items>
  </table>
</#list>
--------------------------------
OUTPUT
--------------------------------
  <table>
      <tr class="oddRow">
        <td>1
        <td>Joe
      <tr class="evenRow">
        <td>2
        <td>Kate
      <tr class="oddRow">
        <td>3
        <td>Fred
  </table>

 

local

- assign 디렉티브와 비슷

- macro, function 디렉티브에서만 사용 가능

<#local name=value>
or
<#local name1=value1 name2=value2 ... nameN=valueN>
or
<#local name>
  capture this
</#local>

 

macro, nested, return

- 매크로 변수를 생성

<#macro name param1 param2 ... paramN>
  ...
  <#nested loopvar1, loopvar2, ..., loopvarN>
  ...
  <#return>
  ...
</#macro>
----------------------------------------------
TEMPLATE
----------------------------------------------
<#macro test foo bar baaz>
  Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<#-- call the macro: -->
<@test foo="a" bar="b" baaz=5*5-2/>
----------------------------------------------
OUTPUT
----------------------------------------------
  Test text, and the params: a, b, 23

----------------------------------------------
TEMPLATE
----------------------------------------------
<#macro test foo bar="Bar" baaz=-1>
  Test text, and the params: ${foo}, ${bar}, ${baaz}
</#macro>
<@test foo="a" bar="b" baaz=5*5-2/>
<@test foo="a" bar="b"/>
<@test foo="a" baaz=5*5-2/>
<@test foo="a"/>
----------------------------------------------
OUTPUT
----------------------------------------------
  Test text, and the params: a, b, 23
  Test text, and the params: a, b, -1
  Test text, and the params: a, Bar, 23
  Test text, and the params: a, Bar, -1
  
----------------------------------------------
TEMPLATE
----------------------------------------------
<#macro list title items>
  <p>${title?cap_first}:
  <ul>
    <#list items as x>
      <li>${x?cap_first}
    </#list>
  </ul>
</#macro>
<@list items=["mouse", "elephant", "python"] title="Animals"/>
----------------------------------------------
OUTPUT
----------------------------------------------
  <p>Animals:
  <ul>
      <li>Mouse
      <li>Elephant
      <li>Python
  </ul>

----------------------------------------------
TEMPLATE
----------------------------------------------
<#macro repeat count>
  <#list 1..count as x>
    <#nested x, x/2, x==count>
  </#list>
</#macro>
<@repeat count=4 ; c, halfc, last>
  ${c}. ${halfc}<#if last> Last!</#if>
</@repeat>
----------------------------------------------
OUTPUT
----------------------------------------------
  1. 0.5
  2. 1
  3. 1.5
  4. 2 Last!

----------------------------------------------
TEMPLATE
----------------------------------------------
<#macro test>
  Test text
  <#return>
  Will not be printed.
</#macro>
<@test/>
----------------------------------------------
OUTPUT
----------------------------------------------
  Test text

 

noautosec

- autosec 의 반대

- 오토 이스케이핑 기능을 사용하지 않는 구역

------------------------
TEMPLATE
------------------------
<#ftl output_format="XML">
${"&"}
<#noautoesc>
  ${"&"}
  ...
  ${"&"}
</#noautoesc>
${"&"}
------------------------
OUTPUT
------------------------
&amp;
  &
  ...
  &
&amp;

 

noparse

- 프리마커 언어로 해석하지 않는 구역

--------------------------------------------------------------------------
TEMPLATE
--------------------------------------------------------------------------
<#noparse>
  <#list animals as animal>
  <tr><td>${animal.name}<td>${animal.price} Euros
  </#list>
</#noparse>

--------------------------------------------------------------------------
OUTPUT
--------------------------------------------------------------------------
  <#list animals as animal>
  <tr><td>${animal.name}<td>${animal.price} Euros
  </#list>

 

nt

- No-Trim 약자, 공백 문자를 Stripping 하지 않음

 

outputformat

- 출력 포맷 설정을 변경

----------------------------------------------
TEMPLATE
----------------------------------------------
<#ftl output_format="XML">
XML escaping: ${"&{}"}
<#outputformat "RTF">
  RTF escaping: ${"&{}"}
</#outputformat>
<#outputformat "plainText">
  No escsaping: ${"&{}"}
</#outputformat>
XML escsaping: ${"&{}"}
----------------------------------------------
OUTPUT
----------------------------------------------
XML escsaping: &amp;{}
  RTF escaping: &\{\}
  No escsaping: &{}
XML escsaping: &amp;{}

----------------------------------------------
TEMPLATE
----------------------------------------------
<#ftl output_format="XML">
${"'{}"}
<#outputformat "HTML">
  ${"'{}"}
  <#outputformat "RTF">
    ${"'{}"}
  </#outputformat>
</#outputformat>
----------------------------------------------
OUTPUT
----------------------------------------------
&apos;{}
  &#39;{}
    '\{\}

----------------------------------------------
TEMPLATE
----------------------------------------------
<#ftl outputFormat="XML">
${"'{}"}
<#outputFormat "{HTML}"><#-- Same as "XML{HTML}" -->
  ${"'{}"}
  <#outputFormat '{RTF}'><#-- Same as "XML{HTML{RTF}}" -->
    ${"'{}"}
  </#outputFormat>
</#outputFormat>
----------------------------------------------
OUTPUT
----------------------------------------------
&apos;{}
  &amp;#39;{}
    &amp;#39;\{\}

 

setting

- 이후 프로세싱에 영향을 미칠 설정 값들을 변경

- setting 디렉티브는 프리마커 엔진의 해석 방식에 영향을 주게 된다

- setting 디렉티브에 locale, number_format, boolean_format, date_format 등을 변경하게 되면, 이 후 프리마커 엔진이 데이터를 처리할 때마다 바꾼 설정 값에 따라 해석된다.

<#setting name=value>

 

stop

- 템플릿의 프로세싱을 종료

- 에러메시지를 줄 수도 있으나, 일반적이지 않은 에러 상황에서만 사용

<#stop>
or
<#stop reason>

 

switch, case, default, break

<#switch value>
  <#case refValue1>
    ...
    <#break>
  <#case refValue2>
    ...
    <#break>
  ...
  <#case refValueN>
    ...
    <#break>
  <#default>
    ...
</#switch>
TEMPLATE
--------------------------------------------
<#switch animal.size>
  <#case "small">
     This will be processed if it is small
     <#break>
  <#case "medium">
     This will be processed if it is medium
     <#break>
  <#case "large">
     This will be processed if it is large
     <#break>
  <#default>
     This will be processed if it is neither
</#switch>

 

t, lt, rt

- 공백문자의 Trim 동작에 대한 디렉티브

- t : 앞 뒤 공백문자를 제거

- lt : 왼쪽 공백문자 제거

- rt : 오른쪽 공백문자 제거

---------------------
TEMPLATE
---------------------
  1 <#t>
  2<#t>
  3<#lt>
  4
  5<#rt>
  6
---------------------
OUTPUT
---------------------
1 23
  4
  5  6

 

User-defined directive(<@...>)

- 사용자 정의 디렉티브

- 매크로에서 사용

 

visit, recurse, fallback

- 재귀적인 방법으로 트리를 순회하며 데이터를 처리하고 싶을 때 사용

<#visit node using namespace>
or
<#visit node>
<#recurse node using namespace>
or
<#recurse node>
or
<#recurse using namespace>
or
<#recurse>
<#fallback>
------------------------------------------------------------------
TEMPLATE
------------------------------------------------------------------
<#-- Assume that nodeWithNameX?node_name is "x" -->
<#visit nodeWithNameX>
Done.
<#macro x>
   Now I'm handling a node that has the name "x".
   Just to show how to access this node: this node has ${.node?children?size} children.
</#macro>

------------------------------------------------------------------
OUTPUT
------------------------------------------------------------------
   Now I'm handling a node that has the name "x".
   Just to show how to access this node: this node has 3 children.
Done.
------------------------------------------------------------------
TEMPLATE
------------------------------------------------------------------
<#import "n1.ftl" as n1>
<#import "n2.ftl" as n2>

<#-- This will call n2.x (because there is no n1.x): -->
<#visit nodeWithNameX using [n1, n2]>

<#-- This will call the x of the current namespace: -->
<#visit nodeWithNameX>

<#macro x>
  Simply x
</#macro>


------------------------------------------------------------------
TEMPLATE : n1.ftl
------------------------------------------------------------------
<#macro y>
  n1.y
</#macro>

------------------------------------------------------------------
TEMPLATE : n2.ftl
------------------------------------------------------------------
<#macro x>
  n2.x
  <#-- This callc n1.y as it inherits the "using [n1, n2]" from the pending visit call: -->
  <#visit nodeWithNameY>
  <#-- This will call n2.y: -->
  <#visit nodeWithNameY using .namespace>
</#macro>

<#macro y>
  n2.y
</#macro>


------------------------------------------------------------------
OUTPUT
------------------------------------------------------------------
  n2.x
  n1.y
  n2.y

  Simply x

 

'Study > Html' 카테고리의 다른 글

이미지 회전 Image rotate  (0) 2020.12.09
HTML CSS 우선도  (0) 2020.12.08
HTML 5 TEST (canvas, video, etc)  (0) 2014.03.05