Flask Web Development —— 模板(下)

作者 | ipython

4、链接

任何应用程序都有多个路由,必然需要包含链接来连接不同的页面,例如导航栏。

在模板中,对于简单的路由直接写URLs做链接是非常琐碎麻烦的,而给带有变量部分的动态路由建立正确的URLs会变得更加复杂。此外,在代码中显式的写URLs会在路由上造成不必要的依赖。如果路由重组,模板中的链接将被打断而变得无法访问。

为了避免这些问题,Flask提供url_for()函数,它会根据存放在应用程序中的URL映射信息来生成URLs。

其最简单的用法,这个函数传入视图函数名(或通过app.add_url_route()定义的路由endpoint名)作为它的参数,然后返回它的URL。例如,在当前版本的hello.py调用url_for('index')将返回/。调用url_for('index', _external=True)将返回一个绝对URL,在该示例中为http://localhost:5000/

注:相对URLs足以满足生成链接来连接应用程序不同的路由。绝对URLs只有在链接被用于web浏览器的外部才是必须的,例如通过邮件发送链接。

可以使用url_for()并传递动态部分作为关键字参数来生成动态URLs。例如,url_for('user', name='join', external=True)会返回http://localhost:5000/user/john

url_for()可以不限参数的使用动态路由。函数会增加扩展参数给查询字符串。例如url_for('index', page=2)会返回/?page=2。

5、静态文件

Web应用程序不仅仅是由Python代码和模板组成。大部分的应用程序会使用静态文件,例如从HTML代码中引用的图片、JavaScript源文件和CSS。

你可能需要回忆一下,在第二章中检查hello.py应用程序的URL映射时,有一个static入口在里面。这也是为什么引用定义成/static/<filename>的静态文件会被当作特殊路由来对待。例如,一个url_for('static', filename='css/style.css', _external=True)调用会返回http://localhost:5000/static/css/styles.css

在它的默认配置中,Flask会在位于应用程序根目录下名为static的子目录中寻找静态文件。可以在这个目录下的子目录组织管理文件。当服务器收到来自之前示例的URL,它会产生一个响应包含static/css/styles.css的文件内容。

示例3-10展示应用程序如何在基础模板中包含favicon.icon图标并让浏览器将其显示在地址栏。

示例3-10. templates/base.html:favicon定义

{% block head %}
{{ super() }}
<link rel="shortcut icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename = 'favicon.ico') }}"
type="image/x-icon"> 
{% endblock %}

图标定义被插入在head块里的最下面。注意super()是如何保留定义在基础模板中块的原始内容的。

建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 3d来切换到这个版本的应用程序。

6、Flask-Moment中的本地化日期和时间

当用户工作在世界各个不同的地方,在web应用程序中处理日期和时间就变成了一个比较重要的问题。

服务器使用统一的时间单位,和每个用户的位置无关,所以使用世界标准时间(UTC)。对于用户,看到UTC格式的时间肯定会感到困惑,用户总是希望看到根据当地习惯显示的日期和时间。

一个优雅的解决方案是允许服务器只发送UTC时间给web浏览器,由浏览器转为当地时间并渲染。Web浏览器在这个问题上做的更好,因为他们可以访问用户电脑的所在的时区和地区设置。

有一个优秀的客户端开源库moment.js,用JavaScript编写的,用于在浏览器上渲染日期和时间。Flask-Moment是一个集成moment.js到Jinja2模板的Flask扩展。可以通过pip来安装:

(venv) $ pip install flask-moment

示例3-11展示扩展初始化。

示例3-11. hello.py:初始化Flask-Moment

from flask.ext.moment import Moment
moment = Moment(app)

Flask-Moment除了依赖moment.js外,还依赖jquery.js。这两个库需要直接包含在HTML文档,这种情况下你可以选择使用什么版本,或通过扩展提供的帮助函数来引用内容分发网络(CDN)的测试版本库。因为Bootstrap已经包含了jquery.js,所以只需要将moment.js增加到这个示例中。示例3-12展示这个库是如何被加载到基础模板scripts中的。

示例3-12. templates/base.html:导入moment.js库

{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{% endblock %}

为了可以使用时间戳,Flask-Moment创建moment类给模板使用。示例3-13传递current_time变量给模板去渲染。

示例3-13. hello.py:增加datetime变量

from datetime import datetime

@app.route('/') 
def index():
    return render_template('index.html', current_time=datetime.utcnow())

示例3-14展示如何在模板中渲染current_time。

示例3-14. templates/index.html:使用Flask-Moment渲染时间戳

<p>The local date and time is {{ moment(current_time).format('LLL') }}.</p>
<p>That was {{ moment(current_time).fromNow(refresh=True) }}</p>

format('LLL')根据客户端电脑的时区和地区设置来格式化显示日期和时间。参数决定了渲染的样式,从L到LLL对应不同的详细级别。format()函数还可以接受自定义的格式说明符。

fromNow()渲染样式显示在第二行,渲染一个相对时间戳并随着时间的推移自动刷新它。最初这个时间戳将显示为“几秒钟前”,但随着时间的流逝刷新选项将保持更新,所以如果你离开已打开几分钟的页面你会看到文本变为“一分钟前”,然后“两分钟前”,等等。

建议:如果你有克隆在GitHub上的应用程序,你现在可以运行git checkout 3e来切换到这个版本的应用程序。

Flask-Moment通过moment.js实现了format(),fromNow(),fromTime(), calendar(),valueOf()和unix()方法。查阅文档,了解提供的所有格式化选项。

注:Flask-Moment假定时间戳由服务端应用程序中表示成UTC格式的“naive”datetime对象来处理。参阅标准库datetime包文档关于date和time对象的navie和aware信息。

Flask-Moment渲染的时间戳可以本地化成多种语言。在模板中通过传递语言代码到lang()函数来选择语言:

{{ moment.lang('es') }}

学完本章中讨论的所有技术,您应该能够为您的应用程序构建现代、用户友好的网页。下一章涉及模板没有讨论的一个方面:如何通过web表单与用户进行交互。

原文转自:https://segmentfault.com/a/1190000000760163

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容