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多进程操作实例
Nov 21 Python
Python中利用函数装饰器实现备忘功能
Mar 30 Python
python打开文件并获取文件相关属性的方法
Apr 23 Python
python实现读取大文件并逐行写入另外一个文件
Apr 19 Python
Pycharm在创建py文件时,自动添加文件头注释的实例
May 07 Python
python3对接mysql数据库实例详解
Apr 30 Python
python 搜索大文件的实例代码
Jul 08 Python
python实现批量nii文件转换为png图像
Jul 18 Python
Python+OpenCv制作证件图片生成器的操作方法
Aug 21 Python
Python中sorted()排序与字母大小写的问题
Jan 14 Python
Python unittest生成测试报告过程解析
Sep 08 Python
python调试工具Birdseye的使用教程
May 25 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
re0第二季蕾姆被制作组打入冷宫!艾米莉亚女主扶正,原因唏嘘
2020/04/02 日漫
PHP基于单例模式实现的数据库操作基类
2016/01/15 PHP
php简单统计在线人数的方法
2016/05/10 PHP
PHP实现SMTP邮件的发送实例
2018/09/27 PHP
ThinkPHP 3.2.3实现加减乘除图片验证码
2018/12/05 PHP
PHP htmlspecialchars()函数用法与实例讲解
2019/03/08 PHP
js简单的表格添加行和删除行操作示例
2014/03/31 Javascript
javascript中 try catch用法
2015/08/16 Javascript
原生JavaScript实现Ajax的方法
2016/04/07 Javascript
IE和Firefox之间在JavaScript语法上的差异
2016/04/22 Javascript
json对象与数组以及转换成js对象的简单实现方法
2016/06/24 Javascript
canvas实现流星雨的背景效果
2017/01/13 Javascript
URL中“#” “?” &amp;“”号的作用浅析
2017/02/04 Javascript
Vue.js项目部署到服务器的详细步骤
2017/07/17 Javascript
深入理解Vue router的部分高级用法
2018/08/15 Javascript
支付宝小程序tabbar底部导航
2018/11/06 Javascript
js实现简单模态框实例
2018/11/16 Javascript
了解javascript中let和var及const关键字的区别
2019/05/24 Javascript
微信小程序利用Canvas绘制图片和竖排文字详解
2019/06/25 Javascript
vue监听用户输入和点击功能
2019/09/27 Javascript
JS实现动态无缝轮播
2020/01/11 Javascript
[44:15]DOTA2上海特级锦标赛主赛事日 - 5 败者组决赛Liquid VS EG第二局
2016/03/06 DOTA
[50:17]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[42:24]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第一场 11.01
2020/11/02 DOTA
在Django框架中伪造捕捉到的URLconf值的方法
2015/07/18 Python
同时安装Python2 &amp; Python3 cmd下版本自由选择的方法
2017/12/09 Python
Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法
2018/01/11 Python
Django使用httpresponse返回用户头像实例代码
2018/01/26 Python
python3+PyQt5实现拖放功能
2018/04/24 Python
Python读取英文文件并记录每个单词出现次数后降序输出示例
2018/06/28 Python
python 遗传算法求函数极值的实现代码
2020/02/11 Python
pyautogui自动化控制鼠标和键盘操作的步骤
2020/04/01 Python
基于Python爬取51cto博客页面信息过程解析
2020/08/25 Python
python连接手机自动搜集蚂蚁森林能量的实现代码
2021/02/24 Python
镇副书记专题民主生活会对照检查材料思想汇报
2014/10/02 职场文书
公司员工离职证明书
2014/10/04 职场文书