使用 pelican+git+ 码云 pages 建立静态 markdown 博客全过程
- 2024-09-15:更新了一下样式。
依赖工具
- python(我用的是 2.7 的最新版,会把下面的工具都带上)
- easy_install
- pip
安装必要程序
pip install pelican markdown
注意,有时候,还会使用工具 virtualenv
。具体用途,请自行查阅相关资料,不过基本不用 python 进行大型开发也就基本用不上这个。
创建目录
在你要放置博客基本框架的位置,建立一个文件夹。直接手工建立就好。
快速开始
在文件夹中,可以使用命令 pelican-quickstart
进行快速设置建立一些基本的文件。会问一系列问题,比如博客网址啊,作者名字啊之类的,根据真实情况填写即可,这些问题只是用来生成配置文件的,后面可以通过修改配置文件来手动修改这些设置。结果会生成一个目录,大体如下:
.
├── content # 这个就是放博客内容目录,这个目录及子目录下的所有 md 和 rst 文件将会被转成 html 文件
├── output # 这个是从 content 目录生成的 html 目标文件的存放目录
├── develop\_server.sh #这个是用来在本地运行一个服务器来实时查看生成的html文档的脚本
├── fabfile.py # 这个是使用 Python 的 fabric 来实现文件上传的工具,即 Deploy 工具
├── Makefile # 这个是使用是用来生成网站内容并上传的工具。
├── pelicanconf.py # 这个是本地开发时的配置文件
└── publishconf.py # 这个是发布时的配置文件
其中,由于我们是使用 git 来进行内容更新,所以基本使用的就是下面这些文件及文件夹
├── content # 这个就是放博客内容目录,这个目录及子目录下的所有 md 和 rst 文件将会被转成 html 文件
├── output # 这个是从 content 目录生成的 html 目标文件的存放目录
├── develop\_server.sh #这个是用来在本地运行一个服务器来实时查看生成的html文档的脚本
├── pelicanconf.py # 这个是本地开发时的配置文件
个性化配置
经过之前的设置,出来的 pelicanconf.py
文件内容已经有了雏形,但是对于进一步的个性化,是远远不够的,还需要我们继续添加修改内容。至于能添加哪些内容,移步 文档
关于日后自行添加个性选项要注意,原本的内容都是这样:AUTHOR = u'yourname'
,要注意,等号左边为全部大写的字母。如果感兴趣可以看我的使用 nest 主题的 pelicanconf.py1
关于 publishconf.py
与 Makefile
我没有使用过,具体请自己查阅文档。我的使用,就没用到。
配置主题,插件
当前查看效果的方式可以使用本地预览。即:先在 根目录
下使用
pelican content
cd output
python -m pelican.server
然后打开 http://localhost:8000
查看效果
Pelican 支持大量的开源主题,GitHub 上的 pelican-themes 项目有几十套主题,大部分都带了效果预览图。可以从里面挑一个你喜欢的主题样式来使用。
还有一个更方便的挑选主题的方式,直接打开 www.pelicanthemes.com 挑选吧。一个网页里就列出了几乎所有的主题。我的博客是使用 nest 主题,并在这套主题的基础上进行了一些定制。
选定好喜欢的主题后,从 GitHub 上下载下来所有的主题:git clone https://github.com/getpelican/pelican-themes.git
我直接将其解压成了根目录下的 pelican-themes
文件夹,所以下文中的主题目录用的就是这个。要注意,有些主题,这个仓库里是不包含的,只有一个空文件夹,就像 nest
,想要时到 github 上去搜索就好。
然后在 pelicanconf.py
配置文件里添加或修改 THEME
项为 nest
:THEME = "nest"
(我使用了几个主题,觉得还是 nest 的汉化还是很方便的,作者很贴心的将参数剥离出来)
Pelican 一开始是将插件内置的, 但是新版本 Pelican 将插件隔离了出来, 所以要到 github 上 克隆一份新的插件,执行 git clone git://github.com/getpelican/pelican-plugins.git
,内容放在根目录下 pelican-plugins
文件夹下。
现在博客目录就新添了一个 pelican-plugins
目录,以配置 sitemap
插件为例, sitemap
插件可以生成 sitemap.xml
供搜索引擎使用。
在 pelicanconf.py 中修改添加:
# 插件,render_math 提供数学公式的显示
# Plugin
PLUGIN_PATHS = ['pelican-plugins']
PLUGINS = [ 'sitemap', 'render_math']
# Sitemap
SITEMAP = {
"format": "xml",
"priorities": {
"articles": 0.7,
"indexes": 0.5,
"pages": 0.3,
},
"changefreqs": {
"articles": "monthly",
"indexes": "daily",
"pages": "monthly",
}
}
最后执行 pelican content
就会在 output
中生成相关的 html 文件
静态目录
PATH = 'content'
PAGE_PATHS = ['pages']
ARTICLE_PATHS = ['articles']
STATIC_PATHS = ['images', 'extra/robots.txt', 'extra/favicon.ico', 'extra/logo.svg', 'charity']
EXTRA_PATH_METADATA = {
'extra/robots.txt': {'path': 'robots.txt'},
'extra/favicon.ico': {'path': 'favicon.ico'},
'extra/logo.svg': {'path': 'logo.svg'},
'charity/404.html': {'path': '404.html'}
}
注意这部分设置,在 content
下放置着写博客要用到的一些内容,因为毕竟是 content -> output 内容的转换。所以尤其要注意这里的设置。
这里有博文,图片,一些有些主题会用到的文档,图标,头像甚至是 404 页面都有放置在对应的文件目录下。
这些目录是可以自己设置的,但是尽量是归好类。
关于静态目录:
A list of directories (relative toPATH
) in which to look forstatic files
. Such files will be copied to the output directory without modification. Articles, pages, and other content source files will normally be skipped, so it is safe for a directory to appear both here and inPAGE_PATHS
orARTICLE_PATHS
. Pelican’s default settings include the “images” directory here.
写博文
pelican 写博文,需要在 md 文档最前面加上元数据,下面是个例子,具体用哪些数据,还得看主题的代码上怎么设定,在主题的 readme.md 文件中若有增加,一般有提示,一般的如下例:
Title: winsows效率之bat文件1
Date: 2017-02-18 17:07:19
Category: 效率
Tags: bat
Slug: bat1
Author: yourname
Status: draft
元数据后要与文本内容空一行以表示元数据的结束。
Status: draft
会让文章不显示,默认为草稿。撰写完文章,需要发布时,需要把这行元数据去掉。否则文章不会出现在博客主页。只会在 drafts 下看得到:你的网址/drafts
。“你的网址”指提交的网站,或者本地预览时的 http://localhost:8000/
使用上面的网址就可以看到。
发布博客
要发布在网上,一般的会使用代码托管网站的 page 服务。我所知道的有三个站点提供:
- 码云
- Coding
- GitHub
相比之下,感觉码云稍快一些,但是 Coding 有提供 https 协议。而 github 不多说。大家自己选择。我用的是码云。
申请账号,创建项目,使用 pages,码云文档做的不错,直接 过去看 就好。这里甚至提到了如何使用 404 页面。实际上就是放置到 output 目录下。
一切准备就绪后,可以在使用过命令 pelican content
后, 进入 output,使用 git。
git init
git add .
git commit -m "pelican static blog test"
git remote add origin https://git.oschina.net/yourname/yourname.git
# 我的仓库地址就是:git@git.oschina.net:yourname/yourname.git
git push -u origin master
要是运行这个后出现:
To ...(地址)
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/yourname/pelican-nest-blog.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
可以尝试使用命令:git push -u origin master -f
由于我是用的是 windows,现在的博文推送方式有点麻烦,可以写 bat 文件简化流程。
由于安装 git 后,实际上是可以在 cmd 中使用的。于是有:
@eche off
@title 本地预览pelican博客
echo 进入文件夹
rem 这是我的content所在目录
cd /d D:\git clone\BLOG\yourname\yourname
echo 执行pelican content
pelican content
echo 进入output
cd /d output
echo 启动本地服务器
python -m pelican.server
echo 结束...
echo 请前往 http://localhost:8000/ 查看
pause
文件之推送博文:
@echo off
@title bat交互执行git命令
echo 进入文件夹
cd /d D:\git clone\BLOG\yourname\yourname
echo 执行pelican content
pelican content
echo 执行git
cd /d output
git add .
git commit -m "update"
git push origin master
echo done...
pause
直接使用这两个批处理就可以完成相应的任务。之后查看即可。
博客功能拓展
评论功能
pelican 支持 disqus 和谷歌分析:
DISQUS_SITENAME = ""
GOOGLE_ANALYTICS = ""
而国内可以换成(我所用的)友言或者多说,以及百度统计。具体如何置换,直接在文件夹中搜索关键字即可。
我用的是 sublime,文件夹中搜索,从搜索结果,进入对应文件中,修改你所用的主题的相应的代码块。这里只需要将对应标签下的内容进行置换就好。
至于用来置换的内容,见下:
以 友言(这里有分享按钮以及评论系统还有推荐系统的代码都可以尝试)为例:
- 获取代码
- 选择平台:通用代码
- 那个代码复制好,粘贴到对应的
DISQUS_SITENAME
所在的主题里的模板文件中,nest 主题是有个单独的文件,直接修改其中内容,if
语句中的内容不要改,相当于就是用原本的 DISQUS 的文件调用关系,使用我们的新内容。 - 置换完成后,在 pelicanconf 文件中
DISQUS_SITENAME = ""
里写点字符串,不要为空,这样就可以运行代码了。我是把该改的都改了,所以我的配置文件中有点不同。
同样的。百度统计 也是一样的。注册时,必要的信息是要准确的。
- 进入
- 管理
- 代码获取
- 按说明内容进行安装。
至于代码放置的方式,类似上面的,就不多说。这个相当于就是提供一个访问统计的一个后台,在博客网站页面上也看不出变化,但是在百度统计的我们的管理系统中,我们可以看到很多有用的数据。
尾声
至此,我的这几天的工作已经结束,虽然似乎没有太多的难度,但是对于我这样一个新手而言,却处处遇到困难。
这些内容也只是用到了 pelican 文档中不多的页面,所以可见,它的可塑空间还很大,大家可以积极改动尝试。
pelican 使用 markdown 写博客,python-markdown 的语法支持比常规的要丰富一点,所以可以看一下我的另一篇博文,那博文要是用在一般的 markdown 网站上,有些格式就显示不正常。 python-markdown
#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
# Site settings
AUTHOR = u'yourname'
AUTHOR_EMAIL = u'your-email'
SITENAME = u'果园'
SITEURL = 'http://yourname.oschina.io'
DEFAULT_DATE_FORMAT = ('%Y-%m-%d')
TIMEZONE = 'Asia/Shanghai'
DEFAULT_LANG = u'zh'
DEFAULT_METADATA = (
)
DELETE_OUTPUT_DIRECTORY = False
# Blogroll
LINKS = (
('果园', 'http://yourname.coding.me'),
)
#######可以改动社交链接
# Social widget
SOCIAL = (
('码云(yourname)', 'https://git.oschina.net/yourname'),
('Coding(yourname)', 'https://coding.net/u/yourname'),
)
# 几乎所有的博客主题都有一个地方展示你的社交账号,这些账号就写在这里,上面是我的
# A list of tuples (Title, URL) for additional menu items to appear at the beginning of the main menu.
MENUITEMS = (
)
# Content path
PATH = 'content'
PAGE_PATHS = ['pages']
ARTICLE_PATHS = ['articles']
STATIC_PATHS = ['images', 'extra/robots.txt', 'extra/favicon.ico', 'extra/logo.svg', 'charity']
EXTRA_PATH_METADATA = {
'extra/robots.txt': {'path': 'robots.txt'},
'extra/favicon.ico': {'path': 'favicon.ico'},
'extra/logo.svg': {'path': 'logo.svg'},
'charity/404.html': {'path': '404.html'}
}
ARTICLE_URL = ('articles/{slug}.html')
ARTICLE_SAVE_AS = ('articles/{slug}.html')
PAGE_LANG_SAVE_AS = False
# Feed
FEED_DOMAIN = SITEURL
FEED_ALL_ATOM = 'feeds/all.atom.xml'
CATEGORY_FEED_ATOM = 'feeds/%s.atom.xml'
TRANSLATION_FEED_ATOM = None
# 每页博文数目
DEFAULT_PAGINATION = 5
# markdown设置
MARKDOWN = {
'extension_configs': {
'markdown.extensions.extra': {},
'markdown.extensions.admonition': {},
'markdown.extensions.codehilite': {'css_class': 'highlight'},
'markdown.extensions.meta': {},
'markdown.extensions.nl2br': {},
'markdown.extensions.sane_lists': {},
'markdown.extensions.smarty':{},
'markdown.extensions.toc': {},
'markdown.extensions.wikilinks': {},
},
'output_format': 'html5',
}
# 评论系统,我是用的是友言
# Comments
UY = "Comments"
# 我用的是百度统计
# Analytics
BAIDU = "Baidu"
# 插件,render_math 提供数学公式的显示
# Plugin
PLUGIN_PATHS = ['pelican-plugins']
PLUGINS = [ 'sitemap', 'render_math']
# Sitemap
SITEMAP = {
"format": "xml",
"priorities": {
"articles": 0.7,
"indexes": 0.5,
"pages": 0.3,
},
"changefreqs": {
"articles": "monthly",
"indexes": "daily",
"pages": "monthly",
}
}
# Can be useful in development, but set to False when you're ready to publish
RELATIVE_URLS = False
# 下面的就是nest主题的配置了,我把一些页面上的英文都简单汉化了。有的主题没有提供类似这样的参数,想改的去主题文件夹中更改。
# NEST Template
THEME = 'pelican-themes/nest'
SITESUBTITLE = u'我的 yourname'
# Minified CSS
NEST_CSS_MINIFY = True
# Add items to top menu before pages
MENUITEMS = [('果园', '/'),('类别','/categories.html')]
# Add header background image from content/images : 'background.jpg'
NEST_HEADER_IMAGES = 'background.jpg'
NEST_HEADER_LOGO = '/images/logo.png'
# Footer
NEST_SITEMAP_COLUMN_TITLE = u'目录'
NEST_SITEMAP_MENU = [('归档', '/archives.html'),('标签','/tags.html'), ('作者','/authors.html')]
NEST_SITEMAP_ATOM_LINK = u'Atom Feed'
NEST_SITEMAP_RSS_LINK = u'RSS Feed'
NEST_SOCIAL_COLUMN_TITLE = u'社交'
NEST_LINKS_COLUMN_TITLE = u'链接'
NEST_COPYRIGHT = u'果园 2017'
# Footer optional
NEST_FOOTER_HTML = ''
# index.html
NEST_INDEX_HEAD_TITLE = u'果园'
NEST_INDEX_HEADER_TITLE = u'林间果几颗'
NEST_INDEX_HEADER_SUBTITLE = u'一篇篇博客,就像一粒粒yourname,从思想最深处,逐渐结出'
NEST_INDEX_CONTENT_TITLE = u'旧果'
# archives.html
NEST_ARCHIVES_HEAD_TITLE = u'归档'
NEST_ARCHIVES_HEAD_DESCRIPTION = u'上传归档'
NEST_ARCHIVES_HEADER_TITLE = u'归档'
NEST_ARCHIVES_HEADER_SUBTITLE = u'收集起来的一篇篇博客,一粒粒yourname,都是时间的见证'
NEST_ARCHIVES_CONTENT_TITLE = u'归档'
# article.html
NEST_ARTICLE_HEADER_BY = u'作者 '
NEST_ARTICLE_HEADER_MODIFIED = u'修改于 '
NEST_ARTICLE_HEADER_IN = u'归类于 '
# author.html
NEST_AUTHOR_HEAD_TITLE = u'上传自 '
NEST_AUTHOR_HEAD_DESCRIPTION = u'上传自 '
NEST_AUTHOR_HEADER_SUBTITLE = u'上传归档'
NEST_AUTHOR_CONTENT_TITLE = u'上传'
# authors.html
NEST_AUTHORS_HEAD_TITLE = u'作者'
NEST_AUTHORS_HEAD_DESCRIPTION = u'作者'
NEST_AUTHORS_HEADER_TITLE = u'作者'
NEST_AUTHORS_HEADER_SUBTITLE = u'根据作者归档'
# categories.html
NEST_CATEGORIES_HEAD_TITLE = u'类别'
NEST_CATEGORIES_HEAD_DESCRIPTION = u'根据类别归档'
NEST_CATEGORIES_HEADER_TITLE = u'类别'
NEST_CATEGORIES_HEADER_SUBTITLE = u'根据类别归档'
# category.html
NEST_CATEGORY_HEAD_TITLE = u'类别归档'
NEST_CATEGORY_HEAD_DESCRIPTION = u'类别归档'
NEST_CATEGORY_HEADER_TITLE = u'类别'
NEST_CATEGORY_HEADER_SUBTITLE = u'类别归档'
# pagination.html
NEST_PAGINATION_PREVIOUS = u'上一页'
NEST_PAGINATION_NEXT = u'下一页'
# period_archives.html
NEST_PERIOD_ARCHIVES_HEAD_TITLE = u'归档于'
NEST_PERIOD_ARCHIVES_HEAD_DESCRIPTION = u'归档于'
NEST_PERIOD_ARCHIVES_HEADER_TITLE = u'归档'
NEST_PERIOD_ARCHIVES_HEADER_SUBTITLE = u'归档于'
NEST_PERIOD_ARCHIVES_CONTENT_TITLE = u'归档于'
# tag.html
NEST_TAG_HEAD_TITLE = u'标签归档'
NEST_TAG_HEAD_DESCRIPTION = u'标签归档'
NEST_TAG_HEADER_TITLE = u'标签'
NEST_TAG_HEADER_SUBTITLE = u'标签归档'
# tags.html
NEST_TAGS_HEAD_TITLE = u'标签'
NEST_TAGS_HEAD_DESCRIPTION = u'标签'
NEST_TAGS_HEADER_TITLE = u'标签'
NEST_TAGS_HEADER_SUBTITLE = u'根据标签归档'
NEST_TAGS_CONTENT_TITLE = u'标签'
NEST_TAGS_CONTENT_LIST = u' 被标注'