最近又开始折腾网站了,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
来部署。