>>> from  env_helper import info; info()
页面更新时间: 2024-04-07 23:45:17
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

6.7. 使用Pelican发布网页

Pelican Static Site Generator, Powered by Python:Pelican是python语言写的静态网站生成器,Pelican 是那些想要自我托管简单网站或博客的 Python 用户的绝佳选择。

6.7.1. Pelican介绍

什么是Pelican

Perlican是用Python实现的一个静态网站生成器,支持reStructuredText或Markdown。它支持以下功能:

  • 博客文章和静态网页

  • 支持评论。评论是通过第三方服务Disqus支持的。即评论数据保存在第三方服务器上

  • 主题支持

  • 把博客文章生成PDF格式文档

  • 多语言博客支持,如可以用英文和中文写同一篇博客。不同语言访问者访问相应语言的博文

  • 支持Atom/RSS订阅

  • 博文中代码高亮支持

  • 博客搬家支持(WordPress, Dotclear, 或RSS feeds)

  • 支持插件,如Twiter, Google Analytics等

为什么选择Pelican

首先排除掉WordPress之类的CMS系统。因为我不想要数据库,我只需要一个轻量级的静态网站生成器。我的博客使用Markdown编写,且保存在GitHub上。我想要的,只是用Markdown写完博客之后,git commit + git push即可直接发布到博客网站上。

选择Pelican是基于如下原因:

  • 使用Python实现。由于最近在学习Python,我可以阅读源码并按照我的需求来改造Pelican使之完全符合我的需求。下次学习Ruby,用jekyll再折腾一遍。因为Jekyll是用Ruby实现的。且GitHub Pages的后台就是用Jekyll,到时可直接用GitHub Pages实现个人博客。

  • 足够轻量级。总的代码量才1MB多。安装也方便。

  • 有一堆现成的主题可以使用。这对我这种非专业前端的开发者来说,省了不少事。

  • 文档齐全。

  • 开发活动活跃。GitHub上代码提交活跃。

最后两点对使用任何开源工具来说都是很重要的,只有开发活跃,社区资源多,文档齐全,遇到问题的时候才能较快地得到解决。

6.7.2. Pelican安装与配置

安装Pelican并创建项目

首先,通过pip安装pelican和markdown:

pip install pelican markdown

然后创建你的博客项目:

mkdir ~/blogs

cd ~/blogs

pelican-quickstart

在运行 pelican-quickstart 时,系统会问一系列问题,比如你的博客网址啊, 作者名字啊之类的,根据真实情况填写即可,这些问题只是用来生成配置文件的,我们后面都可以通过修改配置文件来手动修改这些设置。创建完项目后,目录下看起来象这样。

~/blogs/tree

├── content     # 这个就是放博客内容目录,这个目录及子目录下的所有md和rst文件将会被转成html文件
├── develop_server.sh   #这个是用来在本地运行一个服务器来实时查看生成的html文档的脚本
├── fabfile.py  # 这个是使用Python的fabric来实现文件上传的工具,即Deploy工具
├── Makefile    # 这个是使用是用来生成网站内容并上传的工具。后文详细解释
├── output      # 这个是从content目录生成的html目标文件的存放目录
├── pelicanconf.py      # 这个是本地开发时的配置文件
└── publishconf.py      # 这个是发布时的配置文件

配置pelicanconf.py和publishconf.py

Pelican的配置文件是直接用Python写的,我本地开发配置文件pelicanconf.py内容如下:

>>> from __future__ import unicode_literals
>>> AUTHOR = u'Joey Huang'

SITENAME是博客网站的名称,可以是任何字符;

>>> SITENAME = u"kamidox.com"

SITEURL博客网站的网址,这个字段在本地开发和发布版本是不一样的,本地直接填localhost即可,发布版本里需要填博客网址。

>>> SITEURL = 'http://localhost'

使用Disqus作为我的评论系统。启用Disqus评论系统非常简单,在官网上注册一个Disqus帐户,然后把帐户名填在DISQUS_SITENAME值里即可启用。我的Disqus帐号刚好也是kamidox。

>>> DISQUS_SITENAME = 'kamidox'
>>> PATH = 'content'
>>> TIMEZONE = 'Asia/Shanghai'
>>>
>>> DEFAULT_LANG = u'zh_CN'
>>> DEFAULT_DATE_FORMAT = ('%Y-%m-%d(%A) %H:%M')
>>>
>>> USE_FOLDER_AS_CATEGORY = True
>>> DEFAULT_CATEGORY = 'hide'
>>>
>>> # Feed generation is usually not desired when developing
>>> FEED_ATOM = 'feeds/atom.xml'
>>> FEED_RSS = 'feeds/rss.xml'
>>> FEED_ALL_ATOM = None
>>> FEED_ALL_RSS = None
>>> CATEGORY_FEED_ATOM = None
>>> TRANSLATION_FEED_ATOM = None

设置菜单项

>>> MENUITEMS = [('Home', SITEURL),
>>>             ('About', 'about.html'),]

设置默认分页

>>> DEFAULT_PAGINATION = 10

配置Markdown扩展,用来支持代码高亮。并且使用Emacs风格的代码高亮。

>>> MD_EXTENSIONS = [
>>>         "extra",
>>>         "toc",
>>>         "headerid",
>>>         "meta",
>>>         "sane_lists",
>>>         "smarty",
>>>         "wikilinks",
>>>         "admonition",
>>>         "codehilite(guess_lang=False,pygments_style=emacs,noclasses=True)"]

由于GFW的存在,我把Google Analize换成了国内的CNZZ统计。

>>> CNZZ_ANALYTICS = True
>>> MONTH_ARCHIVE_SAVE_AS = 'posts/{date:%Y}/{date:%m}/index.html'

我的博客使用了foundation-default-colours这套主题。

>>> THEME = "themes/foundation-default-colours"

开发环境和发布环境的配置差不多,除SITEURL不一样外,还多了两个配置:

>>> SITEURL = 'http://kamidox.com'

禁用相对路径引用

>>> RELATIVE_URLS = False

编译之前删除output目录,这样保证output下生成的内容是干净的

>>> DELETE_OUTPUT_DIRECTORY = True

配置Makefile

撰写完博客,并在本地预览后,需要发布到服务器上。我使用Makefile的形式来生成文档并发布。我的Makefile核心代码如下:

指定要上传内容的目的服务器的地址,端口以及用户名

>>> #!/makefile
>>> SSH_HOST="kamidox.com"
>>> SSH_PORT="22"
>>> SSH_USER="ubuntu"

指定远程服务器上保存博客内容的目录

>>> SSH_TARGET_DIR="/home/ubuntu/blogs/"

我添加的SSH Identity文件路径。这是因为Amazon EC2登录时我是用SSH Identity文件登录的,而不是使用用户名和密码

>>> SSH_KEY="/home/kamidox/work/aws/kamidox-key-tokyo.pem"

我使用rsync来进行上传操作。rsync可以在本地和远程服务器之间同步文件。同步过程中只同步那些改变了的文件,且传输过程中会压缩数据,它比scp要所需要的带宽要小。这里要注意的是,我在默认生成的Makefile上增加了-i $(SSH_KEY),这个就是指定SSH Identity文件登录远程SSH的方法。

rsync_upload: publish
    rsync -e "ssh -p $(SSH_PORT) -i $(SSH_KEY)" -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude

配置主题

Pelican支持大量的开源主题,GitHub上的pelican-themes项目有几十套主题,大部分都带了效果预览图。可以从里面挑一个你喜欢的主题样式来使用。还有一个更方便的挑选主题的方式,直接打开 www.pelicanthemes.com 挑选吧。一个网页里就列出了几乎所有的主题。我的博客是使用foundation-default-colours主题,并在这套主题的基础上进行了一些定制。选定好喜欢的主题后,从GitHub上下载下来所有的主题:

mkdir ~/pelican
cd ~/pelican
git clone https://github.com/getpelican/pelican-themes.git

从里面拷贝一份你选中的主题到项目根目录的themes目录下,在本文的例子中是~/lab/blogs/themes。然后在pelicanconf.py和publishconf.py里通过下面代码指定博客主题:

>>> THEME = "themes/foundation-default-colours"

通常的做法是,选中一个自己喜欢的主题后,会进行一些定制。Pelican使用Jinja2来配置主题。一个主题的典型结构如下:

├── static
│   ├── css
│   └── images
└── templates
    ├── analytics_cnzz.html // 这个是我添加的使用cnzz的统计服务的代码
    ├── analytics.html      // 这是Google Analytics的代码
    ├── archives.html       // 这个是博客归档页面的模板
    ├── article.html        // 这个是博客正文的显示模板
    ├── base.html           // 这个是所有页面的父类模板,即所有页面都引用这个页面。比如网页导航栏啊之类的,都定义在这里
    ├── categories.html     // 所有博客文章的分类列表
    ├── category.html       // 某个博客分类的文章列表模板
    ├── index.html          // 主页
    ├── page.html           // 分页显示的模板
    ├── tag.html            // 某类标签下的文章列表
    └── tags.html           // 所有的标签列表页面模板

稍微有点Jinja的知识加上一些HTML和CSS的知识,就可以自己定义主题了。

(为什么博客主页打开半天都不显示出来,因为GFW封锁了几乎所有和Google相关的网站,这些主题里又用了Google的字体,所以下载这些字体时会导致无法下载成功而半天不显示网页。解决方案很简单,直接修改css文件,不去下载Google字体即可。比如针对foundation-default-colours主题,打开主题根目录下的static/css/foundation.css和static/css/foundation.min.css文件,删除掉@import url("//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,700italic,400,300,700");内容即可。当然,如果你和你的读者都是翻墙高手,那就不会遇到这个问题了。 )

6.7.3. 撰写博客

在content目录下新建一个xxx.md,使用Makedown语法直接撰写文档即可。我在ubuntu下使用的是gedit,代码高亮效果很好。撰写博客的时候需要注意,Pelican支持一些元数据。比如,本文的元数据如下:

Title: 使用Pelican搭建博客系统
Date: 2014-10-07 22:20
Modified: 2014-10-07 23:04
Tags: python, pelican

Slug是文档的唯一标识,生成html时,会直接使用这个值当html的文件名。所以,不同博客文章这个值需要保证唯一性,否则生成html时会报错。

Slug: build-blog-system-by-pelican
Authors: Joey Huang
Summary: 本文介绍了Pelican的特性;选择Pelican的理由以及从头安装配置,搭建出一个可运行的独立博客系统。

Status: draft表示本文是草稿。比如我们一篇博客经常不是一次性写完的,写了一半暂不想让读者看到,或者写完想让别人帮忙审查一下,就可以加这一行标识。这样Pelican在处理时,这篇文章也会生成html,但不会放在博客的主页及分类索引里,这样普通的读者一般看不到这个文章。有这个标识的文章生成时放在output/drafts目录下,你就可以通过分享url的方式让你的co-worker帮你review你的文章。

Status: draft

我们可以在content目录下任意建立子目录来组织管理博客文章。由于我们在设置文件里指定这个值USE_FOLDER_AS_CATEGORY = True,这样这些目录名称就自动变成博文分类的目录了。

6.7.4. 预览博客文章

撰写文章的过程中,可以随时在浏览器里预览博客文章。方法是先在博客项目的根目录下执行下面命令来启动预览服务器:

make devserver

这条命令会自动使用pelicanconf.py的配置文件来生成html网页,同时在本地的8000端口上启动一个http服务器,供你预览文章。这样,直接打开浏览器,输入localhost:8000即可打开本地服务器上的你的博客主页。比如,撰写本文时,我就直接在gedit里码字,然后在浏览器里输入http://localhost:8000/drafts/build-blog-system-by-pelican.html 来实时预览效果。需要注意的是,上述命令会在后台持续监听content目录下的内容,如果这个目录下的内容发生变化,会自动重新生成html页面。所以,在gedit里写完一段内容,切换到浏览器,直接刷新一下就可以看到最新的结果了。

当文章写完后,需要在博客项目根目录上运行make stopserver来停止这个预览服务以及数据监控功能。

文章在主页上没看到?

撰写完文章,需要发布时,需要把Status: draft这行元数据去掉。否则文章不会出现在博客主页。只会在drafts下看得到。

6.7.5. 发布博客

写完博客,我们想发布到网上。这个时候我们就需要一个主机和一个域名,我的独立博客系统用到的下面资源:

  • Amazon EC2主机。一个帐户可以免费使用一年。

  • 申请独立域名。我是通过阿里云直接在万网上注册的。

我的博客运行的软件环境:

  • Ubuntu 14.04 Server版,运行在Anazon EC2主机上

  • Nginx

6.7.6. 配置Nginx

Ubuntu下安装Nginx:

sudo apt-get install nginx-full

安装完成后,编辑配置文件:

sudo vim /etc/nginx/sites-enabled/default

将配置文件替换成如下的内容:

server {
  listen 80 default_server;
  server_name localhost;
  root /home/kamidox/lab/blogs/output;
  location / {
    index index.html;
  }
}
  1. 第3行:这个是服务器地址。这里使用本机作为测试服务器就填localhost,如果是配置服务器,就要填服务器的域名。比如我的服务器上,这行是配置成kamidox.com。

  2. 第4行:这个设置成博客文章的根目录。这个使用本机作为测试服务器,所以直接填博客项目的output目录。如果是在服务器上,我是直接配置成/home/ubuntu/blogs。

配置完成后,重启一下Nginx服务:

sudo service nginx resart

然后在浏览器里输入localhost就可以看到博客首页。在本机验证成功Nginx配置后,就可以用SSH登录服务器去配置服务器了。

6.7.7. 上传博客到服务器

直接在项目根目录下运行下面的命令即可把文章上传到博客服务器:

make rsync_upload

因为我们在前文已经配置了Makefile文件。所以运行这个命令之后,就会使用publishconf.py来生成html,并且通过rsync上传到服务器Amazon EC2服务器的/home/ubuntu/blogs/目录下。

配置Amazon EC2主机

发布博客到服务器上,需要先完成Amazon EC2主机的配置。具体可参阅Amazon官网上的文档。如果还没有主机,也可以把自己的电脑配置成服务器来作试验,所要做的,就是修改Makefile里的SSH_HOST的值为localhost即可。