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入门篇之正则表达式
Oct 20 Python
Python的Django框架中自定义模版标签的示例
Jul 20 Python
Python实现遍历目录的方法【测试可用】
Mar 22 Python
Python使用Django实现博客系统完整版
Sep 29 Python
Python并发:多线程与多进程的详解
Jan 24 Python
python文件读写代码实例
Oct 21 Python
pytorch+lstm实现的pos示例
Jan 14 Python
Python定时器线程池原理详解
Feb 26 Python
使用keras实现Precise, Recall, F1-socre方式
Jun 15 Python
Python为何不支持switch语句原理详解
Oct 21 Python
pycharm 配置svn的图文教程(手把手教你)
Jan 15 Python
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 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 开发环境配置(Zend Server安装)
2010/04/28 PHP
PHP单例模式详解及实例代码
2016/12/21 PHP
Laravel配合jwt使用的方法实例
2020/10/25 PHP
JS控件autocomplete 0.11演示及下载 1月5日已更新
2007/01/09 Javascript
html数组字符串拼接的最快方法
2009/09/16 Javascript
javascript 动态生成私有变量访问器
2009/12/06 Javascript
返回对象在当前级别中是第几个元素的实现代码
2011/01/20 Javascript
js自定义事件代码说明
2011/01/31 Javascript
javascript数组的使用
2013/03/28 Javascript
使用微信小程序开发前端【快速入门】
2016/12/05 Javascript
自学实现angularjs依赖注入
2016/12/20 Javascript
bootstrap实现二级下拉菜单效果
2017/11/23 Javascript
利用Angular2 + Ionic3开发IOS应用实例教程
2018/01/15 Javascript
js中apply和Math.max()函数的问题及区别介绍
2018/03/27 Javascript
JS实现的简单折叠展开动画效果示例
2018/04/28 Javascript
一步一步的了解webpack4的splitChunk插件(小结)
2018/09/17 Javascript
监控微信小程序中的慢HTTP请求过程详解
2019/07/05 Javascript
JavaScript实现点击自制菜单效果
2021/02/02 Javascript
python opencv 图像尺寸变换方法
2018/04/02 Python
Django使用Mysql数据库已经存在的数据表方法
2018/05/27 Python
python利用requests库模拟post请求时json的使用教程
2018/12/07 Python
python实现视频分帧效果
2019/05/31 Python
python模拟菜刀反弹shell绕过限制【推荐】
2019/06/25 Python
Python实现计算对象的内存大小示例
2019/07/10 Python
git查看、创建、删除、本地、远程分支方法详解
2020/02/18 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
加拿大在线隐形眼镜专家:PerfectLens.ca
2016/11/19 全球购物
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
IMPORT的选项IGNORE有什么作用?缺省是什么设置?
2015/09/17 面试题
Linux如何压缩可执行文件
2014/03/27 面试题
中专生自我鉴定范文
2013/12/19 职场文书
幼儿园保教管理制度
2014/02/03 职场文书
父亲节活动总结
2015/02/12 职场文书
学校百日安全活动总结
2015/05/07 职场文书
2015党建工作简报
2015/07/21 职场文书
使用CSS实现按钮边缘跑马灯动画
2023/05/07 HTML / CSS