Flask Mega-Tutorial 中文教程 V2.0 第11章:整容

最近在Flask Web Development作者博客看到第二版Flask Mega-Tutorial已在2017年底更新,现翻译给大家参考,希望帮助大家学习flask。

这是Flask Mega-Tutorial系列的第十一章,其中我将告诉您如何使用基于Bootstrap用户界面框架的新模板替换基本HTML模板。

供您参考,以下是本系列文章的列表。

你把玩Microblog应用程序已经有一段时间了,所以我确定你注意到我没有花太多时间美化它,或者更具体地说,我没有花时间在那上面。所有的模板只使用了基础样式,绝对没有自定义样式。对我来说,专注于应用程序的实际逻辑是很有用的,因为不会分心去编写好看的HTML和CSS的代码。

但是我现在专注于这个应用程序的后端部分已经有一段时间。因此,在本章中我将暂停一下,并将花一些时间向您展示如何使应用程序看起来更加优雅和专业。

本章将与之前的章节略有不同,因为我不会像往常解说Python那样,事无巨细,毕竟Python才是本教程的主要内容。创建漂亮的网页是一个很大的主题,与Python Web后端开发很大程度上无关,但我将讨论如何处理前端的一些基本指导和想法,并且您还将通过重新设计外观来研究和学习它。

本章的GitHub链接是:BrowseZipDiff


CSS框架

虽然我们可以说写代码很难,但与网页设计师相比,我们的痛苦是无足轻重的,他们必须在所有的网络浏览器上编写具有良好和一致外观的模板。虽然它近年来这种情况得到一定程度的缓解,但是在某些浏览器中仍然存在一些模糊的错误或奇怪的设定,这使得设计网页的任务变得非常困难。如果您还需要兼容屏幕限制设备(如平板电脑和智能手机)的浏览器,这将更加困难。

如果你像我一样,是一个只想创建出规范网页的开发人员,但没有时间或兴趣去学习底层机制,并通过编写原生HTML和CSS来有效实现它,那么唯一可行的解​​决方案是使用CSS框架来简化任务。通过这条方式,您将失去一些创造性的自由,但另一方面,您的网页在所有浏览器中看起来都会很好,而又不需要花费太多精力。CSS框架提供了一组高级CSS类,其中包含用于常见类型的用户界面元素的预定义样式。大多数这样的框架还提供JavaScript组件,以实现不能纯粹使用HTML和CSS来完成的功能。

介绍Bootstrap

最受欢迎的CSS框架之一是由Twitter推出的Bootstrap。如果您想看看这个框架可以设计的页面类型,那么文档中有一些示例

以下是使用Bootstrap为您的网页设置样式的一些好处:

  • 在所有主流Web浏览器中都有相似的外观
  • 自适应PC,平板电脑和手机屏幕尺寸
  • 可定制的布局
  • 风格精美的导航栏、表单、按钮,提醒、弹出窗口等。

使用Bootstrap的最直接方法是在基本模板中导入bootstrap.min.css文件。您可以下载此文件的副本并将其添加到项目中,也可以直接从CDN导入。然后你可以根据文档开始使用它提供的通用CSS类,实在是太棒了。您可能还想导入包含JavaScript框架代码的bootstrap.min.js文件,以便您也可以使用最高级的功能。

幸运的是,有一个名为Flask-Bootstrap的Flask扩展,它提供了一个开箱即用的基本模板,该模板引入了Bootstrap框架。让我们安装此扩展程序:

(venv) $ pip install flask-bootstrap

使用Flask-Bootstrap

Flask-Bootstrap需要像大多数其他Flask扩展一样进行初始化:

# app/__init__.py: Flask-Bootstrap instance.

# ...
from flask_bootstrap import Bootstrap

app = Flask(__name__)
# ...
bootstrap = Bootstrap(app)

初始化扩展后,bootstrap / base.html模板变为可用状态,并且可以使用extends子句从应用程序模板中引用。

但是你记得,我已经使用了extends子句来继承我的基础模板,这允许我将页面的公共部分放在一个地方。我在base.html模板定义了导航栏,其中包含一些链接,还导出了一个content块。应用程序中的所有其他模板都从基本模板继承,并向content块提供页面的主要内容。

那么我如何适配Bootstrap基础模板呢?其思想是使用一个三级层次结构而不是仅仅使用两层层次结构。bootstrap/base.html文件模板提供页面的基本结构,其中包括Bootstrap框架文件。这个模板导出了一些用于派生模板(如titlenavbarcontent)的块(请参阅块的完整列表)。我要更改base.html文件模板,让它继承bootstrap/base.html文件,并提供titlenavbarcontent块。反过来,base.html将为从其派生的模板导出app_content块以定义页面内容。

下面你可以看看修改base.html后,它是如何从Bootstrap基础模板继承。请注意,此列表不包含导航栏的整个HTML,但您可以在GitHub上看到完整的实现,也可以下载本章的代码

<!-- app/templates/base.html: Redesigned base template. -->

{% extends 'bootstrap/base.html' %}

{% block title %}
    {% if title %}{{ title }} - Microblog{% else %}Welcome to Microblog{% endif %}
{% endblock %}

{% block navbar %}
    <nav class="navbar navbar-default">
        ... navigation bar here (see complete code on GitHub) ...
    </nav>
{% endblock %}

{% block content %}
    <div class="container">
        {% with messages = get_flashed_messages() %}
        {% if messages %}
            {% for message in messages %}
            <div class="alert alert-info" role="alert">{{ message }}</div>
            {% endfor %}
        {% endif %}
        {% endwith %}

        {# application content needs to be provided in the app_content block #}
        {% block app_content %}{% endblock %}
    </div>
{% endblock %}

在这里,您可以看到我如何从bootstrap/base.html派生此模板,然后分别实现页面标题,导航栏和页面内容的三个模板。

title块需要使用<title>标签来定义用于页面标题的文本。对于这个块,我只是移动了原始基本模板中<title>标签内的逻辑。

navbar块是可选块,可用于定义导航栏。对于这个块,我调整了Bootstrap导航栏文档中的示例,以便它在左侧展示网站品牌,跟着是Home和Explore链接。然后,我添加了个人主页和登录/注销链接并使其与页面右边框对齐。如上所述,我在上面的示例中省略了HTML,但您可以从本章的下载包中获取完整的base.html模板。

最后,在content块中我定义了一个顶级容器,在其中我有渲染闪存消息的逻辑,现在它们将显示为Bootstrap警报的样式。接下来是一个新的app_content块,它被定义为只有派生模板才能定义自己的内容。

所有页面模板的原始版本都在名为content的块中定义了它们的内容。如上所示,Flask-Bootstrap使用名为content的块,因此我将内容块重命名为app_content。所以我的所有模板都必须重命名才能使用app_content作为它们的内容块。例如,这是404.html模板的修改后版本的展示:

<!-- app/templates/404.html: Redesigned 404 error template. -->

{% extends "base.html" %}

{% block app_content %}
    <h1>File Not Found</h1>
    <p><a href="{{ url_for('index') }}">Back</a></p>
{% endblock %}

渲染Bootstrap表单

Flask-Bootstrap的一个很棒的工作就是渲染表格。Flask-Bootstrap不是必须逐个设置表单字段的样式,而是使用一个接受Flask-WTF表单对象作为参数的宏,并使用Bootstrap样式渲染出完整的表单。

您可以在下面看到重新设计的register.html模板:

<!-- app/templates/register.html: User registration template. -->

{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}

{% block app_content %}
    <h1>Register</h1>
    <div class="row">
        <div class="col-md-4">
            {{ wtf.quick_form(form) }}
        </div>
    </div>
{% endblock %}

是不是很棒?顶部附近的import声明与Python导入类似。这增加了一个wtf.quick_form()宏,在一行代码中渲染了完整的表单,包括显示验证错误的支持,并且适配Bootstrap框架的所有样式。

再一次,我不会向您展示我为应用程序中的其他表单所做的所有更改,但这些更改都是在您可以在GitHub上下载或检查到的。

渲染博客帖子

渲染单个博客帖子的逻辑被提取到名为_post.html的子模板。我需要对此模板进行一些小的调整,以便在Bootstrap下看起来很好。

<!-- app/templates/_post.html: Redesigned post sub-template. -->

    <table class="table table-hover">
        <tr>
            <td width="70px">
                <a href="{{ url_for('user', username=post.author.username) }}">
                    <img src="{{ post.author.avatar(70) }}" />
                </a>
            </td>
            <td>
                <a href="{{ url_for('user', username=post.author.username) }}">
                    {{ post.author.username }}
                </a>
                says:
                <br>
                {{ post.body }}
            </td>
        </tr>
    </table>

渲染分页链接

分页链接是Bootstrap提供直接支持的另一个领域。为此,我再一次查看Bootstrap 文档并修改其中一个示例。

以下是index.html页面中的内容:

<!-- app/templates/index.html: Redesigned pagination links. -->

    ...
    <nav aria-label="...">
        <ul class="pager">
            <li class="previous{% if not prev_url %} disabled{% endif %}">
                <a href="{{ prev_url or '#' }}">
                    <span aria-hidden="true">&larr;</span> Newer posts
                </a>
            </li>
            <li class="next{% if not next_url %} disabled{% endif %}">
                <a href="{{ next_url or '#' }}">
                    Older posts <span aria-hidden="true">&rarr;</span>
                </a>
            </li>
        </ul>
    </nav>

请注意,在这个实现中,当下一页或上一页方向上没有更多内容时,我将应用禁用状态,而不是隐藏下一页或上一页链接,这将使链接显示为灰色。

类似的更改需要应用于user.html,我不会在这里展示它。本章的下载包包含这些更改。

对比更改前后

要使用这些更改来更新您的应用程序,请下载本章的zip文件并相应地更新您的模板。

下面你可以对比几张美化前后的图片来观察转变情况。请记住,在不更改一行应用程序逻辑的情况下实现了此更改!

ch12-login

ch12-index


原文链接:https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xi-facelift

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值