Flask教程-模板优化
下面是几个非常实用的模板编写技巧,为实现创建和编辑电影条目打下基础。
自定义错误页面:在Flask程序中自定义错误页面非常简单。首先,我们可以编写一个404错误页面模板,例如templates/404.html:
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>{{ user.name }}'s Watchlist</title><link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}"><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css"></head><body><h2><img alt="Avatar" class="avatar" src="{{ url_for('static', filename='images/avatar.png') }}">{{ user.name }}'s Watchlist</h2><ul class="movie-list"><li>Page Not Found - 404<span class="float-right"><a href="{{ url_for('index') }}">Go Back</a></span></li></ul><footer><small>© 2018 <a href="http://helloflask.com/book/3">HelloFlask</a></small></footer></body></html>
接下来,使用app.errorhandler()装饰器注册一个错误处理函数,该函数会在发生404错误时被触发,并将其返回值作为响应主体返回给客户端。在这个函数中,我们可以查询数据库并将user变量传递给模板:
@app.errorhandler(404)def page_not_found(e):user = User.query.first()return render_template('404.html', user=user), 404
这样,当访问一个不存在的URL时,将显示我们自定义的404错误页面。
模板继承:错误页面模板和主页模板存在大量重复的代码,例如<head>标签的内容、页首的标题、页脚信息等。为了避免重复的劳动和修改的麻烦,我们可以使用模板继承的概念。
首先,我们创建一个基础模板,例如templates/base.html,其中包含通用的HTML结构和代码:
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>{% block title %}{% endblock %}</title><link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}"><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css"></head><body><h2><img alt="Avatar" class="avatar" src="{{ url_for('static', filename='images/avatar.png') }}">{{ user.name }}'s Watchlist</h2>{% block content %}{% endblock %}<footer><small>© 2018 <a href="http://helloflask.com/book/3">HelloFlask</a></small></footer></body></html>
然后,在错误页面模板和其他页面模板中,我们可以使用extends关键字继承基础模板,并使用block关键字定义可替换的块:
404错误页面模板templates/404.html:
{% extends 'base.html' %}{% block title %}{{ user.name }}'s Watchlist{% endblock %}{% block content %}<ul class="movie-list"><li>Page Not Found - 404<span class="float-right"><a href="{{ url_for('index') }}">Go Back</a></span></li></ul>{% endblock %}
主页模板templates/index.html:
{% extends 'base.html' %}{% block title %}{{ user.name }}'s Watchlist{% endblock %}{% block content %}<!-- 主页内容 -->{% endblock %}
使用模板继承可以大大简化模板的编写和维护,通过定义不同的块,我们可以在每个页面中插入特定的内容。
模板中的静态文件:当在模板中引用静态文件(如CSS样式表、图像等)时,可以使用url_for函数生成正确的URL。例如,我们在上述示例中使用了url_for来引用favicon图标、样式表和图像。
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}"><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css"><img alt="Avatar" class="avatar" src="{{ url_for('static', filename='images/avatar.png') }}">
url_for('static', filename='...')会生成指向静态文件的URL,其中static是Flask应用程序中静态文件所在的目录。
模板上下文处理函数和模板继承
这是一个非常实用的技巧,可以在多个模板中使用相同的变量而不必重复定义。下面是一个模板上下文处理函数和模板继承的示例代码,帮助你更好地理解:
# 注册模板上下文处理函数@app.context_processordef inject_user():user = User.query.first()return dict(user=user)
在这个示例中,我们定义了一个名为inject_user的模板上下文处理函数。它会查询数据库并将第一个用户对象赋给user变量。然后,我们通过return语句返回一个字典,将user作为键,其值为user变量。这样,user变量就可以在所有模板中使用。
接下来,我们使用模板继承的机制来组织模板结构。我们创建了一个基础模板base.html,其中包含了通用的HTML结构、导航栏、页脚等部分。基础模板中定义了两个块(block),分别是head和content:
<!DOCTYPE html><html lang="en"><head>{% block head %}<!-- head内容 -->{% endblock %}</head><body><!-- 导航栏 --><nav><ul><li><a href="{{ url_for('index') }}">Home</a></li></ul></nav>{% block content %}<!-- content内容 -->{% endblock %}<footer><!-- 页脚内容 --></footer></body></html>
在子模板中,我们使用extends标签声明继承自基础模板,并通过block标签定义需要替换或追加内容的块。例如,主页模板index.html继承自base.html,并在content块中定义了主页的内容:
{% extends 'base.html' %}{% block content %}<!-- 主页内容 -->{% endblock %}
404错误页面模板404.html同样继承自base.html,并在content块中定义了404错误页面的内容:
{% extends 'base.html' %}{% block content %}<!-- 404错误页面内容 -->{% endblock %}
使用模板上下文处理函数和模板继承,我们可以在多个模板中使用相同的变量,并将模板的结构组织得更加清晰和可维护。
添加 IMDb 链接
在主页模板中,我们为每个电影条目右侧添加了一个IMDb链接。下面是对应的HTML代码和CSS样式:
<span class="float-right"><a class="imdb" href="https://www.imdb.com/find?q={{ movie.title }}" target="_blank" title="Find this movie on IMDb">IMDb</a></span>
.float-right {float: right;}.imdb {font-size: 12px;font-weight: bold;color: black;text-decoration: none;background: #F5C518;border-radius: 5px;padding: 3px 5px;}
在这段代码中,我们使用了一个<span>元素将IMDb链接包裹起来,并为它添加了float-right类,使其靠右对齐。链接本身使用<a>标签表示,其中href属性设置为IMDb搜索页面的URL,通过查询参数q传入电影的标题。
target="_blank"属性将链接在新标签页中打开。另外,我们还使用了一些CSS样式来设置链接的字体、颜色、背景色等。
只需2行代码,轻松将PDF转换成Word AI绘画-我的天!潮流女孩 Flask教程-静态文件