从 Pointless 迁移到 Spress
由于 Pointless 「年久失修」,我将博客迁移到了 Spress。不过就目前版本而言,Spress 对多语言支持有些问题。如果你想试用一下 Spress,需要注意以下几点。
Spress 不支持中文标题,它会将标题中的非字母和数字的字符都替换为连字符「-」:
// src/Core/Utils.php
class Utils {
// ...
public static function slugify($text)
{
// replace non letter or digits by -
$result = preg_replace('/[^\\pL\d]+/u', '-', $text);
// ...
}
}
Utils 类就一个 slugify 方法,Spress 的标题会被它过滤,它的第一行代码就将所有非数字和 Unicode letter 的字符替换为连字符。
// src/Core/ContentManager/PostItem.php
class PostItem extends ContentItem
{
// ...
public function getTitle()
{
$title = $this->frontmatter->getFrontmatter()->get('title');
return $title ?: $this->title;
}
// ...
private function getTitleSlugified()
{
return Utils::slugify($this->getTitle());
}
}
然后是 PostItem 类,生成文章链接时需要调用 getTitleSlugified 方法。如果我们在 Front-matter 里自定义了中文标题,自定义标题会覆盖 markdown 文件名中的标题,最终导致自定义标题中的所有中文字符都会被替换掉。解决这个问题很简单,修改一下 getTitleSlugified 方法即可:
// src/Core/ContentManager/PostItem.php
class PostItem extends ContentItem
{
// ...
public function getOriginalTitle()
{
return $this->title;
}
// ...
private function getTitleSlugified()
{
return Utils::slugify($this->getOriginalTitle());
}
}
我添加了一个 getOriginalTitle 方法,它直接返回原标题。然后将 getTitleSlugified 方法中的 getTitle 替换为 getOriginalTitle 即可。当然你也可以简单粗暴的在 getTitleSlugified 里直接使用 $this->title
。
Spress 不支持「page/:num」分页格式。Spress 默认分页为 page:num 格式,文章数量比较多的时候就会在根目录生成一堆 page2,page3 之类的文件夹,完全不能忍。Spress 贴心的提供了 paginate_path
参数来自定义分页路径,但是如果把参数修改为 page/:num,你就会发现首页空了。这是因为 Spress 把新生成的首页放到了 page/ 目录下了:
// src/Core/ContentManager/ContentManager.php
class ContentManager
{
// ...
private function getRelativePathPaginatorTemplate()
{
$path = $this->getRelativePathPaginator();
return $path ? $path.'/index.html' : 'index.html';
}
private function getRelativePathPaginator()
{
$result = '';
$template = $this->configuration->getRepository()->get('paginate_path');
$dir = dirname($template);
if ($dir != '.') {
$result = ltrim($dir, '/');
}
return $result;
}
}
Spress 在生成分页的时候会调用以上两个函数,getRelativePathPaginator 方法决定了首页放置路径。因为我只是用 Spress 来写博客,暂时未想到有什么把首页放到子目录的需求,直接修改代码:
// src/Core/ContentManager/ContentManager.php
class ContentManager
{
// ...
private function getRelativePathPaginator()
{
$result = '';
$template = $this->configuration->getRepository()->get('paginate_path');
$dir = dirname($template);
if ($dir != '.' && 0 === strpos($dir, '/')) {
$result = ltrim($dir, '/');
}
return $result;
}
}
保守起见,我保留了原有的功能,根据 paginate_path 是绝对路径还是相对路径来决定首页的放置路径。然后就可以安心的使用相对路径(例如:page/:num)来定义分页格式了。
Spress 不支持自动部署,也就是说每次 site:build
之后需要自己手工上传。我的博客托管在 Github pages 上,于是直接修改 destination
参数,指向博客的 git 目录。如果你直接放到了 spress 目录,需要将其添加到 exclude
列表,防止多次复制。Github pages 需要的文件(例如:CNAME)必须提取到 Spress 目录,不然会被清空。
经过上面的修改和调整,Spress 已经能够正常使用了。如果你不想自己动手修改代码,可以直接使用我打包好的 Phar 文件,因为是基于 Spress 2.0.0 开发版打包,所以查看帮助列表的时候会看到 unstable 的提醒,忽略即可。