Mustache는 제어 구조를 갖춘 것 중 (아마도) 가장 문법이 간단하고 (아마도) 가장 많은 언어로 포팅된 템플릿 엔진입니다. Mustache를 기반으로 이를 확장한 템플릿 엔진도 여럿 있는데 대표적으로는 헬퍼 개념을 추가한 Handlebars와 트위터에서 만든 Hogan.js를 들 수 있습니다.
이 문서는 Mustache 공식 문서를 기준으로 작성되었으며 예제도 해당 문서에서 가져왔습니다. 많은 스펙 문서가 그렇듯 Mustache의 템플릿 문법 문서에도 빈 부분이 많습니다. 스펙에는 없지만 구현체를 보고 동작을 '짐작'할 수 있는 부분에 대한 설명은 따로 소제목에 밑줄로 표기해두었습니다. 해당 영역에 있는 내용은 구현체마다 달라질 수 있으므로 사용 전에 확인이 필요합니다.
변수
{{
와 }}
사이에 변수 이름을 입력합니다. 문자열은 자동으로 HTML 이스케이프가 되어 출력되는데 만약 이스케이프 되지 않은 문자열을 출력하고 싶다면 {{{
와 }}}
를 사용합니다. 참고로 Mustache는 구분자로 사용하는 {, }
기호가 콧수염 모양이라서 붙인 이름입니다. 🙂
데이터
{
"name" : "Chris",
"company" : "<b>Github</b>"
}
템플릿
* {{name}}
* {{age}}
* {{company}}
* {{{company}}}
결과
* Chris
*
* <b>Github</b>
* <b>Github</b>
두 번째 줄의 {{age}}
는 age
가 없는 변수이므로 아무런 값도 출력되지 않습니다. 네 번째 줄에서는 콧수염 세 개를 사용했기 때문에 HTML이 이스케이프 되지 않고 그대로 출력됩니다. 출력 결과를 웹 브라우저에서 보았다면 네 번째 줄은 굵은 글씨로 표시될 것입니다.
더 복잡한 객체 속성에 접근할 때
그러면 객체 안에 또 객체가 포함된 복잡한 객체에서 여러 단계를 거쳐야 하는 때는 어떻게 해야할까요? 예를 들어 앞에서 다룬 객체를 조금 확장한 다음과 같은 객체가 있다고 생각해봅시다.
{
"name" : "Chris",
"company" : {
"name" : "Github",
"address" : {
"country" : "USA"
}
}
}
여기서 회사가 있는 국가에 접근할 때는 다음과 같이 자바스크립트의 점 문법(dot-syntax)를 사용합니다.
Country : {{company.address.country}}
위 템플릿 코드의 출력 결과는 다음과 같습니다.
Country : USA
섹션
섹션section 문법은 조건문이나 반복문 대신 사용됩니다. 주어진 값에 따라 조건문이나 반복문으로 사용되는데 {{#변수명}}
으로 시작하고 {{/변수명}}
으로 끝납니다. 변수가 배열이면 반복문으로 그렇지 않으면 조건문으로 사용되는데 0, false, 빈 문자열
은 거짓으로 평가되므로 섹션의 내용이 출력되지 않습니다.
조건문
변수의 값이 배열이 아니면 조건문으로 사용됩니다. 단, 배열이라 하더라도 빈 배열은 거짓 조건문과 마찬가지로 취급되어 섹션의 내용이 출력되지 않습니다. 다음은 false
또는 비슷한 값을 변수로 사용했을 때의 결과입니다.
데이터
{
"person" : false
}
템플릿
출력됩니다.
{{#person}}
출력안됩니다.
{{/person}}
결과
출력됩니다.
변수가 객체라면 다음과 같이 사용할 수 있습니다.
데이터
{
"person" : {"name" : "Jon"}
}
템플릿
{{#person}}
{{name}}
{{/person}}
결과
Jon
보다시피 섹션 안에서는 섹션 변수의 속성을 마치 변수처럼 사용할 수 있습니다.
섹션 내에서 다른 루트 변수에 접근할 때
위 코드를 보면 {{#person}}
섹션 안에서는 {{name}}
을 통해 person.name
에 접근했습니다. 그런데 person
과 같은 수준에 있는 다른 변수가 있고 이 변수에 접근하고 싶다면 어떻게 해야할까요? 다음과 같은 객체가 있다고 생각해봅시다.
{
"person" : {"name" : "Jon"},
"company" : {"name" : "Google"}
}
템플릿은 다음과 같이 작성했습니다.
{{#person}}
{{name}}의 회사는 {{???}}입니다.
{{/person}}
위 템플릿이 회사 이름으로 "Google"을 출력하려면 {{???}}
대신 {{company.name}}
을 사용하면 됩니다. 템플릿 코드로 나타내면 다음과 같습니다.
{{#person}}
{{name}}의 회사는 {{company.name}}입니다.
{{/person}}
하지만 Mustache의 확장 구현체인 Handlebars에서는 다음과 같이 사용하므로 주의가 필요합니다.
{{#person}}
{{name}}의 회사는 {{../company.name}}입니다.
{{/person}}
반복문
변수의 값이 배열이면 반복문이 됩니다. 앞에서 말했듯이 빈 배열은 거짓 조건문으로 취급됩니다.
데이터
{
"repo" : [
{ "name" : "resque" },
{ "name" : "hub" },
{ "name" : "rip" }
]
}
템플릿
{{#repo}}
<b>{{name}}</b>
{{/repo}}
출력
<b>resque</b>
<b>hub</b>
<b>rip</b>
반전 섹션
섹션과 반대되는 조건에서만 출력되는 블럭입니다. 즉, 섹션에 사용된 없는 변수이거나 변수의 값이 false
또는 이와 비슷한 값(0, 빈 문자열)이거나 빈 배열일 때만 출력됩니다. 반전 섹션은 {{^변수}}
로 시작하고 {{/변수}}
로 끝납니다.
데이터
{
"repo": []
}
템플릿
{{#repo}}
<b>{{name}}</b>
{{/repo}}
{{^repo}}
저장소가 없네요. -_-
{{/repo}}
출력
저장소가 없네요. -_-
주석
템플릿 코드에는 존재하지만 화면에는 출력되지 않는 코드를 작성할 때 사용합니다. 주석은 {{! 주석 }}
과 같이 작성합니다. 다음과 같은 템플릿이 있다고 생각해봅시다.
<h1>Today{{! 여기는 안 나옵니다. }}</h1>
위 코드는 다음과 같이 출력됩니다.
<h1>Today</h1>
부분템플릿
부분템플릿(Partials)은 외부 파일을 템플릿의 일부로 불러올 수 있는 기능으로서 {{> 파일이름}}
과 같이 사용합니다. 다음은 base라는 템플릿 파일에서 user라는 부분템플릿을 불러오는 예제입니다.
base.mustache 파일:
<h2>Names</h2>
{{#names}}
{{> user}}
{{/names}}
user.mustache 파일:
<strong>{{name}}</strong>
위 코드는 사실 다음과 같은 하나의 템플릿 코드로 봐도 무방합니다.
<h2>Names</h2>
{{#names}}
<strong>{{name}}</strong>
{{/names}}
템플릿 파일의 확장자는 구현체에 따라 달라질 수 있습니다.
구분자 설정
템플릿 태그를 시작하는 {{
와 }}
를 다른 구분자로 바꿀 수 있습니다. 구분자를 변경할 때는 {{=여는구분자 닫는구분자=}}
와 같이 사용합니다. 다음은 구분자를 일시적으로 <% %>
로 변경했다가 다시 {{ }}
로 바꾸는 템플릿 코드입니다.
* {{default_tags}}
{{=<% %>=}}
* <% ERB_스타일_태그 %>
<%={{ }}=%>
* {{ 원래_템플릿_코드 }}
위 템플릿 코드는 두 번째 줄({{=<% %>>=}}
)과 네 번째 줄(<%={{ }}=%>)에서 구분자를 각각 <% %>
와 {{ }}
로 바꾸고 있습니다. TeX처럼 중괄호 두 개가 특수한 의미를 가지는 템플릿을 다룰 때 유용하다고 합니다.
간단하고 좋네요 앵귤러도 이문법을쓰던데
설명감사합니다.!!