If you have read the previous chapter, then you should have completed sufficient preparations and created a very simple web application with the following file structure:
microblog
| -flask folder
|-<Some virtual environment files>
| -app folder
| | -static folder
| | -templates folder
| | -__ init__.py file
| | -views.py file
| -tmp folder
| -run.py file
Dear, want to run this program? Then run this run.py file, and then open the address http: // localhost: 5000 in your browser.
In the following chapters, we will continue to develop our applications from the end of the previous chapter, so you must ensure that your environment has been installed correctly and your applications can run normally.
Why do we need to use a template system
Let's consider how we can expand our applet next.
We want to implement a very basic function in the Weibo application, displaying a title that welcomes the logged-in user on the home page. Ignore the situation that there are no users in the current application.
To display a beautiful and elegant title, the easiest way is to change the way we provide the view to display some HTML code, it is better to look like this: \
from app import app
@ app.route ('/')
@ app.route ('/ index')
def index ():
user = {'nickname': 'Miguel'} # fake user
return '' '
<html>
<head>
<title> Home Page </ title>
</ head>
<body>
<h1> Hello, '' '+ user [' nickname '] +' '' </ h1>
</ body>
</ html>
Now, refresh it in your browser to see if it is cool?
Because our small program also supports user functions, we used a user placeholder object, which is often called affectionate data or test data. It allows us to focus on the parts of the program that need to be resolved urgently.
Finished, let's face it, I hope you will find the above small program mixed with html code quite disgusting. Think about it, if you use a complex HTML page generated by some dynamic content, and want to change some page content in a website composed of such a program, this will be a very painful thing.
Template system saves the world
If you keep the separation of business logic and performance, your website structure will be better organized. Don't believe it, if you complete the business code with python, you can even ask a website designer to help you complete the rest. The template system is to help you achieve separation of business and performance.
Let's complete the first template (fileapp / templates / index.html):
<html>
<head>
<title> {{title}}-microblog </ title>
</ head>
<body>
<h1> Hello, {{user.nickname}}! </ h1>
</ body>
</ html>
As you can see, we just wrote a normal HTML page, the only difference from HTML is that it is mixed with some dynamic content placeholders composed of {{...}}
Now let's see how this template is handled in the view function (fileapp / views.py):
from flask import render_template
from app import app
@ app.route ('/')
@ app.route ('/ index')
def index ():
user = {'nickname': 'Miguel'} # fake user
return render_template ("index.html",
title = 'Home',
user = user)
The point of testing this program is to see how the template system works. You can compare the difference between the rendered HTML page source code and the template file source code in the browser.
In the above program, we imported a new function called render_template from the Flask framework and used this function to render the template. And give this function the template file name and some variables as parameters. It replaces the imported variables with placeholders in the template and returns the rendered template.
Let us understand a little deeper. At the bottom of Flask, the render_template function actually calls a component of Flask: the Jinja2 template processing engine. It is Jinjia2 that replaces the corresponding {{...}} code block in the template with the imported variables.
Flow control in templates
The Jinja2 template system also supports flow control statements. Let ’s try adding an if flow control statement (fileapp / templates / index.html) to the template:
<html>
<head>
{% if title%}
<title> {{title}}-microblog </ title>
{% else%}
<title> Welcome to microblog </ title>
{% endif%}
</ head>
<body>
<h1> Hello, {{user.nickname}}! </ h1>
</ body>
</ html>
Now our template file is a bit smart. If we forget to define the page title variable title in the view function, it will use its own title instead. Try to cancel the title variable in render_template in the view function and see how this if flow statement works.
Use loops in templates
Maybe the user wants to display the latest articles written by his friends on his homepage, which is a bit like everyone, or Sina Weibo like friends, then we will look at how to complete this function.
First, create users and articles (fileapp / views.py):
def index ():
user = {'nickname': 'Miguel'} # fake user
posts = [# fake array of posts
{
'author': {'nickname': 'John'},
'body': 'Beautiful day in Portland!'
},
{
'author': {'nickname': 'Susan'},
'body': 'The Avengers movie was so cool!'
}
]
return render_template ("index.html",
title = 'Home',
user = user,
posts = posts)
Arrays are used to store user articles. Each array element is a dictionary. As shown in the code above, the keys of this dict are author and body, which are used to store the article author and article content. When we decided to use a database to store this information, the key of this dictionary can be invisible as a field of the table. Here, in order to show you the use of the template, we did not use database-related technologies, simply use the dictionary and array to simulate the user and his Articles recently posted by friends of.
Our template file now has a new problem. We have just created content data that contains user articles. This array may contain any number of articles. How can the template automatically render the content based on the number of this array.
To solve this problem, you need a new flow control statement: for loop. Let's add the for loop to the template file (fileapp / templates / index.html)
<html>
<head>
{% if title%}
<title> {{title}}-microblog </ title>
{% else%}
<title> microblog </ title>
{% endif%}
</ head>
<body>
<h1> Hi, {{user.nickname}}! </ h1>
{% for post in posts%}
<p> {{post.author.nickname}} says: {{post.body}} </ p>
{% endfor%}
</ body>
</ html>
Very simple, you can also add more content to the array to see the effect.
Template inheritance
Next, we need to add a navigation menu to this microblog, which contains links to modify personal information, log out and similar.
It is also feasible to add this navigation bar directly in the index.html template file, but when we have a lot of template files that contain this navigation bar, we will get stuck in order to modify the navigation bar somewhere and have to go back and forth in multiple files Editor's awkward situation. When more and more files containing this navigation bar, you will have the heart to die.
We can use Jinja2's template inheritance function, which allows us to combine some common content in the template to create a basic template, and then let other templates inherit this basic template.
Let's first define a basic template, which contains the navigation bar and the first flow control statement about the page title. (fileapp / templates / base.html):
<html>
<head>
{% if title%}
<title> {{title}}-microblog </ title>
{% else%}
<title> microblog </ title>
{% endif%}
</ head>
<body>
<div> Microblog: <a href="/index"> Home </a> </ div>
<hr>
{% block content%} {% endblock%}
</ body>
</ html>
In this template, we use the block control statement to define the display position of the inherited template content. Note: The name set in this block statement must be unique.
Next, let's modify the index.html template to inherit from the base template just added base.html (fileapp / templates / index.html):
{% extends "base.html"%}
{% block content%}
<h1> Hi, {{user.nickname}}! </ h1>
{% for post in posts%}
<div> <p> {{post.author.nickname}} says: {{post.body}} </ p> </ div>
{% endfor%}
{% endblock%}
The basic template base.html helped us get the page structure and public content, so this index.html template became this declining sample. The extends statement associates the two templates. When Jinja2 renders the index.html template and finds the extends statement, it will automatically introduce the base.html base template and match the block statement named content in the two templates. Jinja2 knows how to merge two templates together. When we create a new template in the future, we will also use this method of inheriting from the basic template.
Conclusion
If you want to save time and are too lazy to type code, you can download the sample code in this chapter from the following address:
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.