render¶
/usr/local/m2/setting.json
다음 영역에 대해 기술한다.
{
"functions": {
"contents": {
"render": {
...
}
}
}
}
How to use¶
명령어 리스트¶
# /templates/banner.html 를 기반으로 이미지를 생성한다.
# 변수는 args로 입력한다.
https://exmple.com/templates/banner.html/render/args/title=this_is_title;desc=this_is_desc
https://exmple.com/templates/banner.html/render/args/code=200
https://exmple.com/templates/banner.html/render/args/id=[1,3,5,7,9];key=ASDDDKKQW9
https://exmple.com/templates/banner.html/render/args/maintext=%ec%a0%9c%eb%aa%a9;subtext=%ec%84%a4%eb%aa%85;id=100
# output 명령어를 이용해 다양한 포맷과 크기로 가공한다.
https://exmple.com/templates/banner.html/render/args/code=200/output/format=pdf
https://exmple.com/templates/banner.html/render/args/code=200/output/format=png;width=1200
명령어 |
파라미터 |
동작 |
---|---|---|
|
문자열 |
URL 인코딩된 문자열 |
|
(하위설정) |
output 설정 |
meta¶
"meta" : {
"enable" : false,
"keyword": "render",
"timeout": 5
}
enable (기본: false)
렌더링 활성화
keyword (기본: render)
렌더링 키워드
timeout (기본: 5초)
렌더링 타임아웃
output¶
출력 형식의 기본 값을 정의한다.
"output" : {
"format" : "jpg",
"width" : "auto",
"height" : "auto",
"quality" : 85,
"scaleFactor" : 1
}
format (기본: jpg)
출력 포맷
jpg
,png
,pdf
,html (debug 용)
를 지원한다.Warning
jpg
포맷 이용시 렌더링 영역 크기가65,500 x 65,500
보다 크다면,png
포맷으로 변경된다.width (기본: auto)
가로 길이
auto
속성(<div style="width: 640px; ...">
)이 명시된 태그를 기반으로 계산한다. 속성이 명확하지 않다면 부정학할 수 있다.{pixel}
640처럼 가로 길이를 고정한다.
height (기본: auto)
세로 길이
auto
태그 렌더링 면적의 높이를 계산한다.{pixel}
480처럼 세로 길이를 고정한다.
quality (기본: 85)
이미지 품질 (1~100).
jpg
포맷에 반응한다.scaleFactor (기본: 1)
픽셀 밀도 (1~3). 해상도가 설정값 배수로 증가한다.
Note
렌더링은 다음 우선순위에 따른다.
클라이언트에 의한
output
명령어 호출template에 정의된
<meta name="m2-render-output">
의 속성output 설정 (기본)
템플릿 제작¶
템플릿(template)은 html
파일 형식의 렌더링 소스이다.
다양한 데이터 참조 방법을 이용해 동적 콘텐츠 제작에 사용된다.
다음은 간단한 400 x 300
해상도의 png
파일을 생성하는 간단한 예제이다.
<!DOCTYPE html>
<html>
<head>
<meta name="m2-render-output" format="png" width="400" height="300">
<style>
p { display: block; margin-top: 1em; margin-bottom: 1em; }
</style>
</head>
<body>
<H1>{{ args.maintext }}</H1>
<H2>{{ args.subtext }}</H2>
</body>
</html>
Warning
템플릿의 모든 리소스는 절대 URL로 기재되어야 정상동작한다. 다음과 같이 이미지를 상대주소로 로딩하면 기술적인 이유로 동작하지 않는다.
<img src="/noimage.jpg">
<img src="//demo.winesoft.co.kr/noimage.jpg">
<img src="https://demo.winesoft.co.kr/no2.jpg" onerror="this.src='//demo.winesoft.co.kr/no2.jpg'">
올바른 표현은 아래와 같다.
<img src="https://demo.winesoft.co.kr/noimage.jpg">
<img src="https://demo.winesoft.co.kr/no2.jpg" onerror="this.src='https://demo.winesoft.co.kr/no2.jpg'">
데이터 참조에는 {{ ... }}
라는 nunjucks 표현이 사용된다.
데이터 참조¶
템플릿에서는 3가지 형태의 데이터 참조가 가능하다.
표현 |
설명 |
---|---|
|
클라이언트 HTTP 요청 |
|
|
|
템플릿에 선언된 백엔드 API 호출의 응답 |
HTTP 요청 {{ req }}
¶
클라이언트가 전송한 HTTP 요청은 다음과 같이 구조화되어 템플릿에서 참조한다.
{
"req": {
"headers": {
"host": "www.example.com:8585",
"if-modified-since": "Mon, 13 Apr 2020 06:41:28 GMT",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36",
"accept-encoding": "gzip"
},
"hostname": "www.example.com",
"httpVersion": "1.1",
"method": "GET",
"path": "/fruits",
"protocol": "http",
"query": {
"model": "apple",
"view": "list"
},
"url": "/fruits?model=apple&view=list",
"xhr": false
}
headers
- 클라이언트 요청헤더 목록hostname
- 요청 호스트 이름httpVersion
- HTTP 버전method
- HTTP 메소드path
- 요청 URL 중 경로 정보protocol
- 프로토콜query
- 쿼리스트링 키/값 리스트url
- 요청 URL 정보xhr
- Ajax에 의한 요청 여부 (true
인 경우 Ajax호출)
클라이언트 입력 {{ args }}
¶
클라이언트가 호출한 HTTP 요청 중
args
의 값을 구조화하여 템플릿에서 참조한다.https://exmple.com/templates/banner.html/render/args/maintext=%ec%a0%9c%eb%aa%a9;subtext=%ec%84%a4%eb%aa%85;id=100
Note
값은 URL 디코딩된다.
{
"args": {
"maintext": "제목",
"subtext": "설명",
"id": 100
}
}
{{ args }}
는 1차원적인 Key/Value 쌍을 제공하는 목적으로 구조화된 데이터 모델을 제공하지는 않는다.
외부 API {{ ext }}
¶
렌더링 시점에 참조해야 할 백엔드 API 서버가 있다면 템플릿 파일에 정의한다.
<!DOCTYPE html>
<html>
<head>
<!-- link 태그는 데이터 참조 후 제거된다. -->
<link ref="external" href="https://myapi.com/info?key={{ args.id }} name="info">
...
</head>
<body>
<H1>{{ ext.info.name }} {{ ext.info.age }}</H1>
<p>{{ ext.info.city }}</p>
</body>
</html>
템플릿을 렌더링 하기 전 <link ref="external" ...>
태그는 모두 전처리/참조되어 {{ ext }}
에 바인딩된다.
위 예제는 아래와 같이 동작한다.
# https://myapi.com/info?key=100 호출 결과
{name:"John", age:31, city:"New York"}
# 호출결과는 ext 하위에 name 속성 값으로 바인딩 된다.
{
"ext": {
"info": {
"name": "John",
"age": 31,
"city": "New York"
}
}
}
# 템플릿의 {{ ext.* }} 표현을 데이터 매핑한다.
<body>
<H1>John 31</H1>
<p>New York</p>
</body>
Note
name
속성이 제공되지 않으면_anon_
이 사용된다.{ "ext": { "_anon_": { ... } } }
같은
name
속성이라면 마지막 선언된<link>
로 덮어씌워진다.
외부 API {{ ext }}
동형/배열 참조¶
args
를 배열로 입력하면 백엔드 API를 여러번 호출한 결과를 배열로 구성한다.
# 클라이언트 호출
https://exmple.com/templates/banner.html/render/args/id=[1,3,5,7,9]
# 템플릿의 API 참조
<link ref="external" href="https://myapi.com/info?key={{ args.id }}" name="info">
# 데이터 참조
https://myapi.com/info?key=1
https://myapi.com/info?key=3
https://myapi.com/info?key=5
https://myapi.com/info?key=7
https://myapi.com/info?key=9
5개의 동일한 결과는 배열로 {{ ext }}
에 바인딩된다.
{
"ext": {
"info": [
{
"name": "John",
"age": 31,
"city": "New York"
},
{
"name": "Jane",
"age": 24,
"city": "Boston"
},
...
]
}
}
템플릿에서 배열 표현으로 참조 가능하다.
<!DOCTYPE html>
<html>
<body>
<ul>
{% for item in ext.info %}
<li>{{ item.name }}</li>
{% endfor %}
</ul>
</body>
</html>
외부 API {{ ext }}
이형 참조¶
서로 다른(=heterogeneous) 백엔드 API를 연동하는 경우 name
속성을 다르게 바인딩한다.
# template - <html><head>
<link ref="external" href="https://myapi.com/info?key={{ args.id }}" name="info">
<link ref="external" href="https://desc.myapi.com/products/{{ args.id }}" name="desc">
# {{ ext }} - 호출 결과는 ext 하위로 name 속성을 통해 바인딩된다.
{
"ext": {
"info": { ... },
"desc": { ... },
}
}
# template
<H1>{{ ext.info.name }} {{ ext.info.age }}</H1>
<p>{{ ext.desc.descriptions }}</p>
nunjucks¶
Nunjucks 는 Flask 에서 사용하는 Jinja2 에 영감을 받은 언어이다.
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber": [
{ "type": "home", "number": "212 555-1234" },
{ "type": "fax", "number": "646 555-4567" }
]
}
Nunjucks 형식으로 다음과 같이 템플릿에서 참조 가능하다.
{{ firstname }}
{{ address.state }}
{{ phoneNumber.0.number }}
조건문, 반복문을 지원한다.
{% if hungry %}
I am hungry
{% elif tired %}
I am tired
{% else %}
I am good!
{% endif %}
<h1>Posts</h1>
<ul>
{% for item in items %}
<li>{{ item.title }}</li>
{% else %}
<li>This would display if the 'item' collection were empty</li>
{% endfor %}
</ul>
Note
더 많은 내용은 https://mozilla.github.io/nunjucks/ 를 참조한다.