Flask入门教程实例:搭建一个静态博客


Posted in Python onMarch 27, 2015

现在流行的静态博客/网站生成工具有很多,比如 Jekyll, Pelican, Middleman, Hyde 等等,StaticGen 列出了目前最流行的一些静态网站生成工具。

我们的内部工具由 Python/Flask/MongoDB 搭建,现在需要加上文档功能,写作格式是 Markdown,不想把文档放到数据库里,也不想再弄一套静态博客工具来管理文档,于是找到了 Flask-FlatPages 这个好用的 Flask 模块。熟悉 Flask 的同学花几分钟的时间就可以用搭建一个简单博客,加上 Bootstrap 的帮助,不到一小时内就可以用 Flask-Flatpages 弄个像模像样的网站出来。

创建开发环境

首先我们需要 pip,在 Mac 上最简单的安装办法是:

$ sudo easy_install pip

$ sudo easy_install virtualenv

如果你在 Mac 上用 Homebrew 包管理工具的话的话,也可以用 brew 升级 Python 和安装 pip:
$ brew update

$ brew install python

创建一个 blog 目录、生成 Python 独立虚拟环境并在这个环境里安装需要的 Flask, Flask-FlatPages 模块:
$ mkdir blog

$ cd blog
$ virtualenv flask

New python executable in flask/bin/python

Installing setuptools, pip...done.
$ flask/bin/pip install flask

$ flask/bin/pip install flask-flatpages

在 blog 目录下我们分别新建几个目录:static 用来存放 css/js 等文件,templates 用来存放 flask 要用的 Jinja2 模版,pages 用来存放我们静态博客(Markdown 格式):
$ mkdir -p app/static app/templates app/pages

程序

主程序 blog.py 的功能是,导入必要的模块、配置 Flask-FlatPages 模块需要的参数、创建 Flask 应用、写几个 URL 路由函数,最后运行这个应用:

$ vi app/blog.py

#!flask/bin/python

from flask import Flask, render_template

from flask_flatpages import FlatPages
DEBUG = True

FLATPAGES_AUTO_RELOAD = DEBUG

FLATPAGES_EXTENSION = '.md'
app = Flask(__name__)

app.config.from_object(__name__)

flatpages = FlatPages(app)
@app.route('/')

def index():

    pages = (p for p in flatpages if 'date' in p.meta)

    return render_template('index.html', pages=pages)
@app.route('/pages/<path:path>/')

def page(path):

    page = flatpages.get_or_404(path)

    return render_template('page.html', page=page)
if __name__ == '__main__':

    app.run(port=8000)

模版

在 Python 中直接生成 HTML 很繁琐并不好玩(那是上个世纪90年代的 PHP 搞的事情),在现代社会,我们使用模版引擎,Flask 已经自动配置好了 Jinja2 模版,使用方法 render_template() 来渲染模版就可以了。Flask 会默认在 templates 目录里中寻找模版,我们只需要创建几个模版文件就可以了,这里我们创建 base.html, index.html 和 page.html.

$ vi app/templates/base.html

<!doctype html>

<html>

<head>

    <meta charset="utf-8">

    <title>vpsee.com static blog</title>

</head>
<body>

    <h1><a href="{{ url_for("index") }}">vpsee.com blog</a></h1>

    {% block content %}

    {% endblock content %}

</body>

</html>

代码里 extends “base.html” 的意思是从 base.html 里继承基本的 “骨架”。
$ vi app/templates/index.html

{% extends "base.html" %}
{% block content %}

    <h2>List of pages

    <ul>

        {% for page in pages %}

        <li>

            <a href="{{ url_for("page", path=page.path) }}">{{ page.title }}</a>

        </li>

        {% else %}

        <li>No post.</li>

        {% endfor %}

    </ul>

{% endblock content %}

$ vi app/templates/page.html

{% extends "base.html" %}
{% block content %}

    <h2>{{ page.title }}</h2>

    {{ page.html|safe }}

{% endblock content %}

Flask-FlatPages 模块会默认从 pages 目录里寻找 .md 结尾的 Markdown 文档,所以我们把静态博客的内容都放在这个目录里:
$ vi app/pages/hello-world.md

title: Hello World

date: 2014-10-14

tags: [general, blog]
**Hello World**!
$ vi app/pages/test-flatpages.md

title: Test Flask FlatPages

date: 2014-10-15

tags: [python, flask]
Test [Flask-FlatPages](https://pythonhosted.org/Flask-FlatPages/)

运行

基本搞定,运行看看效果吧:

$ flask/bin/python app/blog.py

 * Running on http://127.0.0.1:8000/

 * Restarting with reloader

Flask入门教程实例:搭建一个静态博客

静态化

到目前为止,上面的博客运行良好,但是有个问题,这个博客还不是 “静态” 的,没有生成任何 html 文件,不能直接放到 nginx/apache 这样的 web 服务器下用。所以我们需要另一个 Flask 模块 Frozen-Flask 的帮助。

安装 Frozen-Flask:

$ flask/bin/pip install frozen-flask

修改 blog.py,导入 Flask-Frozen 模块,初始化 Freezer,使用 freezer.freeze() 生成静态 HTML:
$ vi app/blog.py

...

from flask_flatpages import FlatPages

from flask_frozen import Freezer

import sys

...

flatpages = FlatPages(app)

freezer = Freezer(app)

...

if __name__ == '__main__':

    if len(sys.argv) > 1 and sys.argv[1] == "build":

        freezer.freeze()

    else:

        app.run(port=8000)

运行 blog.py build 后就在 app 目录下生成 build 目录,build 目录里面就是我们要的 HTML 静态文件:
$ flask/bin/python app/blog.py build
$ ls app/

blog.py   build     pages     static    templates

更清晰的目录结构如下:
$ tree app

app

├── blog.py

├── build

│   ├── index.html

│   └── pages

│       ├── hello-world

│       │   └── index.html

│       └── test-flatpages

│           └── index.html

├── pages

│   ├── hello-world.md

│   └── test-flatpages.md

├── static

└── templates

    ├── base.html

    ├── index.html

    └── page.html
Python 相关文章推荐
python构造icmp echo请求和实现网络探测器功能代码分享
Jan 10 Python
python获得linux下所有挂载点(mount points)的方法
Apr 29 Python
在Python中操作字典之setdefault()方法的使用
May 21 Python
Python简单获取自身外网IP的方法
Sep 18 Python
python利用MethodType绑定方法到类示例代码
Aug 27 Python
python判断单向链表是否包括环,若包含则计算环入口的节点实例分析
Oct 23 Python
Python django搭建layui提交表单,表格,图标的实例
Nov 18 Python
如何基于Python实现电子邮件的发送
Dec 16 Python
python学生信息管理系统实现代码
Dec 17 Python
python设置中文界面实例方法
Oct 27 Python
Python编写万花尺图案实例
Jan 03 Python
matplotlib制作雷达图报错ValueError的实现
Jan 05 Python
Python中的高级数据结构详解
Mar 27 #Python
python中反射用法实例
Mar 27 #Python
Python中使用摄像头实现简单的延时摄影技术
Mar 27 #Python
python根据出生日期返回年龄的方法
Mar 26 #Python
python获取远程图片大小和尺寸的方法
Mar 26 #Python
python使用cStringIO实现临时内存文件访问的方法
Mar 26 #Python
python使用pil生成缩略图的方法
Mar 26 #Python
You might like
PHP提取中文首字母
2008/04/09 PHP
PHP5中Cookie与 Session使用详解
2013/04/30 PHP
浅谈php7的重大新特性
2015/10/23 PHP
在Mac OS上自行编译安装Apache服务器和PHP解释器
2015/12/24 PHP
IE6不能修改NAME问题的解决方法
2010/09/03 Javascript
Dom 结点创建 基础知识
2011/10/01 Javascript
jquery实现pager控件示例
2014/04/09 Javascript
浅析javascript中函数声明和函数表达式的区别
2015/02/15 Javascript
JS实现仿新浪黄色经典滑动门效果代码
2015/09/27 Javascript
BootStrap的弹出框(Popover)支持鼠标移到弹出层上弹窗层不隐藏的原因及解决办法
2016/04/03 Javascript
基于JQuery实现的跑马灯效果(文字无缝向上翻动)
2016/12/02 Javascript
jQuery实现限制文本框的输入长度
2017/01/11 Javascript
JavaScript设计模式之单例模式详解
2017/06/09 Javascript
Layui 设置select下拉框自动选中某项的方法
2018/08/14 Javascript
vue 动态表单开发方法案例详解
2019/12/02 Javascript
[54:41]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VGJ.T VS paiN
2018/03/31 DOTA
[00:47]DOTA2荣耀之路6:天火,天火!
2018/05/30 DOTA
详解Python爬虫的基本写法
2016/01/08 Python
Flask-Mail用法实例分析
2018/07/21 Python
python redis 删除key脚本的实例
2019/02/19 Python
python用线性回归预测股票价格的实现代码
2019/09/04 Python
Pandas时间序列:时期(period)及其算术运算详解
2020/02/25 Python
pycharm实现在子类中添加一个父类没有的属性
2020/03/12 Python
html5+CSS3+JS实现七夕言情功能代码
2017/08/28 HTML / CSS
加拿大女鞋品牌:ALDO
2016/11/13 全球购物
《三个小伙伴》教学反思
2014/04/11 职场文书
彩色的翅膀教学反思
2014/04/25 职场文书
个人投资计划书
2014/05/01 职场文书
2015年母亲节寄语
2015/03/23 职场文书
重温入党誓词主持词
2015/06/29 职场文书
某某店铺的开业庆典主持词范本
2019/11/25 职场文书
PHP控制循环操作的时间
2021/04/01 PHP
Python 可迭代对象 iterable的具体使用
2021/08/07 Python
Golang中channel的原理解读(推荐)
2021/10/16 Golang
浅谈JavaScript浅拷贝和深拷贝
2021/11/07 Javascript
Python读写yaml文件
2022/03/20 Python