Fork me on GitHub

博客迁移笔记 5月 07, 2017

去年花了一些时间在github上建起了个人博客,后来又购买了域名nutshellking.com(取自哈姆雷特台词I could be bounded in a nutshell, and count myself a king of infinite space), 该博客采用Jekyll生成,基本满足了我想要的如下功能:

  • 代码高亮;
  • 支持数学公式显示(通过Mathjax实现);
  • 支持评论(通过Disqus实现,后来发现此项功能被GFW屏蔽了);

自那以后,一直瞎忙,没时间打理博客,近来兴起,想将个人博客网站更新重整。此博客原来使用的Jekyll是一个Ruby语言写成的静态网页生成器, 因觉得Ruby用途较为单一,最近在学应用广泛的Python的缘故,觉得将博客迁移至基于Python技术的Web框架应该会比较有趣。比较成熟的Python Web框架要数Flask与Django了。对于一个简洁的博客,Django可能太过重量级,Flask就够用了,因此买了本《Flask Web开发 基于Python的Web应用开发实战》(人称Flask狗书),在电脑上演练一番。在此过程中填了不少坑,浪费了不少时间,最终转到与Jekyll十分类似的Pelican上面。将此段时间的折腾记录如下。

Flask狗书循序渐进的讲述了Flask开发的各个步骤,结合其提供的git代码库能够按章节一步步实现、理解所需功能,实为良心之作。该书作者作为Flask的核心开发者,其个人网站上也有一个讲解Flask的教程很不错。但Flask仅仅只是一个框架,要将其变为可部署的个人博客产品显然需要定制各种插件,加入个性化配置,有很多工作要做。这也是我最初始料未及的。

1. Flask Web开发实战书中的几个问题

1.1 注册时无法通过email收到激活邮件

第8章中用户注册功能需要用向注册的用户发送激活邮件,此步骤要求必须实现配置好邮件发送相关设置,代码中默认的设置使用google的邮件服务,不更改此处显然无法成功。 该设置在Config.py中,以第9章的程序为例, 首先签出对应版本:

git clone https://github.com/miguelgrinberg/flasky.git
cd flasky
git checkout 9a

注意Config.py中以下代码:

    MAIL_SERVER = 'smtp.googlemail.com'
    MAIL_PORT = 587
    MAIL_USE_TLS = True
    MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
    MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
    FLASKY_MAIL_SUBJECT_PREFIX = '[Flasky]'
    FLASKY_MAIL_SENDER = 'Flasky Admin <flasky@example.com>'
    FLASKY_ADMIN = os.environ.get('FLASKY_ADMIN')

若使用163邮箱,可更改其MAIL_SERVER及MAIL_PORT如下(其他邮箱可参考email服务商官网帮助):

    MAIL_SERVER = 'smtp.163.com'
    MAIL_PORT = 25

并将flasky@example.com替换为自己所用邮箱。注意到以上代码中使用了这几个环境变量: MAIL_USERNAME,MAIL_PASSWORD,FLASKY_ADMIN,在linux环境下,需在终端中对其进行设置:

(venv) $ export MAIL_USERNAME=<mail username>
(venv) $ export MAIL_PASSWORD=<mail password>
(venv) $ export FLASKY_ADMIN=<mail username>

若为Windows环境,将export改为set。 注意在终端中输入的邮箱用户名不需要再加上@xxx.com后缀。

1.2 无法发表文章

第11章时会出现使用管理员账户登录后无法发表文章的问题,此问题的原因是数据库中角色权限不对。可参考此处解决方案

1.3 markdown生成的网页文件显示不正常

按照该书提供源码,使用markdown编写文件,插入如下表格格式的文本,预览时发现无法显示表格。

Item     | Value
-------- | ---
Computer | $1600
Phone    | $12

这是由于python的markdown模块将文本转换为网页文件时,未指定使用相应扩展所致。

git checkout 11h

按以上指令检出文件,找到app/models.py中的on_changed_body函数

    @staticmethod
    def on_changed_body(target, value, oldvalue, initiator):
        allowed_tags = ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code',
                        'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul',
                        'h1', 'h2', 'h3', 'p']
        target.body_html = bleach.linkify(bleach.clean(
            markdown(value, output_format='html'),
            tags=allowed_tags, strip=True))

将此段代码改为如下即可:

    @staticmethod
    def on_changed_body(target, value, oldvalue, initiator):
        myexts = ['extra', 'abbr', 'attr_list', 'def_list', 'fenced_code', 'footnotes', 'tables', 'smart_strong', 'admonition', 'codehilite', 'headerid', 'meta', 'nl2br', 'sane_lists', 'smarty', 'toc']
        target.body_html = bleach.linkify(markdown(value, extensions=myexts))

markdown模块的各个扩展的用法可参考此处官网

2 Pelican中markdown文件插入数学公式无法正确显示

Pelican的使用还是相当方便的,但其依赖的Python Markdown模块转换markdown文件的能力没有Jekyll成熟稳定。借助Mathjax脚本在markdown文件中插入Latex数学公式时,若公式中含有下划线_:

$$\vec{X} = (\vec{x_j}, \vec{x_k})$$

则下划线在转换后会生成<em>标签,导致无法正确渲染公式。  解决此问题需要在调用markdown解析转换文件时,碰到$$等符号换种规则解析即可。网上已有解决方案,就无须重造轮子了。按照该方案将mathjax.py拷贝至markdown模块中的extensions子文件夹中,然后在pelicanconf.py中添加以下代码即可:

MARKDOWN = {
    'extension_configs': {
        'markdown.extensions.codehilite': {'css_class': 'highlight'},
        'markdown.extensions.extra': {},
        'markdown.extensions.meta': {},
        'markdown.extensions.mathjax': {},
    },
    'output_format': 'html5',
}

填了这么多坑,费了很多时间终于讲博客迁移成功。希望能够继续坚持探索、记录、分享自己的各种想法。