除了技术贴编写体验差外,我觉得学习者很多时候很困惑,却不知道自己到底哪里困惑,我们是否可以根据编程知识的特点,给列个通用的checklist来帮助大家发现自己的问题所在?
比如我就不知道怎么用jinja2,可能我笨,文档我看不懂哈哈,从外网粘贴了篇教程分享给大家。
kagerato.net
A Quickstart Guide to Using the Jinja2 Template Engine
What is Jinja 2 ?
Jinja2 is the second major version of a Python library used to generate documents based on one or more predefined templates.
As to the name, "jinja" is the Japanese word for a Shinto shrine or temple. Temple, template... a clever pun.
API Overview
There are two key objects in the Jinja API: Environment and Template.
Environment objects are used to initialize, store, and configure variables which are significant to template rendering.
Template objects, on the other hand, represent a particular template file and can be used to generate one or more outputs from it.
Beyond these key objects, there is also a secondary set used for reading the template files. These objects are classified as Loaders. The loaders of significance for typical use are FileSystemLoader, PackageLoader, and DictLoader. The three of these read template data from the file system, a Python package, or a Python dictionary, respectively.
Ordinarily, the process one will use to transform a template and its inputs into a rendered output file has four steps.
First, select and construct an appropriate loader object.
Second, create an environment object while specifying that new loader and any other desired options.
Third, use the environment‘s get_template
method to read the template file using the loader, and store the resulting template object.
Fourth and finally, process the template by passing any inputs into the render
method of the template object.
Leading by Example
Listing 1a: sample Python code
# Load the jinja library‘s namespace into the current module.
import jinja2
# In this case, we will load templates off the filesystem.
# This means we must construct a FileSystemLoader object.
#
# The search path can be used to make finding templates by
# relative paths much easier. In this case, we are using
# absolute paths and thus set it to the filesystem root.
templateLoader = jinja2.FileSystemLoader( searchpath="/" )
# An environment provides the data necessary to read and
# parse our templates. We pass in the loader object here.
templateEnv = jinja2.Environment( loader=templateLoader )
# This constant string specifies the template file we will use.
TEMPLATE_FILE = "/home/user/site/example1.jinja"
# Read the template file using the environment object.
# This also constructs our Template object.
template = templateEnv.get_template( TEMPLATE_FILE )
# Specify any input variables to the template as a dictionary.
templateVars = { "title" : "Test Example",
"description" : "A simple inquiry of function." }
# Finally, process the template to produce our final text.
outputText = template.render( templateVars )
Listing 1b: sample Jinja template
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{{ title }}</title>
<meta name="description" content="{{ description }}" />
</head>
<body>
<div id="content">
<p>Why, hello there!</p>
</div>
</body>
</html>
Template Input Variables
Most of what appears above will be familiar to those versed in Python and HTML. The one aspect which is different, and begins to touch on Jinja‘s features, is the template input. It is possible to pass arbitrary strings of text into predefined placeholders in the actual template file itself. Simple variables like this are marked in the template using the {{ variable_name }}
syntax.
As one would imagine, the Python code can determine the contents of these variables at runtime. Further, it can perform multiple separate renderings of the same template with different input variable values. There is no arbitrary limit to the number of inputs which may be specified this way, either. These facts allow for a great deal of flexibility.
In some cases, this simple input substitution will be enough for the user‘s needs. Especially for purists who do not want to mix any kind of logic into the template file itself, it makes sense to do all manner of processing in the Python code and then output it to the template through variables like these.
However, there are those who do not agree with that philosophy. They wish to insert presentation logic into the template, and regard processing HTML or other disparate code in the Python as unwise. Jinja is able to accommodate them.
Template Logic
Let us look at how to incorporate some fundamental logic into a template in order to keep the Python code simple.
Listing 2a: Python rendering code
import jinja2
templateLoader = jinja2.FileSystemLoader( searchpath="/" )
templateEnv = jinja2.Environment( loader=templateLoader )
TEMPLATE_FILE = "/home/user/site/example2.jinja"
template = templateEnv.get_template( TEMPLATE_FILE )
# Here we add a new input variable containing a list.
# Its contents will be expanded in the HTML as a unordered list.
FAVORITES = [ "chocolates", "lunar eclipses", "rabbits" ]
templateVars = { "title" : "Test Example",
"description" : "A simple inquiry of function.",
"favorites" : FAVORITES
}
outputText = template.render( templateVars )
Listing 2b: Jinja template with a loop
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{{ title }}</title>
<meta name="description" content="{{ description }}" />
</head>
<body>
<div id="content">
<p>Greetings visitor! These are a list of my favorite things:</p>
<ul>
{% for item in favorites %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</div>
</body>
</html>
Take note of both the for loop added to the template, and the additional list variable in the Python code. In particular, pay attention to the fact that logic expressions use a {% ... %}
syntax. Using the variable expansion syntax would be a template bug. More implications are discussed below.
Jinja supports a subset of control structures that are very similar to Python. The critical two are if
and for
. Their syntax is similar to Python, only differing in that no colon is required at the end of the statement and that termination of the block is done using an endif
orendfor
instead of by whitespace. Most user needs for presentational logic can be met with just these two elements.
In the above example, a list of strings is iterated over in a very similar manner to how it would be done in Python. A temporary variable, item, will store the current value of an element of the list for each iteration of the loop. In this case, we merely print the item value inside a list item tag.
Of course, one could do the same effective work in the Python code instead. This would involve a series of selective string concatenations with HTML inline. Then the preprocessed output would be written via a template variable. This works, but has a significant issue with structural clarity. It may also be difficult to maintain an exact formatting of whitespace, especially in a complicated template.