Skip to content

Commit 1abef48

Browse files
committed
major update on template engines page
1 parent a6302bb commit 1abef48

File tree

3 files changed

+404
-163
lines changed

3 files changed

+404
-163
lines changed

all.html

Lines changed: 134 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4016,10 +4016,12 @@ <h2>Other frameworks learning checklist</h2>
40164016
</li>
40174017
</ol>
40184018
<h1>Template Engines</h1>
4019-
<p>Template engines process template files, which provide an intermediate format
4020-
between your Python code and a desired output format, such as HTML or PDF.</p>
4019+
<p>Template engines take in tokenized strings and produce rendered strings with
4020+
values in place of the tokens as output. Templates are typically used as
4021+
an intermediate format written by developers to programmatically
4022+
produce one or more desired output formats, commonly HTML, XML or PDF.</p>
40214023
<h2>Why are template engines important?</h2>
4022-
<p>Template engines allow developers to generate a desired content type, such
4024+
<p>Template engines allow developers to generate desired content types, such
40234025
as HTML, while using some of the data and programming constructs such as
40244026
conditionals and for loops to manipulate the output. Template files that are
40254027
created by developers and then processed by the template engine consist of
@@ -4028,89 +4030,171 @@ <h2>Why are template engines important?</h2>
40284030
<div class="highlight"><pre><span class="cp">&lt;!DOCTYPE html&gt;</span>
40294031
<span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">&quot;en&quot;</span><span class="nt">&gt;</span>
40304032
<span class="nt">&lt;head&gt;</span>
4031-
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;Content-Type&quot;</span> <span class="na">content=</span><span class="s">&quot;text/html; charset=UTF-8&quot;</span><span class="nt">&gt;</span>
4032-
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
4033-
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;X-UA-Compatible&quot;</span> <span class="na">content=</span><span class="s">&quot;IE=edge&quot;</span><span class="nt">&gt;</span>
4034-
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;viewport&quot;</span> <span class="na">content=</span><span class="s">&quot;width=device-width, initial-scale=1.0&quot;</span><span class="nt">&gt;</span>
4035-
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;author&quot;</span> <span class="na">content=</span><span class="s">&quot;Matt Makai&quot;</span><span class="nt">&gt;</span>
4036-
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;description&quot;</span> <span class="na">content=</span><span class="s">&quot;Template engines provide programmatic output of formatted content such as HTML, XML or PDF.&quot;</span><span class="nt">&gt;</span>
4037-
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&quot;shortcut icon&quot;</span> <span class="na">href=</span><span class="s">&quot;//static.fullstackpython.com/fsp-fav.png&quot;</span><span class="nt">&gt;</span>
4033+
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;Content-Type&quot;</span> <span class="na">content=</span><span class="s">&quot;text/html; charset=UTF-8&quot;</span><span class="nt">&gt;</span>
4034+
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
4035+
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;X-UA-Compatible&quot;</span> <span class="na">content=</span><span class="s">&quot;IE=edge&quot;</span><span class="nt">&gt;</span>
4036+
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;viewport&quot;</span> <span class="na">content=</span><span class="s">&quot;width=device-width, initial-scale=1.0&quot;</span><span class="nt">&gt;</span>
4037+
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;author&quot;</span> <span class="na">content=</span><span class="s">&quot;Matt Makai&quot;</span><span class="nt">&gt;</span>
4038+
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;description&quot;</span> <span class="na">content=</span><span class="s">&quot;Template engines provide programmatic output of formatted content such as HTML, XML or PDF.&quot;</span><span class="nt">&gt;</span>
4039+
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&quot;shortcut icon&quot;</span> <span class="na">href=</span><span class="s">&quot;//static.fullstackpython.com/fsp-fav.png&quot;</span><span class="nt">&gt;</span>
40384040
</pre></div>
40394041

40404042

4041-
<p>Every one of the HTML lines above is standard for each page on Full Stack Python,
4042-
with the exception of the <code>&lt;meta name="description"...</code> line which provides
4043-
a unique short description of what the individual page contains.</p>
4044-
<p>The <a href="https://github.com/mattmakai/fullstackpython.com/blob/gh-pages/source/theme/templates/base.html">base.html Jinja template</a> used to generate Full Stack Python
4045-
allows every page on the site to have consistent HTML but
4046-
dynamically generate the pieces that need to change between pages when
4047-
the <a href="/static-site-generator.html">static site generator</a> executes. The below
4048-
code from the <code>base.html</code> template shows that the meta description is up to child
4049-
templates to create.</p>
4043+
<p>Every one of the HTML lines above is standard for each page on Full Stack
4044+
Python, with the exception of the <code>&lt;meta name="description"...</code> line which
4045+
provides a unique short description of what the individual page contains.</p>
4046+
<p>The
4047+
<a href="https://github.com/mattmakai/fullstackpython.com/blob/gh-pages/source/theme/templates/base.html">base.html Jinja template</a>
4048+
used to generate Full Stack Python allows every page on the site to have
4049+
consistent HTML but dynamically generate the pieces that need to change
4050+
between pages when the <a href="/static-site-generator.html">static site generator</a>
4051+
executes. The below code from the <code>base.html</code> template shows that the meta
4052+
description is up to child templates to generate.</p>
40504053
<div class="highlight"><pre><span class="cp">&lt;!DOCTYPE html&gt;</span>
40514054
<span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">&quot;en&quot;</span><span class="nt">&gt;</span>
40524055
<span class="nt">&lt;head&gt;</span>
4053-
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;Content-Type&quot;</span> <span class="na">content=</span><span class="s">&quot;text/html; charset=UTF-8&quot;</span><span class="nt">&gt;</span>
4054-
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
4055-
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;X-UA-Compatible&quot;</span> <span class="na">content=</span><span class="s">&quot;IE=edge&quot;</span><span class="nt">&gt;</span>
4056-
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;viewport&quot;</span> <span class="na">content=</span><span class="s">&quot;width=device-width, initial-scale=1.0&quot;</span><span class="nt">&gt;</span>
4057-
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;author&quot;</span> <span class="na">content=</span><span class="s">&quot;Matt Makai&quot;</span><span class="nt">&gt;</span>
4058-
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">meta_header</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
4059-
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&quot;shortcut icon&quot;</span> <span class="na">href=</span><span class="s">&quot;//static.fullstackpython.com/fsp-fav.png&quot;</span><span class="nt">&gt;</span>
4056+
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;Content-Type&quot;</span> <span class="na">content=</span><span class="s">&quot;text/html; charset=UTF-8&quot;</span><span class="nt">&gt;</span>
4057+
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
4058+
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">&quot;X-UA-Compatible&quot;</span> <span class="na">content=</span><span class="s">&quot;IE=edge&quot;</span><span class="nt">&gt;</span>
4059+
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;viewport&quot;</span> <span class="na">content=</span><span class="s">&quot;width=device-width, initial-scale=1.0&quot;</span><span class="nt">&gt;</span>
4060+
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">&quot;author&quot;</span> <span class="na">content=</span><span class="s">&quot;Matt Makai&quot;</span><span class="nt">&gt;</span>
4061+
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">meta_header</span> <span class="cp">%}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
4062+
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&quot;shortcut icon&quot;</span> <span class="na">href=</span><span class="s">&quot;//static.fullstackpython.com/fsp-fav.png&quot;</span><span class="nt">&gt;</span>
40604063
</pre></div>
40614064

40624065

4063-
<p>In a typical <a href="/wsgi-servers.html">WSGI application</a>, the template engine would
4064-
generate the HTML output response when an HTTP request comes in for a
4066+
<p>In a typical <a href="/wsgi-servers.html">WSGI application</a>, the template engine
4067+
would generate the HTML output response when an HTTP request comes in for a
40654068
particular URL. </p>
40664069
<h2>Python template engines</h2>
4067-
<p>There are several popular Python template engines. A template engine implementation
4068-
will fall somewhere on the spectrum between allowing arbitrary code execution and
4069-
granting only a limited set of capabilities via template tags. A rough visual of
4070-
the code in template spectrum can be seen below for four of the major Python
4071-
template engines.</p>
4070+
<p>There are several popular Python template engines. A template engine
4071+
implementation will fall somewhere on the spectrum between allowing
4072+
arbitrary code execution and granting only a limited set of capabilities
4073+
via template tags. A rough visual of the code in template spectrum can be
4074+
seen below for four of the major Python template engines.</p>
40724075
<p><img src="/img/template-logic-spectrum.png" width="100%" alt="Spectrum between no logic in templates and the ability to run arbitrary code." class="technical-diagram" style="border-radius: 5px;"></p>
4073-
<h3>Jinja</h3>
4074-
<p><a href="http://jinja.pocoo.org/">Jinja</a>, also known as "Jinja2", is a popular Python
4075-
template engine written as an independent open source project, unlike some
4076-
template engines that are provided as part of a larger web framework.</p>
4076+
<h3>Jinja (Jinja2)</h3>
4077+
<p><a href="/jinja2.html">Jinja</a>, also known and referred to as "Jinja2", is a popular
4078+
Python template engine written as a self-contained open source project. Some
4079+
template engines, such as <a href="/django-templates.html">Django templates</a> are
4080+
provided as part of a larger <a href="/web-frameworks.html">web framework</a>, which
4081+
can make them difficult to reuse in projects outside their coupled library.</p>
40774082
<p>Major Python open source applications such as the
40784083
<a href="/configuration-management.html">configuration management</a> tools Ansible
40794084
and <a href="https://github.com/saltstack/salt">SaltStack</a>
4080-
as well as the <a href="/static-site-generator.html">static site generator</a> Pelican use
4081-
the Jinja template engine by default for generating output files.</p>
4082-
<p>There's a whole lot more to learn about Jinja on the <a href="/jinja2.html">Jinja2</a> page.</p>
4085+
as well as the <a href="/static-site-generator.html">static site generator</a> Pelican
4086+
use the Jinja template engine by default for generating output files.</p>
4087+
<p>There is a whole lot more to learn about Jinja on the
4088+
<a href="/jinja2.html">Jinja2 page</a>.</p>
40834089
<h3>Django templating</h3>
40844090
<p>Django comes with its
40854091
<a href="https://docs.djangoproject.com/en/dev/topics/templates/">own template engine</a>
40864092
in addition to supporting (as of Django 1.9) drop-in replacement with other
40874093
template engines such as Jinja.</p>
40884094
<h3>Mako</h3>
4089-
<p><a href="http://www.makotemplates.org/">Mako</a> is the default templating engine for
4090-
the <a href="/pyramid.html">Pyramid web framework</a> and has wide support as a replacement
4095+
<p><a href="/mako.html">Mako</a> is the default templating engine for the
4096+
<a href="/pyramid.html">Pyramid web framework</a> and has wide support as a replacement
40914097
template engine for many <a href="/other-web-frameworks.html">other web frameworks</a>.</p>
4098+
<h3>Other Python template engine implementations</h3>
4099+
<p>There are numerous Python template engine implementations that range from
4100+
weekend hacks to actively developed mature libraries. These template
4101+
engines are listed alphabetically:</p>
4102+
<ul>
4103+
<li>
4104+
<p><a href="https://chameleon.readthedocs.io/en/latest/">Chameleon</a></p>
4105+
</li>
4106+
<li>
4107+
<p><a href="https://pythonhosted.org/Cheetah/">Cheetah</a></p>
4108+
</li>
4109+
<li>
4110+
<p><a href="http://docs.diazo.org/en/latest/">Diazo</a></p>
4111+
</li>
4112+
<li>
4113+
<p><a href="https://pypi.python.org/pypi/evoque/">evoque</a></p>
4114+
</li>
4115+
<li>
4116+
<p><a href="https://genshi.edgewall.org/">Genshi</a></p>
4117+
</li>
4118+
<li>
4119+
<p><a href="https://github.com/breily/juno">Juno</a></p>
4120+
</li>
4121+
<li>
4122+
<p><a href="https://pythonhosted.org/Myghty/whatsitdo.html">Myghty</a></p>
4123+
</li>
4124+
<li>
4125+
<p><a href="https://pypi.python.org/pypi/pyratemp/0.3.2">pyratemp</a></p>
4126+
</li>
4127+
<li>
4128+
<p><a href="https://www.owlfish.com/software/simpleTAL/">SimpleTAL</a></p>
4129+
</li>
4130+
</ul>
4131+
<h3>Template engine implementation comparisons</h3>
4132+
<p>There are many Python template engine implementations in addition to the
4133+
ones listed above. These resources can help you select a Python template
4134+
engine implementation that works well for your project.</p>
4135+
<ul>
4136+
<li>
4137+
<p><a href="https://ivanteoh.com/posts/188-python-web-templating-battle/">Python Web Templating Battle</a>
4138+
compares and contrasts Django templates, Chameleon, Jinja, Diazo
4139+
and Mako, with examples for each engine.</p>
4140+
</li>
4141+
<li>
4142+
<p>This
4143+
<a href="http://www.simple-is-better.org/template/index.html">template engines site</a>
4144+
contains a range of information from what templates engines are to listing
4145+
more esoteric Python template engines.</p>
4146+
</li>
4147+
<li>
4148+
<p><a href="http://lucumr.pocoo.org/2008/1/1/python-template-engine-comparison/">Python Template Engine Comparison</a>
4149+
is an older but still relevant post by the creator of
4150+
<a href="/jinja2.html">Jinja</a> that explains why and how he switches between Mako,
4151+
Jinja and Genshi for various projects he works on. </p>
4152+
</li>
4153+
<li>
4154+
<p><a href="https://www.quora.com/Python-Web-Frameworks/Python-Web-Frameworks-What-are-the-advantages-and-disadvantages-of-using-Mako-vs-Jinja2">Python Web Frameworks: What are the advantages and disadvantages of using Mako vs. Jinja2?</a>
4155+
has some good answers from developers on Quora about using Mako compared
4156+
with Jinja2.</p>
4157+
</li>
4158+
</ul>
40924159
<h3>Template engine resources</h3>
4160+
<p>Template engines are often used with web frameworks a black box where input
4161+
goes in, and rendered text magically appears out the other side. However,
4162+
when something unexpected returns from a template engine it is useful to
4163+
know how they work to aid your debugging. The following resources examine
4164+
existing template engine design as well as how to build your own engine
4165+
when that's necessary for your projects.</p>
40934166
<ul>
40944167
<li>
4168+
<p><a href="https://fengsp.github.io/blog/2016/8/how-a-template-engine-works/">How a template engine works</a>
4169+
uses the template module in Tornado as an example to step through how
4170+
a template engine produces output, from parsing the incoming string to
4171+
rendering the final output.</p>
4172+
</li>
4173+
<li>
40954174
<p><a href="http://aosabook.org/en/500L/a-template-engine.html">A template engine in 500 lines or less</a>
40964175
is an article by <a href="http://nedbatchelder.com/">Ned Batchelder</a> provides a<br />
40974176
template engine in 252 lines of Python that can be used to understand how
40984177
template engines work under the cover.</p>
40994178
</li>
41004179
<li>
4101-
<p><a href="https://realpython.com/blog/python/primer-on-jinja-templating/">A Primer on Jinja Templating</a>
4102-
shows how to use the major parts of this fantastic template engine.</p>
4103-
</li>
4104-
<li>
41054180
<p><a href="http://agiliq.com/blog/2015/08/template-fragment-caching-gotchas/">Template fragment gotchas</a>
41064181
is a collection of situations that can trip up a developer or designer when
41074182
working with templates.</p>
41084183
</li>
41094184
<li>
4110-
<p>This
4111-
<a href="http://www.simple-is-better.org/template/index.html">template engines site</a>
4112-
contains a range of information from what templates engines are to listing
4113-
more esoteric Python template engines.</p>
4185+
<p><a href="https://makina-corpus.com/blog/metier/2016/the-worlds-simplest-python-template-engine">The world's simplest Python template engine</a>
4186+
shows how the <code>format()</code> function can implement a simple template engine
4187+
with conditionals, loops and method invocations.</p>
4188+
</li>
4189+
<li>
4190+
<p><a href="http://stackoverflow.com/questions/1030622/when-to-use-a-templating-engine-in-python">When to use a Templating Engine (in Python)?</a>
4191+
is a Stack Overflow question with a useful answer on why and when to
4192+
use an existing template engine.</p>
4193+
</li>
4194+
<li>
4195+
<p><a href="http://interactivepython.org/runestone/static/webfundamentals/Frameworks/templates.html">Template Engines</a>
4196+
uses Jinja as an implementation example to explain the tasks that
4197+
template engines can be used to perform.</p>
41144198
</li>
41154199
</ul>
41164200
<h1>Jinja2</h1>

0 commit comments

Comments
 (0)