Pelican Static Site Generator, Powered by Python: Pelican是python语言写的静态网站生成器, Pelican 是那些想要自我托管简单网站或博客的 Python 用户的绝佳选择。
为什么选择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上代码提交活跃。
最后两点对使用任何开源工具来说都是很重要的,只有开发活跃,社区资源多, 文档齐全,遇到问题的时候才能较快地得到解决。
# pip install pelican markdown
Collecting pelican Downloading pelican-4.11.0-py3-none-any.whl.metadata (5.3 kB) Requirement already satisfied: markdown in /opt/conda/lib/python3.12/site-packages (3.6) Requirement already satisfied: blinker>=1.7.0 in /opt/conda/lib/python3.12/site-packages (from pelican) (1.9.0) Collecting docutils>=0.20.1 (from pelican) Using cached docutils-0.21.2-py3-none-any.whl.metadata (2.8 kB) Collecting feedgenerator>=2.1.0 (from pelican) Downloading feedgenerator-2.1.0-py3-none-any.whl.metadata (1.8 kB) Requirement already satisfied: jinja2>=3.1.2 in /opt/conda/lib/python3.12/site-packages (from pelican) (3.1.5) Collecting ordered-set>=4.1.0 (from pelican) Downloading ordered_set-4.1.0-py3-none-any.whl.metadata (5.3 kB) Collecting pygments<2.19.0,>=2.16.1 (from pelican) Downloading pygments-2.18.0-py3-none-any.whl.metadata (2.5 kB) Requirement already satisfied: python-dateutil>=2.8.2 in /opt/conda/lib/python3.12/site-packages (from pelican) (2.9.0.post0) Collecting rich>=13.6.0 (from pelican) Downloading rich-14.0.0-py3-none-any.whl.metadata (18 kB) Collecting unidecode>=1.3.7 (from pelican) Downloading Unidecode-1.3.8-py3-none-any.whl.metadata (13 kB) INFO: pip is looking at multiple versions of pelican to determine which version is compatible with other requirements. This could take a while. Collecting pelican Downloading pelican-4.10.2-py3-none-any.whl.metadata (5.4 kB) Requirement already satisfied: pygments>=2.16.1 in /opt/conda/lib/python3.12/site-packages (from pelican) (2.19.1) Downloading pelican-4.10.1-py3-none-any.whl.metadata (5.4 kB) Downloading pelican-4.10.0-py3-none-any.whl.metadata (5.4 kB) Downloading pelican-4.9.1-py3-none-any.whl.metadata (5.4 kB) Downloading pelican-4.9.0-py3-none-any.whl.metadata (5.3 kB) Downloading pelican-4.8.0-py3-none-any.whl.metadata (4.5 kB) Requirement already satisfied: pytz>=2020.1 in /opt/conda/lib/python3.12/site-packages (from pelican) (2025.1) Requirement already satisfied: MarkupSafe>=2.0 in /opt/conda/lib/python3.12/site-packages (from jinja2>=3.1.2->pelican) (3.0.2) Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pelican) (1.17.0) Collecting markdown-it-py>=2.2.0 (from rich>=13.6.0->pelican) Downloading markdown_it_py-3.0.0-py3-none-any.whl.metadata (6.9 kB) Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich>=13.6.0->pelican) Downloading mdurl-0.1.2-py3-none-any.whl.metadata (1.6 kB) Downloading pelican-4.8.0-py3-none-any.whl (1.4 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 319.7 kB/s eta 0:00:00a 0:00:01 Downloading docutils-0.21.2-py3-none-any.whl (587 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 587.4/587.4 kB 726.0 kB/s eta 0:00:00:--:-- Downloading feedgenerator-2.1.0-py3-none-any.whl (21 kB) Downloading rich-14.0.0-py3-none-any.whl (243 kB) Downloading Unidecode-1.3.8-py3-none-any.whl (235 kB) Downloading markdown_it_py-3.0.0-py3-none-any.whl (87 kB) Downloading mdurl-0.1.2-py3-none-any.whl (10.0 kB) Installing collected packages: unidecode, mdurl, feedgenerator, docutils, markdown-it-py, rich, pelican Successfully installed docutils-0.21.2 feedgenerator-2.1.0 markdown-it-py-3.0.0 mdurl-0.1.2 pelican-4.8.0 rich-14.0.0 unidecode-1.3.8 Note: you may need to restart the kernel to use updated packages.
创建博客项目:
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 # 这个是发布时的配置文件
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_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
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
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");
内容即可。
当然,如果读者都是翻墙高手,那就不会遇到这个问题了。)
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文章。
可以在content目录下任意建立子目录来组织管理博客文章。
由于在设置文件里指定这个值USE_FOLDER_AS_CATEGORY = True
,
这样这些目录名称就自动变成博文分类的目录了。
这条命令会自动使用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
下看得到。
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;
}
}
- 第3行:这个是服务器地址。这里使用本机作为测试服务器就填localhost,
如果是配置服务器,就要填服务器的域名。比如服务器上,这行是配置成
kamidox.com
。 - 第4行:这个设置成博客文章的根目录。这个使用本机作为测试服务器,
所以直接填博客项目的output目录。如果是在服务器上,
是直接配置成
/home/ubuntu/blogs
。
配置完成后,重启一下Nginx服务:
sudo service nginx resart
在浏览器里输入localhost就可以看到博客首页。在本机验证成功Nginx配置后,就可以用SSH登录服务器去配置服务器了。
make rsync_upload
因为在前文已经配置了Makefile文件。所以运行这个命令之后,
就会使用publishconf.py
来生成html,
并且通过rsync上传到服务器Amazon EC2服务器的/home/ubuntu/blogs/
目录下。
配置Amazon EC2主机:发布博客到服务器上,需要先完成Amazon EC2主机的配置。
具体可参阅Amazon官网上的文档。
如果还没有主机,也可以把自己的电脑配置成服务器来作试验,
所要做的,就是修改Makefile里的SSH_HOST
的值为localhost即可。