ď…“
Python - Jinja2
Eueung Mulyana
http://eueung.github.io/python/jinja2
Python CodeLabs | Attribution-ShareAlike CC BY-SA
1 / 27
Agenda
Jinja Basics
Rendering to Files
Jinja + Flask
2 / 27
ď…“ Jinja Basics
3 / 27
Example #1/1-2
HelloJohnDoe!
Myfavoritenumbers:123456789
fromjinja2importTemplate
template=Template('Hello{{name}}!')
printtemplate.render(name='JohnDoe')
t=Template("Myfavoritenumbers:{%forninrange(1,10)%}{{n}}"
printt.render()
<title></title>
<ul>
<li><ahref="abc@gmail.com">abc</a></li>
<li><ahref="123@gmail.com">123</a></li>
</ul>
fromjinja2importTemplate
template=Template('''
<title>{%blocktitle%}{%endblock%}</title>
<ul>
{%foruserinusers-%}
<li><ahref="{{user.url}}">{{user.username}}</a></li>
{%endfor-%}
</ul>''')
printtemplate.render(title='titlestring',users=[{'username'
4 / 27
Example #1/3
<html><head><title>HelloTitle</title></head>
<body>Hello.</body>
</html>
fromjinja2importEnvironment
HTML="""
<html><head><title>{{title}}</title></head>
<body>Hello.</body>
</html>
"""
defprint_html():
printEnvironment().from_string(HTML).render(title='Hello
print_html()
5 / 27
Example #2/1
<html>
<head>
<title>{{title}}</title>
</head>
<body>
Hello.
</body>
</html>
basic-1.html
fromjinja2importEnvironment,FileSystemLoader
THIS_DIR='templates'
defprint_html():
j2_env=Environment(loader=FileSystemLoader(THIS_DIR),trim_blocks=
printj2_env.get_template('basic-1.html').render(
title='HelloTitle'
)
print_html()
<html>
<head>
<title>HelloTitle</title>
</head>
<body>
Hello.
</body>
</html>
6 / 27
Example #2/2
importjinja2
templateLoader=jinja2.FileSystemLoader(searchpath="templates"
templateEnv=jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE="basic-2.html"
template=templateEnv.get_template(TEMPLATE_FILE)
FAVORITES=["chocolates","lunareclipses","rabbits"]
templateVars={"title":"TestExample",
"description":"Asimpleinquiryoffunction."
"favorites":FAVORITES}
printtemplate.render(templateVars)
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="UTF-8"/>
<title>{{title}}</title>
<metaname="description"content="{{description}}"/>
</head>
<body>
<divid="content">
<p>MyFavoriteThings:</p>
<ul>
{%foriteminfavorites-%}
<li>{{item}}</li>
{%endfor-%}
</ul>
</div>
</body>
</html>
basic-2.html
7 / 27
Example #2/2
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="UTF-8"/>
<title>TestExample</title>
<metaname="description"content="Asimpleinquiryoffunction."
</head>
<body>
<divid="content">
<p>MyFavoriteThings:</p>
<ul>
<li>chocolates</li>
<li>lunareclipses</li>
<li>rabbits</li>
</ul>
</div>
</body>
</html>
8 / 27
Example #2/3
basic-3.html
<!DOCTYPEhtml>
<html>
<head>
<metacharset="utf-8"/>
<title>TestJinja2</title>
</head>
<body>
<center>
<h1>HelloJinja2</h1>
<p>BuiltinFilters-{{urls|length}}links</p>
</center>
<olalign="left">
{%setcounter=0-%}
{%forurlinurls-%}
{%setcounter=counter+1-%}
<li><ahref="{{url}}">{{url}}</a>|counterinside:{{counter}}
{%endfor-%}
</ol>
<p>counteroutside:{{counter}}</p>
</body>
</html>
importos
fromjinja2importEnvironment,FileSystemLoader
PATH='.'
TEMPLATE_ENVIRONMENT=Environment(
autoescape=False,
loader=FileSystemLoader(os.path.join(PATH,'templates')),
trim_blocks=False)
defrender_template(template_filename,context):
returnTEMPLATE_ENVIRONMENT.get_template(template_filename
defcreate_index_html():
fname="results/output-basic-3.html"
urls=['http://example.com/1','http://example.com/2',
context={
'urls':urls
}
withopen(fname,'w')asf:
html=render_template('basic-3.html',context)
f.write(html)
create_index_html()
9 / 27
output-basic-3.html
10 / 27
ď…“ Rendering to Files
Based on the Codes by @mjhea0 (Michael Herman/Real Python)
11 / 27
importos
fromjinja2importEnvironment,FileSystemLoader
PATH='.'
TEMPLATE_ENVIRONMENT=Environment(
autoescape=False,
loader=FileSystemLoader(os.path.join(PATH,'templates')),
trim_blocks=False)
defrender_template(template_filename,context):
returnTEMPLATE_ENVIRONMENT.get_template(template_filename).render(context)
defcreate_index_html():
fname="results/output-t-0.html"
my_string="Hello!"
my_list=[0,1,2,3,4,5]
context={
'title':'titlet-0',
'my_string':my_string,
'my_list':my_list
}
withopen(fname,'w')asf:
html=render_template('t-0.html',context)
f.write(html)
create_index_html()
Example t-0
<divclass="container">
<p>Mystring:{{my_string}}</p>
<p>Valuefromthelist:{{my_list[3]}}</p>
<p>Loopthroughthelist:</p>
<ul>
{%forninmy_list%}
<li>{{n}}</li>
{%endfor%}
</ul>
</div>
t-0.html (partial)
12 / 27
output-t-0.html
13 / 27
Example t-1
{%extends"t-layout-1.html"%}
{%blockcontent%}
<h3>Thisisthestartofmychildtemplate</h3>
<br>
<p>Mystring:{{my_string}}</p>
<p>Valuefromthelist:{{my_list[3]}}</p>
<p>Loopthroughthelist:</p>
<ul>
{%forninmy_list%}
<li>{{n}}</li>
{%endfor%}
</ul>
<h3>Thisistheendofmychildtemplate</h3>
{%endblock%}
t-1.html
<divclass="container">
<h2>Thisispartofmybasetemplate</h2>
<br>
{%blockcontent%}{%endblock%}
<br>
<h2>Thisispartofmybasetemplate</h2>
</div>
t-layout-1.html (partial)
14 / 27
output-t-1.html
15 / 27
Example t-2
{%extends"t-layout-2.html"%}
{%blockpage%}Home{%endblock%}
{%blockheading%}
{{super()}}
{%endblock%}
{%blockcontent%}
<h3>Thisisthestartofmychildtemplate</h3>
<br>
<p>Mystring:{{my_string}}</p>
<p>Valuefromthelist:{{my_list[3]}}</p>
<p>Loopthroughthelist:</p>
<ul>
{%forninmy_list%}
<li>{{n}}</li>
{%endfor%}
</ul>
<h3>Thisistheendofmychildtemplate</h3>
{%endblock%}
t-2.html
t-layout-2.html (partial)
<divclass="container">
{%blockheading%}
<h1>{%blockpage%}{%endblock%}-FlaskSuperExample
{%endblock%}
<h2>Thisispartofmybasetemplate</h2>
<br>
{%blockcontent%}{%endblock%}
<br>
<h2>Thisispartofmybasetemplate</h2>
</div>
16 / 27
output-t-2.html
17 / 27
Example t-3
t-3.html
{%extends"t-layout-3.html"%}
{%blocktitle%}{{title}}{%endblock%}
{%blockhead%}
{{super()}}
{%endblock%}
{%blockpage%}{{title}}{%endblock%}
{%blockheading%}{{super()}}{%endblock%}
{%blockcontent%}
<h3>Thisisthestartofmychildtemplate</h3><br><br>
<p>Mystring:{{my_string}}</p>
<p>Valuefromthelist:{{my_list[3]}}</p>
<p>Loopthroughthelist:</p>
<ul>{%forninmy_list%}
<li>{{n}}</li>
{%endfor%}</ul>
<br><p>Samelistwithafilter:{{my_list|join(',')}}</
<h3>Thisistheendofmychildtemplate</h3>
{%blocktrailer%}{{super()}}{%endblock%}
{%endblock%}
t-layout-3.html (partial)
<divclass="container">
{%blockheading%}
<h1>{%blockpage%}{%endblock%}-FlaskSuperExample
{%endblock%}
<h2>Thisispartofmybasetemplate</h2>
<br>
{%blockcontent%}{%endblock%}
<br>
<h2>Thisispartofmybasetemplate</h2>
<br>
<divclass="trailer">
{%blocktrailer%}
Watch!Thiswillbeaddedtomybaseandchildtemplates
<br><br><br>
{%endblock%}
</div>
18 / 27
Example t-3
{%macronav_link(endpoint,name)%}
<li><ahref="#{{endpoint}}">{{name}}</a></li>
{%endmacro%}
t-macro-3.html
t-layout-3.html (partial)
{%from"t-macro-3.html"importnav_linkwithcontext%}
<!DOCTYPEhtml>
...
{%blockhead%}
<title>{%blocktitle%}{%endblock%}-FlaskSuperExample
{%endblock%}
...
<divid="navbar"class="collapsenavbar-collapse">
<ulclass="navnavbar-nav">
{{nav_link('home','Home')}}
{{nav_link('about','About')}}
{{nav_link('contact','ContactUs')}}
<liclass="dropdown">
...</li>
</ul>
</div>
19 / 27
output-t-3.html
20 / 27
ď…“ Jinja + Flask
21 / 27
fromflaskimportFlask,render_template
importdatetime
app=Flask(__name__)
#---------------------------------------------
@app.template_filter()
defdatetimefilter(value,format='%Y/%m/%d%H:%M'):
returnvalue.strftime(format)
app.jinja_env.filters['datetimefilter']=datetimefilter
#---------------------------------------------
@app.route("/")
deftemplate_test():
returnrender_template('f-template.html',my_string="Wheeeee!"
@app.route("/home")
defhome():
returnrender_template('f-template.html',my_string="Foo"
@app.route("/about")
defabout():
returnrender_template('f-template.html',my_string="Bar"
@app.route("/contact")
defcontact():
returnrender_template('f-template.html',my_string="FooBar"
#---------------------------------------------
if__name__=='__main__':
app.run(host='0.0.0.0',debug=True)
Example #4
f-macro.html
{%macronav_link(endpoint,name)%}
{%ifrequest.endpoint.endswith(endpoint)%}
<liclass="active"><ahref="{{url_for(endpoint)}}">{{name}
{%else%}
<li><ahref="{{url_for(endpoint)}}">{{name}}</a></li>
{%endif%}
{%endmacro%}
22 / 27
Example #4
f-template.html
{%extends"f-layout.html"%}
{%blocktitle%}{{title}}{%endblock%}
{%blockhead%}{{super()}}{%endblock%}
{%blockpage%}{{title}}{%endblock%}
{%blockheading%}{{super()}}{%endblock%}
{%blockcontent%}
<h3>Thisisthestartofmychildtemplate</h3>
<br>
<h4>Currentdate/time:{{current_time|datetimefilter}}
<br>
<p>Mystring:{{my_string}}</p>
<p>Valuefromthelist:{{my_list[3]}}</p>
<p>Loopthroughthelist:</p>
<ul>
{%forninmy_list%}
<li>{{n}}</li>
{%endfor%}
</ul>
<br>
<p>Samelistwithafilter:{{my_list|join(',')}}</p>
<h3>Thisistheendofmychildtemplate</h3>
{%blocktrailer%}{{super()}}{%endblock%}
{%endblock%}
23 / 27
http://localhost:5000
24 / 27
http://localhost:5000/about
25 / 27
References
1. Welcome to Jinja2 — Jinja2 Documentation
2. Introduction
3. Tips and Tricks
4. Template Designer
5. Primer on Jinja Templating - Real Python
Other Readings
1. Jinja2 Example | Python Adventures
2. Jinja2 Examples
3. Quickstart Guide to Using Jinja2
26 / 27
ď…“
END
Eueung Mulyana
http://eueung.github.io/python/jinja2
Python CodeLabs | Attribution-ShareAlike CC BY-SA
27 / 27

Python Templating Engine - Intro to Jinja