Elvyn's Blog
Elvyn's Blog
Elvyn's Blog

Pelican自定义独立404页面引发的问题

前言

自定义404页面按照Pelican官方教程,本来貌似是一件很简单的事。

在github page平台,只需要制作好404页面,它就自动调用这个页面了。

然而真的做好一个404页面后,却发现事实并非这么简单。

重新整理一下环境,Pelican博客系统,托管在github page平台,定制一个独立的404页面,当我们想要这个404页面是一个完整的独立的html页面,不希望它被当成文章页或page页(主要是一切从简,不用套用base.html模板页面)时,竟然不知道如何“发布”它?!

问题起因

发生这个问题是有前提的。现在再来回想,如果我不做一些文件结构的设置,也许也就不会出这种事情了。

那就是,安装了博客系统后,默认情况下,Pelican是将生成的所有html页面一股脑儿放在output文件夹下的,而由于文章页的标题太长,看着很乱,我添加了设置将生成的文章页面放到output/posts文件夹中。

然后我要做一个简洁的404页面时,问题就出现了:

照理说在制作出一个404.html文件后,将它放到已经设置为静态路径的文件夹下,不就行了吗?

结果发现,想得太天真了,不管我将它在STATIC_PATHSEXTRA_PATH_METADATA里怎么设置,Pelican都会在生成站点时重新解析这个404.html文件。

为什么呢?不是放在静态目录下的文件不处理,直接复制到output文件夹的么?

github的说明里,只要在站点根目录下有一个404.html或404.md文件,它就会自动调用这个页面来替换默认的404界面。

然而这里Pelican却死活不肯给我将404.html输出到output目录下,要么在output/posts目录要么在output/pages目录,在output/posts目录中时还被改成了文章的标题格式。

令人抓狂的是明明觉得应该是件极其简单的事情,却也会出现让人摸不着头脑的意外。

无视问题的解决办法

其实要解决的话,最简单的方法,就是制作404.md文件,在元数据区添加这三个参数:

Title: Not Found
Status: hidden
Save_as: 404.html

然后将文件放到pages目录下,Pelican系统在生成站点时,就会将404.md文件转换继承base.html页面,生成一个隐藏的404页面。

然而这样却是一个带满各种页面框架的复杂页面,界面也不好看,并不是我们想要的效果。

我们要的只是简简单单一个显示404错误的页面而已啊。

查找原因

无奈只好求助于网络,也才发现,这种类似的问题,原来在官方issue和stackoverflow都有人问及。

综合看完后, 我们来说一下发生这种情况的原因,和怎么解决。

原来Pelican在执行生成站点时,默认会将所有读取到的.md, .rst.html三处格式的文件都解析处理一遍。不管是在什么文件夹。

也就是说,放在静态文件夹中的这三种格式的文件,是不会像其它格式文件一样被“原封不动不经处理”地复制到输出目录中的。

有用户就提议修改Pelican系统代码,让Pelican不要处理静态目录下的html文件。

然而却被回复说会引起冲突,因为之所以会出现这种情况,是由于Pelican在3.5.0版本时更新了一个功能,允许静态文件和文章文件放在同一个目录中。基于这个设定,Pelican会认为放在静态文件夹中的.md, .rst.html文件,是动静混合内容中的内容源文件,于是读取到这些文件时也会解析处理一遍。

真是头大。

不过还好,知道了怎么回事以后,我们总会想到应对的解决办法的不是么?

下面来看一下解决方法:

针对问题的解决办法一

方法一是直接在设置文件中添加这样一行参数设置:

READERS = {"html": None}

意思是让Pelican的读取器直接忽略html格式文件。

这种方式一劳永逸,但是弊端也显而易见:如果我们制作了一些只含代码块的html页面,需要继承base.html模板的话,这样一刀切的设置就行不通了。

针对问题的解决办法二

方法二是在设置文件中同时添加以下几个选项:

STATIC_PATHS = ['images', 'extra']
PAGE_EXCLUDES = ['images', 'extra', 'posts']
ARTICLE_EXCLUDES = ['pages', 'images', 'extra']
EXTRA_PATH_METADATA = {
    'extra/robots.txt': {'path': 'robots.txt'},
    'extra/404.html': {'path': '404.html'},
    'extra/CNAME': {'path': 'CNAME'},
    'extra/README.md': {'path': 'README.md'},
    'images/favicon.ico': {'path': 'favicon.ico'},
}

也就是在STATIC_PATHSEXTRA_PATH_METADATA设置的基础上添加PAGE_EXCLUDESARTICLE_EXCLUDES

前两个设置项是设置静态目录和静态文件的路径的;后两个设置项用于告诉Pelican系统不要读取列表中的目录下的文件。

设置好,再将404页面放到extra文件夹中,生成站点,终于正常可以显示了。

结语

这个问题,其实不单单是404页面,比如如果我们已经用其他电子书制作工具生成好了一系列的完整的html页面,只需要当成静态文件输出时,也会面对这种情况。

然而为了一个404页面,弄这么复杂,也是有些麻烦啊。

一如,几句话说明白的事儿,写这么复杂,也是有些啰嗦啊。