Hexo自定义主题(五)

标签: Hexo 分类: 前端 创建时间:2019-11-23 01:05:34 更新时间:2023-10-20 11:23:25

1.文章和分类无法使用特殊符号的问题

在使用hexo新建一篇文章,比如文章的名字叫“C#”,结果,会发现,生成的md的文件名中的#被省略了,直接生成了一个名为C.md的文件,这主要是因为hexo默认以文章的名称作为文章的url,所以url中不能有特殊的字符。URL 中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~ 4个特殊字符以及所有保留字符。如果文章的名字中出现了:! * ‘ ( ) ; : @ & = + $ , / ? # [ ] 这些字符,那么就容易产生url歧义,因为这些字符在url中都有特定的含义,所以就产生了url编码。有三种编码函数,函数后面的内容,是函数不会对url进行编码的字符,除了这些,都是会被以%开头的字符进行转义的。

1
2
3
escape(69个):*/@+-._0-9a-zA-Z
encodeURI(82个):!#$&'()*+,/:;=?@-._~0-9a-zA-Z
encodeURIComponent(71个):!'()*-._~0-9a-zA-Z

鉴于此,在编写文章的名字的时候,还是要好好的考虑一下,特别是这个C#这个字符。同理,在分类和标签中,也不应该出现特殊字符。那如果我非得要写一个分类为c#的分类怎么办呢?我的做法是对文章的分类进行编码,但是因为是在generator.register生成器中,不能直接对文章的分类进行修改,这个分类是一个getter函数,所以需要自行封装一个对象,将文章的分类进行重赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// 文章渲染前进行操作,将分类和tags标签改为首字母大写
hexo.extend.generator.register('post', function(locals){
return locals.posts.map(function(post){
// 修改分类为首字母大写
// 因为文章的分类信息如下,不能直接修改文章的分类路径,所以应该新建一个对象,复制相关内容
// [
// Document {
// name: 'Javascript',
// _id: 'ck31jjht40042kyfmbx0lbv8y',
// slug: [Getter],
// path: [Getter],
// permalink: [Getter],
// posts: [Getter],
// length: [Getter]
// }
// ]
var categories=post.categories.data;
var newCat={};
for(let menuItem in categories){
let name=categories[menuItem].name;
//将首字母改为大写
name=name.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
//将路径中的特殊符号进行编码
let path=categories[menuItem].path;
if(path.indexOf(name)<0){
// console.log(name);
path="categories/"+encodeURIComponent(name)+"/";
}else{
path=encodeURIComponent(categories[menuItem].path.replace(/\./g,"-"));
}

// 构造新的分类对象
newCat={
name:name,
_id:categories[menuItem]._id,
slug:categories[menuItem].slug,
path:path,
permalink:categories[menuItem].permalink,
posts:categories[menuItem].posts,
length:categories[menuItem].length
}
categories[menuItem]=newCat;
}
//修改标签为首字母大写
var tags=post.tags.data;
for(let menuItem in tags){
// console.log(tags[menuItem]);
let name=tags[menuItem].name;
//将首字母改为大写
name=name.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());

let path=tags[menuItem].path;
if(path.indexOf(name)<0){
path="tags/"+encodeURIComponent(name)+"/";
}else{
//将路径中的点,换成-
path=path=encodeURIComponent(tags[menuItem].path.replace(/\./g,"-"));
}

// 构造新的对象
newCat={
name:name,
_id:tags[menuItem]._id,
slug:tags[menuItem].slug,
path:path,
permalink:tags[menuItem].permalink,
posts:tags[menuItem].posts,
length:tags[menuItem].length
}
tags[menuItem]=newCat;
}

return {
path: post.path,
categories:newCat,
data: post,
layout: 'post'
};
});
});

至于对文章生成的分类和标签中的中文名称,进行编码,因为我尝试过,总是显示找不到编码后端路径,姑且就还是用中文好了。

而查看生成的public目录,明明就有相应的目录的,却始终找不到。问题没有解决。做法也很简单,就是注册生成器,生成 category 时,传入编码后的路径。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//生成分类
hexo.extend.generator.register('category', function(locals){
let categoriesPage={}
locals.posts.map(function(post){
//将文章的标签和分类首字母改为大写
var categories=post.categories.data;
if(categories.length<=0){
if(!categoriesPage["其他"]){
categoriesPage["其他"]=[];
}
categoriesPage["其他"].push(post);
}else{
for(let menuItem in categories){
let name=categories[menuItem].name;
// console.log(name.toLowerCase());
//将首字母改为大写
name=name.toLowerCase().replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
categories[menuItem].name=name;

//保存相关文章
if(!categoriesPage[name]){
categoriesPage[name]=[];
}
categoriesPage[name].push(post);
}
}
post.path=encodeURIComponent(post.path);

});
let themeConfig=hexo.theme.config;
let perPage=(themeConfig.categories_generator&&themeConfig.categories_generator.per_page)?themeConfig.categories_generator.per_page:10;
var pages=[];
for(let categoriesName in categoriesPage){
let page=categoriesPage[categoriesName];
// console.log(categoriesName);
let path="/categories/"+encodeURIComponent(categoriesName.replace(/\.|\s/g,"_"));
var data = pagination(path, page, {
perPage: perPage,
layout: ['category', 'index'],
format: '/page/%d/',
data: {
categories: categoriesName,
path:path
}
});
pages=[...pages,...data];
}
return pages;
});

当然也可以使用参考文章中的方法,将文章的永久链接改为id号,或者是纯英文的方法。

2.解决部署到github上出现的404问题

我的问题是这样的,为了统一文章的标签和分类,我再theme目录下的scripts目录下写了一些生成器,将分类和标签的首字母进行了大写,在本地开发的时候,public目录下,生成了我需要的文件及文件夹,但是当我部署的时候,出现的分类并不是我先要结果,比如分类本来是GIS,经过处理后可以变成Gis,本地使用:http://localhost:4000/categories/Gis/ 可以找到相关内容,但是到服务器上:https://bibichuan.github.io/categories/Gis/ 就成了404。

和其他人的404不同,我的并不是完成的404,像中文的分类,部署后还是可以正常的浏览的。

问题的原因主要是因为git默认是不区分大小的,所以即使你将文件名都改成大写,或者首字母大小,如果原先已经存在了相同的文件名,它依然也是不会覆盖的。
(1) 添加配置,告诉git区分大小写

1
2
3
4
## 不起作用
git config core.ignorecase false
## 同样不行
git config --global core.ignorecase false

同时出现了:fatal: bad numeric config value ‘fase’ for ‘core.ignorecase’: invalid unit

原因是我把:git config –global core.ignorecase false 写成了:git config –global core.ignorecase fase 结果还是不起作用。

(2) 尝试使用windows10的更新,区分文件大小写
使用: fsutil.exe file SetCaseSensitiveInfo . enable 命令,结果出现错误,不支持该请求

分别尝试了用 点,用相对路径,用决定路径,都不行。

最后我在控制面板中->程序->打开或关闭window程序中,打开了:适用于于Linux的Windows子系统 功能。

然后重启电脑,更新,再次进入到相关目录,运行: fsutil.exe file SetCaseSensitiveInfo . enable 结果还是真是好了。

开启了这个功能,还意外的在vscode中提示我安装了一个叫Remote-WSL的工具

接着执行:hexo clean -> hexo g -> hexo d,结果还是不行啊。

(3) 使用克隆然后重写github主页仓库
添加了windows的区分大小写之后,我有不想删除远程的github pages主页,所以我使用 git clone 克隆了远程仓库也就是github pages主页仓库到一个临时的文件夹,然后将有大小写文件的文件夹删掉,使用 git add . 和 git commmit -m “改名” 进行了git push 一次提交。然后我从原先的地方,将区分了大小写的文件夹拷贝到临时文件夹的原先的位置,再次进行 git add . 和 git commit -m “” 以及 git push 提交,可以看到我在克隆的仓库中进行了提交,是改变了github上的大小写问题。

奇怪的地方又出现了,虽然我在克隆的仓库中重新提交之后,解决了大小写的问题,但是我使用hexo d部署时,还是出现了大小写不区分的问题。

这里的GIS本来应该是Gis的形式进行提交的。

(4) 最后删除了.deploy文件夹
最后删除了.deploy文件夹,然后重新执行hexo d进行部署,结果成功了。
或者是进入.deploy文件夹,执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## 将ignorecase=true 改为 ignorecase=false
cd .deploy_git
vim .git/config

## 删除博客项目中 .deploy_git 文件夹下的所有文件,并 push 到 Github 上,
git rm -rf *
git commit -m 'clean all file'
git push

## 使用 Hexo 再次生成及部署
cd ..
hexo clean
hexo deploy -generate

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。