最近又开始折腾网站了,hexo管理本地文件的方式真的非常蠢,所有文章都是在_post下按照alphabet排序,文章一多起来很难管理,找个文章只能看文件名,没法大概预估是什么时候的,而且并不是按照文件创建顺序排列。

但是如果把文件名都用YYYY-MM-DD-的日期前缀命名,就又会导致生成的页面路由变成domain.com/YYYY/MM/DD/YYYY-MM-DD-title的奇怪格式。

有一个办法是用hexo-abbrlink,生成唯一的文章链接,只是这样就会导致文章的路由没有实际意义了,比如文章原来的路由是/hello-world/,abbrlink后就变成没有实际意义的hex码,我这里就不考虑了。

在hexo的配置文件(根目录下的_config.yml)里可以设置文章路由格式,如下图:

这里的:title代表的并不是文章的标题,而是文章的文件名。因此如果我去掉了前面的:year/:month/:day/,并把每个文章的文件名改成YYYY-MM-DD-filename.md的格式,最终路由是可以接受的,会变成YYYY-MM-DD-filename。而生成的网站静态文件则会同样的组织格式,如下:

但我想生成的静态文件,也能够继续按照年月日来进行归组管理,问题就产生了:

  • 日常写作,以日期前缀管理文章
  • 生成站点后,以/YYYY/MM/DD/filename格式作为路由
  • 静态资源以年月日归组html

想同时满足这个诉求,就要做点定制。我的方案是把文件名在部署之前通过脚本批量改成无前缀格式,在部署完毕之后再根据文章的创建日期把前缀加回去。然后通过npm脚本来执行开发、生成、部署等日常操作,将自动化的脚本串起来。

这种操作只在部署时需要,其他操作都没有必要去改文件名(日常创作是需要前缀的),所以设计两个脚本,分别在hexo d的前后执行:

./script/before_deploy.sh # 批量的将_posts文件夹下的文件重命名,去掉日期前缀

#!/bin/bash

folder="./source/_posts"

for file in "$folder"/*.md; do

    filename=$(basename "$file")
    # 获取文件名中的日期前缀
    date_prefix=$(echo "$filename" | grep -Eo "^[0-9]{4}-[0-9]{2}-[0-9]{2}-")

    echo $date_prefix $file

    # 如果存在日期前缀,则去掉
    if [ -n "$date_prefix" ]; then
      new_file="${filename#$date_prefix}"
      mv "$file" "$folder/$new_file"
    fi
done

git add -A

./script/before_deploy.sh # 批量的将_posts文件夹下的文件重命名,根据创建日期添加文件前缀

#!/bin/bash

# set target folder
target_folder="./source/_posts"

# loop through all files in the target folder
for file in $(find "$target_folder" -name "*.md"); do

  filename=$(basename "$file")
  date_time=$(head -n 10 "$file" | grep "^date: " | sed -n 's/^date: *\(.*\)/\1/p' | awk '{print $0}')

  # 获取文件名中的日期前缀
  date_prefix=$(echo "$date_time" | grep -Eo "^[0-9]{4}-[0-9]{2}-[0-9]{2}")

  # 如果存在日期前缀,则重命名文件
  if [ -n "$date_prefix" ]; then
    new_file="${date_prefix}-$filename"
#    echo $file "$folder/$new_file" $new_file
    mv "$file" "$target_folder/$new_file"
  fi


done

git add -A

exit 0

上面的脚本保存到./script文件夹下面,在hexo工程根目录下执行:

# 增加文件的执行权限
chmod +x ./scrpt/before_deploy.sh ./script/after_deploy.sh

最后在hexo工程的package.json中添加npm脚本:

{
  "scripts": {
    "deploy": "sh script/before_deploy.sh && hexo clean && hexo deploy && sh script/after_deploy.sh"
  }
}

通过执行npm run deploy来部署。