์ผ๋ถ ํ๋ก์ ํธ์์ C ์ฝ๋๋ฅผ ๋ด๋ณด๋ด๋ ๋ฐ ์ฌ์ฉํ StringTemplate ์์ง์์ ๊ณต๋ฐฑ ์ ๋์ฌ๊ฐ ์ถ๋ ฅ ๋ผ์ธ์ ์๋์ผ๋ก ์ถ๊ฐ๋ฉ๋๋ค.
PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
if (someRuntimeFlag) {
<linesGlobal>
if (anotherRuntimeFlag) {
<linesLocal>
}
}
}
>>
์ด ํ ํ๋ฆฟ์ด StringTemplate์์ ๋ ๋๋ง๋๋ฉด ์ฌ๋ฌ ์ค๋ก ๋ linesGlobal ๋ฐ linesLocal ๋ฌธ์์ด์ ์ ๋์ฌ ๊ณต๋ฐฑ์ด ๋ฐฉ์ถ๋๋ ๋ชจ๋ ์ค์ ๋ณต์ฌ๋ฉ๋๋ค. ์์ฑ๋ C ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
void foo() {
if (someRuntimeFlag) {
int i;
i=1; // <=== whitespace prefix copied in 2nd
i++; // <=== and 3rd line
if (anotherRuntimeFlag) {
int j=i;
j++; // <=== ditto
}
}
}
์ ๋ Jinja2๋ฅผ ์ฒ์ ์ ํ๊ณ ์ด๊ฒ์ ๋ณต์ ํ๋ ค๊ณ ํ์ต๋๋ค.
#!/usr/bin/env python
from jinja2 import Template
linesGlobal='\n'.join(['int i;', 'i=1;'])
linesLocal='\n'.join(['int j=i;', 'j++;'])
tmpl = Template(u'''\
void foo() {
if (someRuntimeFlag) {
{{linesGlobal}}
if (anotherRuntimeFlag) {
{{linesLocal}}
}
}
}
''')
print tmpl.render(
linesGlobal=linesGlobal,
linesLocal=linesLocal)
...ํ์ง๋ง ๋ค์์ ์์ฑํ๋ ๊ฒ์ ๋ณด์์ต๋๋ค.
void foo() {
if (someRuntimeFlag) {
int i;
i=1;
if (anotherRuntimeFlag) {
int j=i;
j++;
}
}
}
...๋ด๊ฐ ์ํ๋ ๊ฒ์ด ์๋๋๋ค. ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ ํ ๊ณต๋ฐฑ ์ ๋์ฌ๋ฅผ ์ถ๋ ฅํ๋๋ก ๊ด๋ฆฌํ์ต๋๋ค.
...
if (someRuntimeFlag) {
{{linesGlobal|indent(8)}}
if (anotherRuntimeFlag) {
{{linesLocal|indent(12)}}
}
}
...ํ์ง๋ง ์ด๊ฒ์ ๋ด๊ฐ ๋ฐฉ์ถํ๋ ๋ชจ๋ ๋ฌธ์์ด์ ๋ํด ๊ณต๋ฐฑ์ ์๋์ผ๋ก ๊ณ์ฐํด์ผ ํ๊ธฐ ๋๋ฌธ์ ํ๋ฆผ์์ด ๋์ฉ๋๋ค...
๋ด๊ฐ ๋๋ฝ ๋ ๋ ์ข์ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ๊ฒ์ ๊ด์ฌ์ด ์์ต๋๋ค. ์ด ๋ฌธ์ ๋ stackoverflow์์๋ ๋ฐ์ํ์ต๋๋ค. http://stackoverflow.com/questions/10821539/jinja-keep-indentation-on-include-or-macro
+1
๋ค์ ํ์์ ์ฌ์ฉํ ๋๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.
{{linesGlobal|join('\n')}}
์ด ํ์์ ์์๋๋ก ์๋ํ์ง ์์ต๋๋ค. jinja2๊ฐ ๊ฐํ ๋ฌธ์๋ฅผ ๋ด๋ณด๋ด๋ ํ์์ด๊ธฐ ๋๋ฌธ์ ๋ง์ง๋ง ๋ค์ฌ์ฐ๊ธฐ ์์ค๊ณผ ์ ๋ ฌ๋ ์ํ๋ฅผ ์ ์งํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ ์์ผ๋ฉด ๋งค์ฐ ์ข์ ๊ฒ์ ๋๋ค! ํจ์ฌ ๋ ๋ฉ์ง ํ ํ๋ฆฟ๊ณผ ๋ ๋๋ง๋ ์ถ๋ ฅ์ ๋์์ ๋ง๋ค ์ ์์ต๋๋ค.
ํ๊ฐ ๋์์ ํ์ฌ ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ์ถ๊ฐํ๋ {%+ ๋ฐ {%-์ ์ ์ฌํ ๋ค๋ฅธ ๊ณต๋ฐฑ ์ต์ ์ ์์ฑํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? {%= ๋๋ {%|์ผ ์ ์์ต๋๋ค.
+1
+1
API ์ฒญ์ฌ์ง ๋ฌธ์๋ฅผ ํ ํ๋ฆฟํํ๋ ค๋ฉด ์ฌ๊ธฐ์ ํ์ํฉ๋๋ค.
{% macro entity_one() -%}
{
"one": 1,
"two": 2
}
{% endmacro -%}
+ Response 200 (application/json):
{
"entity": [
{{ entity_one() }}
]
}
์ง๊ธ ๋ ๋๋ง๋ฉ๋๋ค:
+ Response 200 (application/json):
{
"entity": [
{
"one": 1,
"two": 2
}
]
}
YAML ๋๋ Python์ ๋ด๋ณด๋ผ ๋ ์ด๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
ํฌํจ๋ ๋ชจ๋ tempkate์ ๋ํด ๋งคํฌ๋ก๋ฅผ ์ ์ํ๊ณ ์๋์ผ๋ก ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ์ ๋ ฅํ๋ ๊ฒ ์ธ์ ํ์ฌ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
์ด ์ค๋๋ ๋ฌธ์ ๋ฅผ ๋์ด๋ ค์ ์ฃ์กํฉ๋๋ค. ๋ฐฉ๊ธ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ ์ธํฐ๋ท ๊ฒ์์ ํตํด ์ฌ๊ธฐ๋ก ์์ต๋๋ค. ์ข ๋ ๋๋ฌ๋ณธ ํ ๋ค์ฌ์ฐ๊ธฐ ํํฐ๋ฅผ ํตํด ์ด๋ฅผ ๋ฌ์ฑํ ์ ์๋ ์ข์ ๋ฐฉ๋ฒ์ด ์๋ค๋ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค.
@kaikuchn ๊ณ ๋ง์, ์น๊ตฌ! ํจ๊ณผ๊ฐ์๋ค.
@kaikuchn , @Cigizmoond-Vyhuholev ์ฌ๋ฌ๋ถ, ์ ๊ฐ ํ๋ก์ฐํ๊ณ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค... ๋งจ ์์ ์๋ ์ ์๋ ๋ณด๊ณ ์์์ ๋ณผ ์ ์๋ฏ์ด indent
ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ธ๊ธํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ด ๋ช
ํํ๊ฒ ๋ช
์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด StringTemplate์ด ํ๋ ๊ฒ์ฒ๋ผ ๊ฐ๋จํ๊ณ ๊ฐ๋ ฅํ ๋ฐฉ์์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ง ์์ต๋๋ค. ํ ๋ธ๋ก์ ํ์ ๋ด๋ณด๋ด์ผ ํ ๋๋ง๋ค ๋ค์ฌ์ฐ๊ธฐ ๊ณต๋ฐฑ์ ๊ณ์ฐํด์ผ ํ๊ธฐ ๋๋ฌธ์
๋๋ค... ๊ทธ๋ ๊ฒ ํด์ผ ํ๊ณ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ ์ด๋ค ํ์(C, Python ๋ฑ)์ด๋ ๊ฐ์ ํ๋ก์ธ์ค๋ฅผ ์์ ํ ํฌ๊ธฐํ๊ฒ ๋ ๊ฒ์
๋๋ค.
๊ทธ๋ฐ ๋ค์ ๋ค์, ๋๋ ๋น์ ์ด ์๋ฏธํ๋ ๋ฐ๋ฅผ ์๋ชป ์ดํดํ์ ์ ์์ต๋๋ค ... ์๋จ์ ํ์๋ ์๋ ์๊ตฌ ์ฌํญ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ ํํ ๊ณต์ ํ ์ ์์ต๋๊น? ์ฆ, Jinja2 ๊ตฌ๋ฌธ์ผ๋ก ๋์ผํ ์ข ๋ฅ์ ์ถ๋ ฅ์ ์์ฑํฉ๋๊น? ์ด๊ฑด ๋ด๊ฐ ์ซ๋ค...
if (someRuntimeFlag) {
{{linesGlobal|indent(8)}}
if (anotherRuntimeFlag) {
{{linesLocal|indent(12)}}
}
}
...์ฝ๋๋ฅผ ๋ด๋ณด๋ด๋ ๋ชจ๋ ํ ํ๋ฆฟ์์ "8"๊ณผ "12"๋ฅผ ๊ณ์ฐํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด์ ๋นํด StringTemplate์์๋...
PrintCFunction(linesGlobal, linesLocal) ::= <<
void foo() {
if (someRuntimeFlag) {
<linesGlobal>
if (anotherRuntimeFlag) {
<linesLocal>
}
}
}
>>
๋ถ๋ช ํ PR์ ์ผ๋ถ ์ฃผ์ ๋ฆฌํฉํ ๋ง์ด ํ์ํ ์ฝ๋ ๋ณ๊ฒฝ์ผ๋ก ์ธํด #919๊ฐ ๋ซํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ ๋ ์ด ๊ธฐ๋ฅ์ด ์ ๊ฐ ๊ฐ์ฅ ์ข์ํ๋ ํ ํ๋ฆฟ ์์ง์์ ๊ตฌํ๋๋ ๊ฒ์ ๋ณด๊ณ ์ถ์ต๋๋ค.
์ด๊ฒ์ด ์ฌ์ ํ ํต์ฌ ๊ฐ๋ฐ์๊ฐ ๊ตฌํ๋๊ธฐ๋ฅผ ๋ฐ๋ผ๋ ๊ฒ์ด๋ผ๋ฉด(์ปค๋ฎค๋ํฐ๋ ์ด๊ฒ์ด PR์ด๊ณ ๊ฐ์ฅ ๋ง์ ์์ง์๊ฐ๋ฝ์ ์น์ผ๋ ๊ณต๊ฐ ๋ฌธ์ ์ด๊ธฐ ๋๋ฌธ์ ํ์คํ ๊ทธ๊ฒ์ ์ํฉ๋๋ค) ์ ๋ ๊ธฐ๊บผ์ด ๋์์ ๋๋ฆฌ๊ณ ์ ํ๊ณ ์๋ง๋ ์ด๊ฒ์ ์ค์ค๋ก ๊ตฌํํ๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค.
์ด ๊ธฐ๋ฅ๋ ๋ณด๊ณ ์ถ์ต๋๋ค. ๋ค์ฌ์ฐ๊ธฐ ์์ค์ ์ ์ ์๋ ๊ฒฝ์ฐ indent
ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์:
{{field.type}} {{field.name}}; {{field.comment|indent(??)}}
๋ณด์กดํ ๋ค์ฌ์ฐ๊ธฐ ์์ค์ ์ฒ์ ๋ ๊ฐ์ ๊ธธ์ด์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค.
ํ ๊ฐ์ง ๊ฐ์ค์ด ์์ต๋๋ค. ๋ธ๋ก ์ ์ธ์์ ์ผ์ชฝ ํธ๋ฆฌ๋ฐ 1๋จ๊ณ ๋ค์ฌ์ฐ๊ธฐ๋ ์ด๋ป์ต๋๊น?
์์:
{%- macro some_yaml_block(sub_block) ~%}
label indented with how many spaces: 2
amount of spaces that will be trimmed due to that "~" char above: 2
{%- if sub_block ~%}
"yay! we can indent ifs!": true
the minimal indent in this if block is 2, so:
this extra-indented value is still indented properly
{%- endif %}
{%- endmacro -%}
now we invoke that here:
{{ some_yaml_block(true) }}
๋ ๋๋ง์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
now we invoke that here:
label indented with how many spaces: 2
amount of spaces that will be trimmed due to that "~" char above: 2
"yay! we can indent ifs!": true
the minimal indent in this if block is 2, so:
this extra-indented value is still indented properly
๊ธฐ๋ณธ์ ์ผ๋ก ~%}
๋ธ๋ก์ ์๋ฃํ ๋ Jinja๋ ๋ค์์ ์ํํฉ๋๋ค.
newline_sequence
ํ๊ฒฝ ๋งค๊ฐ๋ณ์์ ํ์๋ ๋๋ก EOL ์ํ์ค์ธ ๊ฒฝ์ฐ ์ฒซ ๋ฒ์งธ ๋ฌธ์๋ฅผ ์ ๊ฑฐํฉ๋๋ค.๋์ค์ ํน์ ๋ค์ฌ์ฐ๊ธฐ์ ํจ๊ป ์ด ๋ธ๋ก์ ํฌํจํด์ผ ํ๋ ๊ฒฝ์ฐ some_yaml_block|indent
์ ๊ฐ์ด ํธ์ถํ๊ธฐ
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
YAML ๋๋ Python์ ๋ด๋ณด๋ผ ๋ ์ด๊ฒ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.