美文网首页Hexo
修改Hexo自动生成的HTML文件名

修改Hexo自动生成的HTML文件名

作者: BiggerBoy | 来源:发表于2019-05-31 16:04 被阅读0次

    导读

    我们在使用Hexo框架生成静态博客时,其实是将你写好的.md文件输出成HTML文件进行渲染,其中HTML的文件名称就是.md的文件名称。

    而我们为了编辑文章方便,为了通过文件名就知道这是哪篇文章,通常是把.md文件命名成中文的甚至是文章的标题,那么生成HTML文件时也就是中文的文件名了。

    例如:钢铁是怎么炼成的.md经过hexo g命令会生成钢铁是怎么炼成的.html;执行hexo d命令会将文件推送到你的仓库,那么你访问这篇章时,对应的地址栏就是http://xxxx/.../钢铁是怎么炼成的.html,这样看起来很别扭,对搜索引擎也不友好。

    那么我们如何修改为以数字加字母命名的HTML呢?今天我们就来探究一下。查看效果

    (1)修改生成HTML时的命名策略

    我们从Hexo是基于Node.js的,Hexo生成HTML文件这句话的到启发,Hexo肯定会获取文件夹下的所有.md文件生成HTML文件,命名格式xxx.md-->xxx.html,然后肯定会创建目录存放HTML文件。

    这时候我们会想,我们是不是可以在Hexo生成HTML文件时,修改HTML的命名策略,即将原始的命名方式改为我们自定义的命名方式?

    有了思路说干就干。于是去Hexo的各个文件里去找,它是在哪转换文件的。当我找了好几个文件后,我放弃了,文件太多了,太难找了,无异于大海捞针。在hexo模块里找了很久也没找到。。。

    image.png

    (2)修改HTML文件名

    既然刚才那种方法行不通,那么我们就另辟蹊径,在Hexo生成HTML文件后,再去修改文件名。
    JS怎么获取目录下的所有文件呢?搜了一下说Node.js可以,刚好Hexo是基于Node.js的。
    于是任意目录下(除hexo目录)创建rename.js文件如下,其中新的文件名生成策略可以自己定义。

    //引入fs操作文件
    var fs = require('fs');
    //引入jquery
    var join = require('path').join;
    var jsdom = require('jsdom');
    const {JSDOM} = jsdom;
    const {document} = (new JSDOM('<!doctype html><html><body></body></html>')).window;
    global.document = document;
    global.window = document.defaultView;
    global.jQuery = require('jquery')(window);
    const $ = require('jquery')(window);
    
    var eng = ['a','b','c','d','e','f','g','h','i','j'];
    //生成随机6位数字字母 全路径新文件名
    function getNewNameRandom(_file){
        var fiveInt = Math.floor(Math.random()*89999+10000);//无五位随机数
        var eng_index = Math.floor(Math.random()*10+1);//一位字母
        return _file.substr(0,_file.lastIndexOf('\\')+1) + eng[eng_index-1] + fiveInt + ".html";//新文件名,全路径
    }
    function getAllFiles(jsonPath){
        let jsonFiles = [];
        function findJsonFile(path){
            let files = fs.readdirSync(path);
            files.forEach(function (item, index) {
                let fPath = join(path,item);
                let stat = fs.statSync(fPath);
                if(stat.isDirectory() === true) {
                    findJsonFile(fPath);
                }
                if (stat.isFile() === true) { 
                  jsonFiles.push(fPath);
                }
            });
        }
        findJsonFile(jsonPath);
        console.log(jsonFiles);//指定目录下的文件,包括子目录
        return jsonFiles;
    }
    function doFileRename(){
        var jsonFiles = getAllFiles("F:/static/page");//生成的HTML文件
        for(var i=0;i<jsonFiles.length;i++){
            var _file = jsonFiles[i];
            var newName = getNewNameRandom(_file);//新文件名,全路径
            console.log(newName)
            fs.rename(_file,newName,function(err){//重命名
                if(err){
                    console.log("重命名失败");
                }else{
                    console.log("重命名成功");
                }
            })
        }
    }
    doFileRename();
    
    

    然后在这个JS所在目录打开命令行,执行node rename.js

    image.png

    看日志,是全部成功了,找到对应目录,真的成功了。

    image.png

    存在的问题

    hexo g时,又会生成原来的那样中文命名的HTML,我们重命名的还在(执行hexo clean就不在了),这不是我们想要的,或许你会说,再执行一次node rename.js,这不是我想要的,因为,这样执行每次原来的文章页面的名字都会变,我不知道这会不会影响SEO,即时不会也不想这样,因为加入别人收藏了你的文章链接,但你的文章HTML名字变了,拿别人收藏的就无效了啊。

    所以这种方式会存在这个最严重的问题。

    (3)Base64生成文件名

    修改JS代码

    //引入fs操作文件
    var fs = require('fs');
    //引入jquery
    var join = require('path').join;
    var jsdom = require('jsdom');
    const {JSDOM} = jsdom;
    const {document} = (new JSDOM('<!doctype html><html><body></body></html>')).window;
    global.document = document;
    global.window = document.defaultView;
    global.jQuery = require('jquery')(window);
    const $ = require('jquery')(window);
    
    var eng = ['a','b','c','d','e','f','g','h','i','j'];
    //文件名Base64后 根据算法从编码中取6位作为新文件名
    function getNewNameBase64(_file){
        var fileName = _file.substr(_file.lastIndexOf('\\')+1,_file.length);//文件名
        var fi_bs64 = Buffer.from(fileName.substr(0,fileName.lastIndexOf('.'))).toString('base64')//转成base64编码
        var arr = fi_bs64.split("");
        var len = arr.length;
        var fis = "";
        for(var i=1;i<=6;i++){
            var s1 = arr[Math.floor(len/(2*i))];
            if(s1=='/'||s1=='+'){
                var eng_index = Math.floor(Math.random()*10+1);
                s1 = eng[eng_index-1];
            }
            fis = fis + s1;
        }
        console.log(fis)
        return _file.substr(0,_file.lastIndexOf('\\')+1) + fis + ".html";
    }
    function getAllFiles(jsonPath){
        let jsonFiles = [];
        function findJsonFile(path){
            let files = fs.readdirSync(path);
            files.forEach(function (item, index) {
                let fPath = join(path,item);
                let stat = fs.statSync(fPath);
                if(stat.isDirectory() === true) {
                    findJsonFile(fPath);
                }
                if (stat.isFile() === true) { 
                  jsonFiles.push(fPath);
                }
            });
        }
        findJsonFile(jsonPath);
        console.log(jsonFiles);//指定目录下的文件,包括子目录
        return jsonFiles;
    }
    function doFileRename(){
        var jsonFiles = getAllFiles("F:/static/page");//生成的HTML文件
        for(var i=0;i<jsonFiles.length;i++){
            var _file = jsonFiles[i];
            var newName = getNewNameBase64(_file);//新文件名,全路径
            console.log(newName)
            fs.rename(_file,newName,function(err){//重命名
                if(err){
                    console.log("重命名失败");
                }else{
                    console.log("重命名成功");
                }
            })
        }
    }
    doFileRename();
    

    效果

    image.png

    看日志,是全部成功了

    找到对应目录,真的成功了。

    存在的问题

    这种方法解决了上面那个方法存在的问题,即每次执行node rename.js只要原文件名不变,生成的新文件名不变。但是需要限制文件名不能变,否则新文件名还是会变。还有一点不能重复执行node rename.js,因为会根据新的再次生成新的。

    小结

    第2、3种方式都需要注意的是,
    1、新名字的生成规则,要保证唯一性,不能重复
    2、每次hexo g之后hexo d之前,要执行node rename.js
    3、不要重复执行
    4、第一种不太可行,推介第二种

    (4)修改文件生成规则

    以上两种方式都需要我们来写代码,而且要手动执行node rename.js
    对于这么懒的我来说很不方便,有没有更好的办法?答案是肯定的。

    我们可以找到Hexo的根配置文件_config.yml,打开它,找到下图这个

    image.png

    我把他改成这样了,page是目录,执行hexo g会在public下生成,我让生成的HTML文件都放在page下,:fileName.html是HTML的命名格式,其中fileName是个变量。这个变量从哪来?
    从你的.md文件里,如下图,在你的文章头部增加这个变量并指定一个值,这就是生成HTML时的文件名,注意也是不要和其他文件重复

    image.png

    也就是说,你的每篇文章只要头部加了这个属性,并赋值且确保唯一就OK了,不用像上面那两种方式那样麻烦了。
    只样在执行hexo g后就变成这样了

    image.png

    执行hexo d后访问我的网站就是这样了

    image.png

    为了避免忘记在写文章时写fileName属性,我们可以修改模板,在scaffolds目录下有三个模板
    在模板添加fileName属性

    image.png

    存在的问题

    需要手动写文件的名字,且要保证唯一,但是比较方便

    总结

    推荐使用第3和第4种,第3种主要就是解决每次执行hexo g后生成的HTML文件名不变(前提是.md文件名不变),但不要忘了执行node rename.js,第4种只要自己有一个自己的命名规范就好了,比如:今天是五月m,日期29,周三w,时间是17点,文件名就可以就是m29w17。

    如果大家知道在Hexo生成HTML得时候就可以改或者有别的好办法,可以留言告诉我,谢谢。


    本文以及本文提供的方法均为作者原创,自己摸索出来的,转载请注明出处,感谢!!!

    相关文章

      网友评论

        本文标题:修改Hexo自动生成的HTML文件名

        本文链接:https://www.haomeiwen.com/subject/sqkgtctx.html