用Pelican创建静态博客网站

基于 Pelicanniu-x2-sidebar 主题的静态博客网站在 python3.4 下尝试多次,均不能成功,后试过 python2.7 ,第一次成功,后又有配置问题导致显示不正常,经过多方调试,终得以成功,记录下安装及配置的过程,用于留存。

创建运行环境

创建虚拟环境

$ cd ~
$ virtualenv -p python2 env2p
New python executable in env2p/bin/python
Installing setuptools, pip, wheel...done.

$ cd env2p
$ source bin/activate
(env2p) $ pip list
pip (7.1.2)
setuptools (18.2)
urllib3 (1.12)
wheel (0.24.0)

安装 pelican 支持

(env2p) $ pip install pelican markdown
......
Installing collected packages: pygments, pytz, six, feedgenerator, unidecode, python-dateutil, MarkupSafe, jinja2, docutils, blinker, pelican, markdown
Successfully installed MarkupSafe-0.23 blinker-1.4 docutils-0.12 feedgenerator-1.7 jinja2-2.8 markdown-2.6.2 pelican-3.6.3 pygments-2.0.2 python-dateutil-2.4.2 pytz-2015.6 six-1.9.0 unidecode-0.4.18
(env2p) $ pip list
blinker (1.4)
docutils (0.12)
feedgenerator (1.7)
Jinja2 (2.8)
Markdown (2.6.2)
MarkupSafe (0.23)
pelican (3.6.3)
pip (7.1.2)
Pygments (2.0.2)
python-dateutil (2.4.2)
pytz (2015.6)
setuptools (18.2)
six (1.9.0)
Unidecode (0.4.18)
urllib3 (1.12)
wheel (0.24.0)

创建静态博客文件目录结构及初始配置

(env2p) $ mkdir blog
(env2p) $ cd blog
(env2p) $ pelican-quickstart
Welcome to pelican-quickstart v3.6.3.

This script will help you create a new Pelican-based website.

Please answer the following questions so this script can generate the files
needed by Pelican.


> Where do you want to create your new web site? [.] 
> What will be the title of this web site? STEPUP
> Who will be the author of this web site? 蜗牛
> What will be the default language of this web site? [en] zh
> Do you want to specify a URL prefix? e.g., http://example.com   (Y/n) 
> What is your URL prefix? (see above example; no trailing slash) http://snailhome.github.io
> Do you want to enable article pagination? (Y/n) 
> How many articles per page do you want? [10] 
> What is your time zone? [Europe/Paris] Asia/Shanghai
> Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) 
> Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) 
> Do you want to upload your website using FTP? (y/N) 
> Do you want to upload your website using SSH? (y/N) 
> Do you want to upload your website using Dropbox? (y/N) 
> Do you want to upload your website using S3? (y/N) 
> Do you want to upload your website using Rackspace Cloud Files? (y/N) 
> Do you want to upload your website using GitHub Pages? (y/N) y
> Is this your personal page (username.github.io)? (y/N) y
Done. Your new project is available at /home/snail/env2p/blog

安装 niu-x2-sidebar 主题模板

安装系统依赖

对于Debian系:

$ sudo apt-get install python-dev libjpeg-dev zlib1g-dev

对于openSUSE:

$ sudo zypper in gcc make git
$ sudo zypper in python-devel libjpeg8-devel zlib-devel

这些都是Pillow需要用到的。

生成zh_CN.UTF-8 locale

$ sudo locale-gen zh_CN.UTF-8

openSUSE默认就是,可以不用设置这个

安装 python 依赖

上面的主题或插件的额外依赖

pelican-minify: 压缩html文件 beautifulsoup4: 解析html文件 Pillow: PIL

使用pip安装

(env2p) $ pip install pelican-minify beautifulsoup4 Pillow
......
Installing collected packages: htmlmin, pelican-minify, beautifulsoup4, Pillow
Successfully installed Pillow-3.0.0 beautifulsoup4-4.4.1 htmlmin-0.1.10 pelican-minify-0.8
(env2p) $ pip list
beautifulsoup4 (4.4.1)
blinker (1.4)
docutils (0.12)
feedgenerator (1.7)
htmlmin (0.1.10)
Jinja2 (2.8)
Markdown (2.6.2)
MarkupSafe (0.23)
pelican (3.6.3)
pelican-minify (0.8)
Pillow (3.0.0)
pip (7.1.2)
Pygments (2.0.2)
python-dateutil (2.4.2)
pytz (2015.6)
setuptools (18.2)
six (1.9.0)
Unidecode (0.4.18)
urllib3 (1.12)
wheel (0.24.0)

安装 niu-x2-sidebar 主题

(env2p) $ mkdir themes
(env2p) $ cd themes
(env2p) $ git clone https://github.com/mawenbao/niu-x2-sidebar.git
(env2p) $ ls
niu-x2-sidebar
(env2p) $ cd ..

安装 niu-x2-sidebar 主题插件

extract_headings插件: 从html文件里提取h1~h6标题并生成目录列表 niux2_hermit_player插件: 音频播放器 niux2_lazyload_helper插件: 延迟加载图片 pelican-update-date插件: 提取文章内的修改时间 sitemap插件: 生成sitemap summary插件: 提取第一句话作为摘要

(env2p) $ mkdir plugins
(env2p) $ cd plugins
(env2p) $ git clone https://github.com/mawenbao/extract_headings.git
(env2p) $ git clone https://github.com/mawenbao/niux2_hermit_player.git
(env2p) $ git clone https://github.com/mawenbao/niux2_lazyload_helper.git
(env2p) $ git clone https://github.com/mawenbao/pelican-update-date.git
(env2p) $ cd ../../
(env2p) $ git clone https://github.com/getpelican/pelican-plugins.git
(env2p) $ cp -R pelican-plugins/sitemap blog/plugins/
(env2p) $ cp -R pelican-plugins/summary blog/plugins/
(env2p) $ cd blog
(env2p) $ ls plugins
extract_headings     niux2_lazyload_helper  sitemap
niux2_hermit_player  pelican-update-date    summary

配置 pelicanconf.py

复制了原作者关于Pelican静态博客搭建总结的配置,并作了适当修改

#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
from collections import OrderedDict
import datetime

AUTHOR = u'蜗牛'
SITENAME = u'STEPUP'
SITEURL = ''

TIMEZONE = 'Asia/Shanghai'
DATE_FORMATS = {
        'zh_CN': '%Y-%m-%d %H:%M:%S',
}
DEFAULT_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
DEFAULT_DATE = 'fs'  # use filesystem's mtime
LOCALE = ('zh_CN.utf8',)
DEFAULT_LANG = u'zh_CN'
FILENAME_METADATA = '(?P<slug>.*)'
#GOOGLE_ANALYTICS = 'XXXXXX'
# feed config
FEED_DOMAIN = SITEURL
FEED_ALL_RSS = 'feed.xml'
FEED_MAX_ITEMS = 20
FEED_ALL_ATOM = None
CATEGORY_FEED_ATOM = None
TRANSLATION_FEED_ATOM = None
# use directory name as category if not set
USE_FOLDER_AS_CATEGORY = True
DELETE_OUTPUT_DIRECTORY = True
DEFAULT_CATEGORY = 'uncategorized'
DEFAULT_PAGINATION = 7

READERS = {
    'html': None,
}

STATIC_PATHS = [
    'images',
    'static',
    'extra',
]
EXTRA_PATH_METADATA = {
    'extra/CNAME': { 'path': 'CNAME' },
    'extra/.nojekyll': { 'path': '.nojekyll' },
    'extra/README': { 'path': 'README.md' },
    'extra/favicon.ico': { 'path': 'favicon.ico' },
    'extra/LICENSE.txt': { 'path': 'LICENSE.txt' },
    'extra/robots.txt': { 'path': 'robots.txt' },
    'extra/BingSiteAuth.xml': {'path': 'BingSiteAuth.xml' },
}

ARTICLE_URL = '{category}/{slug}.html'
ARTICLE_SAVE_AS = ARTICLE_URL
PAGE_URL = '{slug}.html'
PAGE_SAVE_AS = PAGE_URL
CATEGORY_URL = '{slug}/index.html'
CATEGORY_SAVE_AS = CATEGORY_URL
TAG_URL = 'tag/{slug}.html'
TAG_SAVE_AS = TAG_URL
TAGS_SAVE_AS = 'tag/index.html'
# disable author pages
AUTHOR_SAVE_AS = ''
AUTHORS_SAVE_AS = ''

TEMPLATE_PAGES = {
    "404.html": "404.html",
    "archives_updatedate.html": "archives_updatedate.html",
}
JINJA_EXTENSIONS = [
    'jinja2.ext.ExprStmtExtension',
]

# plugin config
PLUGIN_PATHS = ['./plugins']
PLUGINS = [
    #'pandoc_reader',
    #'gzip_cache',
    'pelican-update-date',
    'extract_headings',
    'sitemap',
    'summary',
    'niux2_lazyload_helper',
    'niux2_hermit_player',
    #'minify',
]
UPDATEDATE_MODE = 'metadata'

# extrac_headings plugin config
import md5
def my_slugify(value, sep):
    m = md5.md5(value.encode('UTF-8'))
    return m.digest().encode('hex')[:6]
MY_SLUGIFY_FUNC = my_slugify
MY_TOC_LIST_TYPE = 'ol'

# niux2_lazyload_helper plugin config
import os
def my_img_url_2_path(url):
    if not url.startswith('//static.atime.me'):
        print("ignore " + url)
        return ''
    return os.path.abspath(os.path.join('content', 'static', url[1 + url.index('/', 2):]))
MY_IMG_URL2PATH_FUNC = my_img_url_2_path

from markdown.extensions import codehilite
MD_EXTENSIONS = ([
    'extra',
    'footnotes',
    'tables',
    codehilite.CodeHiliteExtension(configs=[('linenums', False), ('guess_lang', False)]),
])

# sitemap plugin config
SITEMAP = {
    'format': 'xml',
    'priorities': {
        'articles': 0.5,
        'indexes': 0.5,
        'pages': 0.5
    },
    'changefreqs': {
        'articles': 'weekly',
        'indexes': 'daily',
        'pages': 'monthly'
    }
}

# cache policy, currently no cache
LOAD_CONTENT_CACHE = False
CACHE_CONTENT = False
#CHECK_MODIFIED_METHOD = 'md5'

# theme config
THEME = './themes/niu-x2-sidebar'
NIUX2_DEBUG = False

# niu-x2 theme config
NIUX2_AUTHOR_TRANSL = '作者'
NIUX2_404_TITLE_TRANSL = '404错误 页面未找到!'
NIUX2_404_INFO_TRANSL = '请求页面未找到!'
NIUX2_TAG_TRANSL = '标签'
NIUX2_ARCHIVE_TRANSL = '存档'
NIUX2_ARCHIVE_UPDATEDATE_TRANSL = '存档 (按修改时间)'
NIUX2_CATEGORY_TRANSL = '分类'
NIUX2_TAG_CLEAR_TRANSL = '清空'
NIUX2_TAG_FILTER_TRANSL = '过滤标签,不妨试试[0-9]{3}'
NIUX2_HEADER_TOC_TRANSL = '目录'
NIUX2_SEARCH_TRANSL = '搜索'
NIUX2_SEARCH_PLACEHOLDER_TRANSL = '按回车开始搜索 ...'
NIUX2_COMMENTS_TRANSL = '评论'
NIUX2_PUBLISHED_TRANSL = '发布时间'
NIUX2_LASTMOD_TRANSL = '最后修改'
NIUX2_PAGE_TITLE_TRANSL = '页面'
NIUX2_RECENT_UPDATE_TRANSL = '最近修改'
NIUX2_HIDE_SIDEBAR_TRANSL = '隐藏侧边栏'
NIUX2_SHOW_SIDEBAR_TRANSL = '显示侧边栏'
NIUX2_REVISION_HISTORY_TRANSL = '修订历史'
NIUX2_VIEW_SOURCE_TRANSL = '查看源文件'

NIUX2_DUOSHUO_SHORTNAME = 'snailhome'
#NIUX2_DUOSHUO_THREAD_KEY = 'slug'
NIUX2_PYGMENTS_THEME = 'github'
NIUX2_PAGINATOR_LENGTH = 11
NIUX2_RECENT_UPDATE_NUM = 10
NIUX2_FAVICON_URL = '/favicon.ico'
NIUX2_GOOGLE_CSE_ID = 'XXXXXX'
NIUX2_DISPLAY_TITLE = True
NIUX2_LAZY_LOAD = True
NIUX2_LAZY_LOAD_TEXT = 'orz 努力加载中'
NIUX2_LAZY_LOAD_ICON = 'icon-spin icon-spinner2'
NIUX2_TOOLBAR = True
NIUX2_TOOLBAR_LOAD_ICON = 'icon-spin icon-4x icon-spinner9'

NIUX2_LIB_FONT_ICONS = '/theme/font-icons'
NIUX2_LIB_JQUERY = '/theme/js/jquery-1.11.0.min.js'
NIUX2_LIB_BOOTSTRAP = '/theme'

NIUX2_CATEGORY_MAP = {
    'code': ('代码', 'icon-code'),
    'collection': ('搜藏', 'icon-briefcase'),
    'essay': ('随笔', 'icon-leaf'),
    'life': ('日常', 'icon-coffee'),
    'note': ('笔记', 'icon-book'),
    'research': ('研究', 'icon-flask'),
}

NIUX2_HEADER_SECTIONS = [
    ('关于', '关于本网站', '/about.html', 'icon-anchor'),
    #('使用协议', '使用协议', '/agreement.html', 'icon-exclamation-circle'),
    #('项目', '我的项目', '/my_projects.html', 'icon-rocket'),
    ('标签', '标签', '/tag/', 'icon-tag'),
]

NIUX2_HEADER_DROPDOWN_SECTIONS = OrderedDict()
NIUX2_HEADER_DROPDOWN_SECTIONS[('存档', 'icon-archive')] = [
    ('存档 (按发布时间)', 'archives order by publish time', '/archives.html', 'icon-calendar'),
    ('存档 (按修改时间)', 'archives order by modify time', '/archives_updatedate.html', 'icon-pencil'),
]

NIUX2_FOOTER_LINKS = [
    ('关于', '关于', '/about.html', ''),
    #('使用协议', 'terms, license and privacy etc.', '/agreement.html', ''),
    #('XICP备XXX号', '备案号', '/', ''),
]

NIUX2_FOOTER_ICONS = [
    #('icon-key', 'my public key', '/my_gnupg.html'),
    ('icon-envelope-o', '我的邮箱', 'mailto: snail.zh@gmail.com'),
    ('icon-github-alt', '我的GithubPage', 'http://github.com/snailhome'),
    ('icon-rss', 'RSS', '/feed.xml'),
]

创建内容目录下的相关子目录

(env2p) $ cd content
(env2p) $ mkdir pages
(env2p) $ mkdir static
(env2p) $ mkdir extra
(env2p) $ mkdir code
(env2p) $ mkdir collection
(env2p) $ mkdir essay
(env2p) $ mkdir life
(env2p) $ mkdir note
(env2p) $ mkdir research
(env2p) $ ls
code  collection  essay  extra  life  note  pages  research  static

本地生成测试

生成输出文件

(env2p) $ make html

查看网站生成的效果

(env2p) $ make serve

然后打开浏览器,输入 http://127.0.0.1:8000 就可以看到网站的效果了。 也可以把上面两步并成一步,自动检测文件更新并生成 html

运行测试服务器

(env2p) $ make devserver

这个方法会自动监测文件的修改,并自动生成网站,

所以当我们修改.md文件保存后,直接刷新 http://127.0.0.1:8000 就可以看到更新后的效果了。

发布并git

生成ssh密钥

(env2p) $ cd ~/.ssh
(env2p) $ ls
config  id_rsa  id_rsa.pub  known_hosts
(env2p) $ mkdir key_backup
(env2p) $ cp id_rsa* key_backup
(env2p) $ rm id_rsa*
(env2p) $ ssh-keygen -t rsa -C "邮件地址@youremail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/your_user_directory/.ssh/id_rsa):<回车就好>
Enter passphrase (empty for no passphrase):<输入加密串>
Enter same passphrase again:<再次输入加密串>

添加SSH Key到GitHub:

在本机设置SSH Key之后,需要添加到GitHub上,以完成SSH链接的设置。

用文本编辑工具打开id_rsa.pub文件,如果看不到这个文件,你需要设置显示隐藏文件。准确的复制这个文件的内容,才能保证设置的成功。

在GitHub的主页上点击设置按钮:

选择SSH Keys项,把复制的内容粘贴进去,然后点击Add Key按钮即可。

ssh连接测试

可以输入下面的命令,看看设置是否成功,git@github.com的部分不要修改:

$ ssh -T git@github.com
Hi <em>username</em>! You've successfully authenticated, but GitHub does not provide shell access.

如果有这个显示,就表示SSh连接是成功的。

下面我们就可以git网站了。

git静态网站

git前

(env2p) $ git config --global user.email "you@example.com"
(env2p) $ git config --global user.name "Your Name"

初次git时

(env2p) $ cd output
(env2p) $ git init
(env2p) $ git add .
(env2p) $ git remote add origin https://github.com/snailhome/snailhome.github.io.git
(env2p) $ git commit -m "First Updated"
(env2p) $ git push -u origin master

提示出错,貌似要先 pull 一下,于是

(env2p) $ git pull origin master
(env2p) $ git commit -a
(env2p) $ git push -u origin master

推送成功。

一般而言, git init 后需要(未证实必须) $ git pull origin master //先同步远程文件,后面的参数会自动连接你远程的文件 $ git status //查看本地自己修改了多少文件,此步非必须 $ git add . //添加远程不存在的git文件 $ git commit * -m "what I want told to someone" //备注信息 $ git push origin master //更新到远程服务器上

以后每次要推送时

(env2p) $ make publish
(env2p) $ cd output
(env2p) $ git add -A
(env2p) $ git commit -m "Commit Info"
(env2p) $ git push -u origin master

就可以了~~

为了方便操作我做了别名

$ vim ~/.bashrc

#输入以下别名设置
alias sa='source bin/activate'
alias da='deactivate'
alias git2p='cd ~/env2p/blog&&make publish&&cd output&& git add -A&&git commit -m "Commit Info"&&git push -u origin master&&cd -'

$ source ~/.bashrc  ## 即时生效

这样,我打开终端输入 sa 就直接进入虚拟环境,输入 git2p 就直接生成发布文档并git到我的page里,输入 da 就直接退出虚拟环境。

但是还不够好,每次都需要输入用户名和密码,可以免输用户名和密码吗?

设置git时免输用户名和密码

(env2p) $ cd output/.git
(env2p) $ vim config

看到这一段

[remote "origin"]
        url = https://github.com/yourname/yourname.github.io.git

将其改为:

[remote "origin"]
        url = https://yourname:password@github.com/yourname/yourname.github.io.git

当然,这个操作最好是在自己的机器上,毕竟用户名和密码明文放在上面,在其它机器上还是老老实实输入用户名和密码吧。

发布时间:
2015-10-05 00:00
分类:
标签: