跳转至

静态网站生成器Pelican学习笔记

2021-03-02:本博客已经改用 Mkdocs生成


不写是不好的。

写微信、微博,像是在村头赤身裸体,彼此都尴尬;写博客是在无中心的世界里守株待兔,带点虚空的暧昧情绪。

尝试了几种静态文件生成器,基于Python语言的Pelican最简单、亲切。这是照着pelican 文档练习时随手所记,备查。

快速上手#

  • 安装,通常在一个独立的Python venv中
pip install pelican markdown beautifulsoup4
  • 在当前目录生成一个网站骨架
pelican-quickstart

目录结构如下:

yourproject/
├── content              # 文章
│   └── (pages)         # 固定页面
│   └── (images)        # 静态文件夹(图像)
├── output               # 生成的网站
├── develop_server.sh
├── fabfile.py           # 自动化工具
├── Makefile             # 自动化工具
├── pelicanconf.py       # 主配置
└── publishconf.py       # 发布配置

常用命令#

  • 启动开发服务,监控更改,实时发布更新:
pelican -r

即:

pelican --autoreload
  • 在输出文件夹output的位置启动Python3服务器(其他服务器也可以),然后浏览器中打开给出的地址:
python -m http.server

文件元数据#

Pelican支持Markdown、reStructuredText、AsciiDoc等书写格式,也能直接使用HTML页面。下面以较常见的Markdown为主。

  • 常用Markdown元数据:
---
title: 文章标题        // 必填
Slug:                 // 文章唯一标识,相同的Slug搭配不同的Lan标记可以形成多语言平行页
                      // 缺省则用Title生成,汉字转换为无调拼音并用'-'分割
Category: 分类         // 归类到导航栏菜单中(可设置),缺省值是所在的output中的次级目录名(可关闭)
Tags: 标签1; 标签2     // 顶级分隔符也可用','
Authors: 作者1; 作者2   // 顶级分隔符也可用',',只有一个作者时可以用'author'
Date: 2018-10-14 08:44      // 书写时间,必须
Modified: 2018-10-14 08:44  //更改时间
Summary: 摘要          // 缺省为使用正文开头50个单词(字数可设置,有标签而无值似乎有问题)
                       // 中文无法正确计算词数(也是按空格、标点计),所以必须手动设置本项
Status:                // 状态,如draft(草稿,不公布), published(发布,缺省值),
                       // hidden(只用于隐藏page,如404页)
---

另有Save_as:标签,控制转换后的输出目标。配合INDEX_SAVE_AS = 'blog_index.html'可以更改网站首页。

  • HTML元数据:
<html>
    <head>
        <title>My super title</title>
        <meta name="tags" content="thats, awesome" />
        <meta name="date" content="2012-07-09 22:28" />
        <meta name="modified" content="2012-07-10 20:14" />
        <meta name="category" content="yeah" />
        <meta name="authors" content="Alexis Métaireau, Conan Doyle" />
        <meta name="summary" content="Short version for index and feeds" />
    </head>
    <body>
        This is the content of my super blog post.
    </body>
</html>

HTML标签#

:abbr:`HTML (HyperText Markup Language)`

pages(固定页面)#

内容文件夹content下的文件夹pages,其中的内容会生成静态页,比如About、Contact页。通过DISPLAY_PAGES_ON_MENU选项控制pages中的内容是否全部在顶级导航菜单中显示,默认为True。个别文章可以通过元数据status: hidden隐藏。

内部内容链接#

链接到内部的内容文件,包括即将编译的markdown文件;但图片等静态文件当用static标签。根文件夹前要用/,如/category

[a link relative to the current file](article1.md)

静态文件链接#

pelicanconf.py中设置静态文件路径:

STATIC_PATHS = ['images', 'pdfs']

文章使用方法static标签:

![Alt Text](img/han.jpg)
[Our Menu]({static}/pdfs/menu.pdf)

filename标签定义的链接,编译后将指向目标(如md文件)的编译输出文件(如html文件),而static标签定义的链接仍指向源文件。 另外,用attach代替static可以保持文章与附件的相对关系。但建议只当所有链接都指向同一个文件,且链接所在的文章都在同一目录时才使用attach标签。

元数据链接#

链接到元数据:

`{author}name`
`{category}foobar`
`{index}`
`{tag}tagname`

代码语法高亮#

Markdown文件使用CodeHilite extension,代码块缩进、其上加语言标识(用常规的一对三反引号也可以):

print("The triple-colon syntax will *not* show line numbers.")

加行号(但会导致css中的pre {overflow-x: auto;}失效):

print("The path-less shebang syntax *will* show line numbers.")

用于诗歌等纯文本时,也应该明示为:::text,否则可能出现错误的红色框。因为如果没有明示语言,那么Pygments语法高亮引擎会猜测一种语言(除非guess_lang=False)。

缺省元数据和发布草稿#

在元数据中添加草稿标签Status: draft,可发布到草稿文件夹drafts,不会列入目录、分类、标签中。可设置缺省元数据,缺省发布状态为草稿:

DEFAULT_METADATA = {
    'status': 'draft',
}

此后如果要发布,则需要添加发布状态标签:

Status: published.

文章的多语言翻译#

略。

extract_toc插件#

extract_toc通过article.content中第一个[TOC]标签的内容生成目录,放在article.toc中,从而可以在模板中使用。注意,第一个[TOC]标签将被删除。安装依赖:

pip install beautifulsoup4

在设置中安装插件:

PLUGIN_PATHS = ['path/to/pelican-plugins']
PLUGINS = ['extract_toc']

在模板中使用。比我的博客,把目录移到右侧文章信息下部:

  • 在Pelican自带主题notmyidea的article_infos.html中添加空block,以便扩展:
{% block toc %}
{% endblock%}
  • 再新建article_infos_toc.html,扩展前者:
{% extends "article_infos.html" %}
{% block toc %}
    {% if article.toc %}
        <nav class="toc">
        {{ article.toc }}
        </nav>
    {% endif %}
{% endblock %}

常用配置#

pelican-quickstart自动生成的pelicanconf.py种有一些重要的设置项,不在此列。这里主要是额外补充的:

# 网站副标题
SITESUBTITLE = '你来了!'

# 站点地址,最后的"/"不能少。或留空。
SITEURL = ''
# SITEURL = 'http://blog.xiiigame.com/'

# 日期格式参看:https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
DEFAULT_DATE_FORMAT = '%Y-%m-%d %a'

# 使用未install的主题
THEME = "./themes/notmyidea-ah21"

# Markdown扩展
MARKDOWN = {
    'extension_configs': {
        'markdown.extensions.codehilite': {'css_class': 'highlight'},
        'markdown.extensions.extra': {},
        'markdown.extensions.meta': {},
        'markdown.extensions.tables': {  # 表格
        },
        'markdown.extensions.toc': {     # 目录,设置看https://python-markdown.github.io/extensions/toc/
            'title': 'TOC:',      # 目录题头
            'toc_depth': 3, 
        },
    },
    'output_format': 'html5',
}

# 插件路径
PLUGIN_PATHS = ['./pelican-plugins']
# 使用的插件(extract_toc要和Markdown的toc扩展插件配合使用)
PLUGINS = ['extract_toc']

# 静态文件夹、文件
STATIC_PATHS = ['images', 'extra/CNAME', 'extra/README.txt', 'extra/favicon.ico']
# 以下设置页无法避免.md文件的转换处理
# ARTICLE_EXCLUDES = ['extra/README.md']
# STATIC_EXCLUDES = ['extra/README.md']
# 复制元数据('images'不需要写明复制)
EXTRA_PATH_METADATA = {'extra/CNAME': {'path': 'CNAME'},
                        'extra/README.txt': {'path': 'README.md'},
                        'extra/favicon.ico': {'path': 'favicon.ico'},
                    }

#次级文件夹中的文章,如果没有分类,则使用文件夹名称代替,缺省为True
USE_FOLDER_AS_CATEGORY = True
# 默认归类(未归类的归入自动此类)
DEFAULT_CATEGORY = '杂项'

# 输出时保护(如版本数据)
OUTPUT_RETENTION = [".hg", ".git", ".bzr"]

# 忽略文件,不予处理
# IGNORE_FILES = ['README.MD']

# 自动生成的摘要的最大词语个数,缺省为50
SUMMARY_MAX_LENGTH = 50

# 生成GitHub缎带
GITHUB_URL = "https://github.com/Fusyong"
# DISQUS账号
# DISQUS_SITENAME

# 导航栏条目,只能是绝对路径,否则前面会自动加上“category/”;
# 主题模板的archives.html和tags.html页则可在base.html中硬编码
MENUITEMS = [ ('XiiiGame', 'http://www.xiiigame.com')]

# 倒序排列分类(只能控制自动生成的分类,不能控制导航栏条目)
# REVERSE_CATEGORY_ORDER = True

# 谷歌分析号码
GOOGLE_ANALYTICS = 'UA-xxxxxxxxx-x'

详细配置见pelican 文档

部署到github的User Pages#

在github上新建一个名为username.github.io的库(username必须是你的github账户名,以下Fusyong是我的账号,请改成你自己的)。然后在本地的output文件夹进行git克隆,或者初始化、提交、关联,再推送。

echo "# Fusyong.github.io" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/Fusyong/Fusyong.github.io.git
git push -u origin master

即可访问Yourusername.github.io。如果误删除.git文件夹,重新克隆库即可:

git clone https://github.com/Fusyong/Fusyong.github.io.git output

每次更新后提交、推送:

git add --all
git commit -m "refresh"
git push -u origin master

以上是用HTTPS链接,每次push都需要输入账号、密码,不过可以在git中保存账户名和密码:

git config --global credential.helper store

或者使用如下的SSH链接,使用秘钥,不需要每次提供:git@github.com:Fusyong/Fusyong.github.io.git

git知识可参考廖雪峰的git教程.

另,我的win7系统上无法使用官方推荐的ghp-import来更新库。

域名绑定#

如果需要绑定自己的域名,在github库根目录建一个名为CNAME的文件,写上要绑定的域名,如blog.xiiigame.com。xiiigame.com域名的DNS解析相应新建一条CNAME记录,指向Fusyong.github.io。如果绑定顶级域名,DNS要建A记录,指向Fusyong.github.io的IP地址(通过ping Fusyong.github.io获取)。

更改主题#

给代码块加水平滚动条#

更改css文件。代码块折行:

    pre {
      white-space: pre-wrap;
    }

不折行而加上横向滚动条:

    pre {
      overflow-x: auto;
    }

from :使用pre标签样式的注意事项