1 修改主题配色
有自定义的配色还是不错的选择的,所以,我们可以自定义配色。
一般在
/themes/hexo-theme-matery/source/css/matery.css
中,搜索
.bg-color
来修改背景颜色,修改标题栏、菜单栏、各种标签背景的颜色,使主题颜色为Material的黑色。感谢Material Design Colours提供的配色方案。
其他的也可以在这个css文件中修改,自己琢磨一下。
2 为你的Hexo加上评论系统-Valine
给个链接:https://blog.csdn.net/blue_zy/article/details/79071414
注意:Valine用在matery主题上有个bug就是第一条评论位置会错位
如下图:
解决办法:
F12开发者模式,控制台定位bug位置,修改参数,调整对应主题源文件参数,得以解决,如下图示:
修改图示
3 SEO 优化
给个链接:https://blog.csdn.net/sunshine940326/article/details/70936988/
4 优化网站加载速度
4.1 优化图片加载
issue问题:
优化网站加载逻辑问题:图片最后加载,加入图片懒加载方法
hexo-lazyload-image的作用原理是讲你博客里面img标签的src属性替换为一个loading image,把真实的图片地址放在data-origin属性下面。然后当你的网页翻到那张图片时(也就是图片在窗口中完全可见时),他会有一段js用data-origin的内容替换src,打到懒加载的目的。
一般情况下懒加载和gallery插件会发生冲突,比如按照我上面所说,最终结果就会变成,可能只有第一张图片在gallery中打开是原图,右翻左翻都会是那张loading image,需要你掌握js,可以修改matery.js里面的内容,甚至可能换一个gallery,比如photosiwpe之类的
解决方法:修改/themes/matery/source/js中的matery.js文件
第103行:
$('#articleContent, #myGallery').lightGallery({
selector: '.img-item',
// 启用字幕
subHtmlSelectorRelative: true,
showThumbByDefault: false //这句加上
});
后面加上:
$(document).find('img[data-original]').each(function(){
$(this).parent().attr("href", $(this).attr("data-original"));
});
再装个插件,https://github.com/Troy-Yang/hexo-lazyload-image
在博客根目录配置.yml文件加入对应字段,如下:
# lazyload configuration 2019.08.23
lazyload:
enable: true
onlypost: false
loadingImg: # eg ./images/loading.gif
好了,这样实现了博客网站的图片懒加载。
4.2 Gulp实现代码压缩
Gulp实现代码压缩,以提升网页加载速度。
1 首先我们需要安装Gulp插件和5个功能模块,依次运行下面的两条命令。
npm install gulp -g #安装gulp
# 安装功能模块
npm install gulp-htmlclean gulp-htmlmin gulp-minify-css gulp-uglify gulp-imagemin --save
# 额外的功能模块
npm install gulp-debug gulp-clean-css gulp-changed gulp-if gulp-plumber gulp-babel babel-preset-es2015 del --save
2 接下来在博客的根目录下新建gulpfile.js文件,并复制下面的内容到文件中。
var gulp = require("gulp");
var debug = require("gulp-debug");
var cleancss = require("gulp-clean-css"); //css压缩组件
var uglify = require("gulp-uglify"); //js压缩组件
var htmlmin = require("gulp-htmlmin"); //html压缩组件
var htmlclean = require("gulp-htmlclean"); //html清理组件
var imagemin = require("gulp-imagemin"); //图片压缩组件
var changed = require("gulp-changed"); //文件更改校验组件
var gulpif = require("gulp-if"); //任务 帮助调用组件
var plumber = require("gulp-plumber"); //容错组件(发生错误不跳出任务,并报出错误内容)
var isScriptAll = true; //是否处理所有文件,(true|处理所有文件)(false|只处理有更改的文件)
var isDebug = true; //是否调试显示 编译通过的文件
var gulpBabel = require("gulp-babel");
var es2015Preset = require("babel-preset-es2015");
var del = require("del");
var Hexo = require("hexo");
var hexo = new Hexo(process.cwd(), {}); // 初始化一个hexo对象
// 清除public文件夹
gulp.task("clean", function() {
return del(["public/**/*"]);
});
// 下面几个跟hexo有关的操作,主要通过hexo.call()去执行,注意return
// 创建静态页面 (等同 hexo generate)
gulp.task("generate", function() {
return hexo.init().then(function() {
return hexo
.call("generate", {
watch: false
})
.then(function() {
return hexo.exit();
})
.catch(function(err) {
return hexo.exit(err);
});
});
});
// 启动Hexo服务器
gulp.task("server", function() {
return hexo
.init()
.then(function() {
return hexo.call("server", {});
})
.catch(function(err) {
console.log(err);
});
});
// 部署到服务器
gulp.task("deploy", function() {
return hexo.init().then(function() {
return hexo
.call("deploy", {
watch: false
})
.then(function() {
return hexo.exit();
})
.catch(function(err) {
return hexo.exit(err);
});
});
});
// 压缩public目录下的js文件
gulp.task("compressJs", function() {
return gulp
.src(["./public/**/*.js", "!./public/libs/**"]) //排除的js
.pipe(gulpif(!isScriptAll, changed("./public")))
.pipe(gulpif(isDebug, debug({ title: "Compress JS:" })))
.pipe(plumber())
.pipe(
gulpBabel({
presets: [es2015Preset] // es5检查机制
})
)
.pipe(uglify()) //调用压缩组件方法uglify(),对合并的文件进行压缩
.pipe(gulp.dest("./public")); //输出到目标目录
});
// 压缩public目录下的css文件
gulp.task("compressCss", function() {
var option = {
rebase: false,
//advanced: true, //类型:Boolean 默认:true [是否开启高级优化(合并选择器等)]
compatibility: "ie7" //保留ie7及以下兼容写法 类型:String 默认:''or'*' [启用兼容模式; 'ie7':IE7兼容模式,'ie8':IE8兼容模式,'*':IE9+兼容模式]
//keepBreaks: true, //类型:Boolean 默认:false [是否保留换行]
//keepSpecialComments: '*' //保留所有特殊前缀 当你用autoprefixer生成的浏览器前缀,如果不加这个参数,有可能将会删除你的部分前缀
};
return gulp
.src(["./public/**/*.css", "!./public/**/*.min.css"]) //排除的css
.pipe(gulpif(!isScriptAll, changed("./public")))
.pipe(gulpif(isDebug, debug({ title: "Compress CSS:" })))
.pipe(plumber())
.pipe(cleancss(option))
.pipe(gulp.dest("./public"));
});
// 压缩public目录下的html文件
gulp.task("compressHtml", function() {
var cleanOptions = {
protect: /<\!--%fooTemplate\b.*?%-->/g, //忽略处理
unprotect: /<script [^>]*\btype="text\/x-handlebars-template"[\s\S]+?<\/script>/gi //特殊处理
};
var minOption = {
collapseWhitespace: true, //压缩HTML
collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input />
removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
removeComments: true, //清除HTML注释
minifyJS: true, //压缩页面JS
minifyCSS: true, //压缩页面CSS
minifyURLs: true //替换页面URL
};
return gulp
.src("./public/**/*.html")
.pipe(gulpif(isDebug, debug({ title: "Compress HTML:" })))
.pipe(plumber())
.pipe(htmlclean(cleanOptions))
.pipe(htmlmin(minOption))
.pipe(gulp.dest("./public"));
});
// 压缩 public/uploads 目录内图片
gulp.task("compressImage", function() {
var option = {
optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级)
progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
interlaced: false, //类型:Boolean 默认:false 隔行扫描gif进行渲染
multipass: false //类型:Boolean 默认:false 多次优化svg直到完全优化
};
return gulp
.src("./public/medias/**/*.*")
.pipe(gulpif(!isScriptAll, changed("./public/medias")))
.pipe(gulpif(isDebug, debug({ title: "Compress Images:" })))
.pipe(plumber())
.pipe(imagemin(option))
.pipe(gulp.dest("./public"));
});
// 执行顺序: 清除public目录 -> 产生原始博客内容 -> 执行压缩混淆 -> 部署到服务器
gulp.task(
"build",
gulp.series(
"clean",
"generate",
"compressHtml",
"compressCss",
"compressJs",
"compressImage",
gulp.parallel("deploy")
)
);
// 默认任务
gulp.task(
"default",
gulp.series(
"clean",
"generate",
gulp.parallel("compressHtml", "compressCss", "compressImage", "compressJs")
)
);
//Gulp4最大的一个改变就是gulp.task函数现在只支持两个参数,分别是任务名和运行任务的函数
3 最后
hexo clean && hexo g && gulp && hexo d
就可以了。
注意,很可能你会运行到第三步,也就是运行gulp压缩命令时会报错。
那是因为gulp安装的本地版本和hexo自带的版本不对应导致,第三步gulp压缩可以用下面命令强制使用本地版本:
node ./node_modules/gulp/bin/gulp.js
4.3 Github & Coding Pages 双部署
Github & Coding Pages 双部署,对国内,国外用户进行分流访问,以提升网站的访问速度。
Github Pages 的部署前面已经说了,这里就讲一讲 Coding Pages 如何部署.其实与 Github Pages 也类似,先到coding官网注册,创建一个与用户名同名的仓库,添加仓库地址到配置文件中,在根目录_config.yml对应地方添加如下:
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
- type: git # 设置发布类型,如git
repo:
github: git@github.com:OUYANGSIHAI/OUYANGSIHAI.github.io.git # 设置repository对应的链接
coding: git@e.coding.net:ouyangsihai/sihaiblog.git
branch: master # 设置提交到的分支
message: Site updated at {{ now("YYYY-MM-DD HH:mm:ss") }} # 设置我们提交的信息
- type: baidu_url_submitter
把本地生成 SSH 公匙添加到 Coding 这一步看我前面的教程,原理类似.
然后
hexo clean && hexo g && hexo d
部署上去就是了.
当然,部署上去后,你需要开启 page 服务.
你可以在 pages 设置里面自定义域名,区域名解析控制台,添加两条 CNAME 记录,将域名指向
RepoName.coding.me
就可以的,申请 ssl 证书,强制开启https
可能遇到的问题:
- coding pages 申请ssl 证书总是提示:错误!
这里提一句,如果你是github pages 和 coding pages双部署,用同一个域名的话,可以将xxx.github.io 解析成 境外, xxx.coding.me 解析成 默认,这个时候如果你之前就申请过 ssl 证书的话,再在 coding 里面申请 ssl证书会一直提示 失败,解决办法:
先去域名解析控制台,将境外解析的两条 CNAME 记录 暂停,过个五六分钟,回到 coding 点击申请 ssl,很快就会提示,申请成功!
刚好我过程中遇到了这个问题,所以把它记下来,方便后面的小伙伴看到.
5 代码高亮
由于 Hexo 自带的代码高亮主题显示不好看,所以主题中使用到了 hexo-prism-plugin 的 Hexo 插件来做代码高亮,安装命令如下:
npm i -S hexo-prism-plugin
然后,修改 Hexo 根目录下 _config.yml 文件中 highlight.enable 的值为 false,并新增 prism 插件相关的配置,主要配置如下:
highlight:
enable: false
prism_plugin:
mode: 'preprocess' # realtime/preprocess
theme: 'tomorrow'
line_number: false # default false
custom_css:
做了除此设置之外,还有一个很大的问题,就是写代码块的时候,并不会自动的识别是哪种语言,还需要在代码前面标记是哪种语言,所以,非常的麻烦,未来解决这个问题还问了一个同用这个主题的网友,非常感谢他的热心帮助。
解决方法
在这个路径在找到这个文件
/**
* Code transform for prism plugin.
* @param {Object} data
* @return {Object}
*/
function PrismPlugin(data) {
// Patch for caption support
if (captionRegex.test(data.content)) {
// Attempt to parse the code
data.content = data.content.replace(captionRegex, (origin, lang, caption, code) => {
if (!lang || !caption || !code) return origin;
return `<figcaption>${caption}</figcaption><pre><code class="${lang}">${code}</code></pre>`;
})
}
//=============
var myflag=true
//===================
data.content = data.content.replace(regex, (origin, lang, code) => {
const lineNumbers = line_number ? 'line-numbers' : '';
const startTag = `<pre class="${lineNumbers} language-${lang}"><code class="language-${lang}">`;
const endTag = `</code></pre>`;
code = unescape(code);
let parsedCode = '';
if (Prism.languages[lang]) {
parsedCode = Prism.highlight(code, Prism.languages[lang]);
} else {
parsedCode = code;
}
if (line_number) {
const match = parsedCode.match(/\n(?!$)/g);
const linesNum = match ? match.length + 1 : 1;
let lines = new Array(linesNum + 1);
lines = lines.join('<span></span>');
const startLine = '<span aria-hidden="true" class="line-numbers-rows">';
const endLine = '</span>';
parsedCode += startLine + lines + endLine;
}
myflag=false
return startTag + parsedCode + endTag;
});
//================================================================================================
if(myflag){
data.content=data.content.replace(/<code>/igm,'<code class="c">\n') //c 改成 java 即可
data.content = data.content.replace(regex, (origin, lang, code) => {
const lineNumbers = line_number ? 'line-numbers' : '';
const startTag = `<pre class="${lineNumbers} language-${lang}"><code class="language-${lang}">`;
const endTag = `</code></pre>`;
code = unescape(code);
let parsedCode = '';
if (Prism.languages[lang]) {
parsedCode = Prism.highlight(code, Prism.languages[lang]);
} else {
parsedCode = code;
}
if (line_number) {
const match = parsedCode.match(/\n(?!$)/g);
const linesNum = match ? match.length + 1 : 1;
let lines = new Array(linesNum + 1);
lines = lines.join('<span></span>');
const startLine = '<span aria-hidden="true" class="line-numbers-rows">';
const endLine = '</span>';
parsedCode += startLine + lines + endLine;
}
return startTag + parsedCode + endTag;
});
}
//================================================================================================
return data;
}
/**
* Copy asset to hexo public folder.
*/
function copyAssets() {
const assets = [{
path: `css/${prismThemeFileName}`,
data: () => fs.createReadStream(prismThemeFilePath)
}];
// If line_number is enabled in plugin config add the corresponding stylesheet
if (line_number) {
assets.push({
path: 'css/prism-line-numbers.css',
data: () => fs.createReadStream(path.join(prismLineNumbersPluginDir, 'prism-line-numbers.css'))
});
}
// If prism plugin config mode is realtime include prism.js and line-numbers.js
if (mode === 'realtime') {
assets.push({
path: 'js/prism.js',
data: () => fs.createReadStream(prismMainFile)
});
if (line_number) {
assets.push({
path: 'js/prism-line-numbers.min.js',
data: () => fs.createReadStream(path.join(prismLineNumbersPluginDir, 'prism-line-numbers.min.js'))
});
}
}
return assets;
}
/**
* Injects code to html for importing assets.
* @param {String} code
* @param {Object} data
*/
如果你不是Java,想改成其他语言,修改上面代码的这部分即可。
给代码块开启行号
我们在配置文件.yml中找到prism_plugin配置项line_number: false(# default false)改为true,开启行号,但是在我们这个matery主题中中是无效的,有bug需要改一下matery.css样式参数,在第95行位置将:
pre {
padding: 1.5rem !important;
margin: 1rem 0 !important;
background: #272822;
overflow: auto;
border-radius: 0.35rem;
tab-size: 4;
}
改为:
pre {
padding: 1.5rem 1.5rem 1.5rem 3.3rem !important;
margin: 1rem 0 !important;
background: #272822;
overflow: auto;
border-radius: 0.35rem;
tab-size: 4;
}
注释掉紧接着的code代码块里面的font-size项,如下:
code {
padding: 1px 5px;
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
/*font-size: 0.91rem;*/
color: #e96900;
background-color: #f8f8f8;
border-radius: 2px;
}
好了这下可以显示行号了。
6 修改页面底部
找到这个文件
修改成以下内容
本站由©<a href="https://blog.ouyangsihai.cn" target="_blank"> 欧阳思海 </a>维护.
7 图片压缩
参考文章:https://www.zrahh.com/archives/269.html
8 代码块优化
1. 安装代码块插件
npm i -S hexo-prism-plugin
2. Hexo根目录配置
打开Hexo根目录的配置文件
_config.yml
,修改并添加如下代码
highlight:
enable: false # 关闭原有的高亮代码
# 添加prism_plugin配置项
prism_plugin:
mode: 'preprocess' # realtime/preprocess
theme: 'tomorrow'
line_number: true # default false
custom_css:
3. Matery主题根目录
打开Matery主题的配置文件
themes\matery\_config.yml
,添加如下代码
code:
lang: true # 代码块是否显示名称
copy: true # 代码块是否可复制
shrink: true # 代码块是否可以收缩
break: false # 代码是否折行
4. 代码块CSS优化
打开
themes\source\css\matery.css
,大概在100到200行左右,修改代码块CSS样式如下
pre {
padding: 1.5rem 1.5rem 1.5rem 3.3rem !important;
margin: 1rem 0 !important;
background: #272822;
overflow: auto;
border-radius: 0.35rem;
tab-size: 4;
}
.code-area::after {
content: " ";
position: absolute;
border-radius: 50%;
background: #ff5f56;
width: 12px;
height: 12px;
top: 0;
left: 12px;
margin-top: 12px;
-webkit-box-shadow: 20px 0 #ffbd2e, 40px 0 #27c93f;
box-shadow: 20px 0 #ffbd2e, 40px 0 #27c93f;
}
code {
padding: 1px 5px;
top: 13px !important;
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
font-size: 0.91rem;
color: #e96900;
background-color: #f8f8f8;
border-radius: 2px;
}
.code_copy {
position: absolute;
top: 0.7rem;
right: 25px;
z-index: 1;
filter: invert(50%);
cursor: pointer;
}
.codecopy_notice {
position: absolute;
top: 0.7rem;
right: 6px;
z-index: 1;
filter: invert(50%);
opacity: 0;
}
.code_lang {
position: absolute;
top: 1.2rem;
right: 46px;
line-height: 0;
font-weight: bold;
font-family: normal;
z-index: 1;
filter: invert(50%);
cursor: pointer;
}
.code-expand {
position: absolute;
top: 4px;
right: 0px;
filter: invert(50%);
padding: 7px;
z-index: 999 !important;
cursor: pointer;
transition: all .3s;
transform: rotate(0deg);
}
.code-closed .code-expand {
transform: rotate(-180deg) !important;
transition: all .3s;
}
.code-closed pre::before {
height: 0px;
}
pre code {
padding: 0;
color: #e8eaf6;
background-color: #272822;
}
pre[class*="language-"] {
padding: 1.2em;
margin: .5em 0;
}
code[class*="language-"],
pre[class*="language-"] {
color: #e8eaf6;
white-space: pre-wrap !important;
}
.line-numbers-rows {
border-right-width: 0px !important;
}
.line-numbers {
padding: 1.5rem 1.5rem 1.5rem 3.2rem !important;
margin: 1rem 0 !important;
background: #272822;
overflow: auto;
border-radius: 0.35rem;
tab-size: 4;
}
5. 文章代码块添加
打开
themes\matery\layout\_partial\post-detail.ejs
,添加如下代码
<!-- 代码块功能依赖 -->
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeBlockFunction.js') %>"></script>
<!-- 代码语言 -->
<% if (theme.code.lang) { %>
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeLang.js') %>"></script>
<% } %>
<!-- 代码块复制 -->
<% if (theme.code.copy) { %>
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeCopy.js') %>"></script>
<% } %>
<!-- 代码块收缩 -->
<% if (theme.code.shrink) { %>
<script type="text/javascript" src="<%- url_for('/libs/codeBlock/codeShrink.js') %>"></script>
<% } %>
<!-- 代码块折行 -->
<% if (!theme.code.break) { %>
<style type="text/css"> code[class*="language-"], pre[class*="language-"] { white-space: pre !important; } </style>
<% } %>
6. 代码块JS添加
打开目录
themes\matery\source\libs
,新建一个名字为
codeBlock
的目录,然后打开该目录。
在
themes\matery\source\libs\codeBlock
目录下新建
codeBlockFunction.js
文件,并添加如下代码
// 代码块功能依赖
$(function () {
$('pre').wrap('<div class="code-area" style="position: relative"></div>');
});
在
themes\matery\source\libs\codeBlock
目录下新建
codeCopy.js
文件,并添加如下代码
// 代码块一键复制
$(function () {
var $copyIcon = $('<i class="fa fa-files-o code_copy" title="复制代码" aria-hidden="true"></i>')
var $notice = $('<div class="codecopy_notice"></div>')
$('.code-area').prepend($copyIcon)
$('.code-area').prepend($notice)
// “复制成功”字出现
function copy(text, ctx) {
if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
try {
document.execCommand('copy') // Security exception may be thrown by some browsers.
$(ctx).prev('.codecopy_notice')
.text("复制成功")
.animate({
opacity: 1,
top: 30
}, 450, function () {
setTimeout(function () {
$(ctx).prev('.codecopy_notice').animate({
opacity: 0,
top: 0
}, 650)
}, 400)
})
} catch (ex) {
$(ctx).prev('.codecopy_notice')
.text("复制失败")
.animate({
opacity: 1,
top: 30
}, 650, function () {
setTimeout(function () {
$(ctx).prev('.codecopy_notice').animate({
opacity: 0,
top: 0
}, 650)
}, 400)
})
return false
}
} else {
$(ctx).prev('.codecopy_notice').text("浏览器不支持复制")
}
}
// 复制
$('.code-area .fa-files-o').on('click', function () {
var selection = window.getSelection()
var range = document.createRange()
range.selectNodeContents($(this).siblings('pre').find('code')[0])
selection.removeAllRanges()
selection.addRange(range)
var text = selection.toString()
copy(text, this)
selection.removeAllRanges()
})
});
在
themes\matery\source\libs\codeBlock
目录下新建
codeLang.js
文件,并添加如下代码
// 代码块语言识别
$(function () {
var $highlight_lang = $('<div class="code_lang" title="代码语言"></div>');
$('pre').before($highlight_lang);
$('pre').each(function () {
var code_language = $(this).attr('class');
if (!code_language) {
return true;
};
var lang_name = code_language.replace("line-numbers", "").trim().replace("language-", "").trim();
// 首字母大写
// lang_name = lang_name.slice(0, 1).toUpperCase() + lang_name.slice(1);
$(this).siblings(".code_lang").text(lang_name);
});
});
在
themes\matery\source\libs\codeBlock
目录下新建
codeShrink.js
文件,并添加如下代码
// 代码块收缩
$(function () {
var $code_expand = $('<i class="fa fa-angle-down code-expand" aria-hidden="true"></i>');
$('.code-area').prepend($code_expand);
$('.code-expand').on('click', function () {
if ($(this).parent().hasClass('code-closed')) {
$(this).siblings('pre').find('code').show();
$(this).parent().removeClass('code-closed');
} else {
$(this).siblings('pre').find('code').hide();
$(this).parent().addClass('code-closed');
}
});
});
7. 解决代码块复制内容不换行问题
Matery主题在开启复制版权且添加了版权信息后,会导致复制的所有内容换行失效,以下将解决这个问题。
在
themes\matery\layout\_partial\post-detail.ejs
文件中,大约在222行左右找到
selection.getRangeAt(0).commonAncestorContainer.nodeName
,将原先
if
条件中的的
PRE
修改为
CODE
即可。
if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'CODE') {
newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>";
}
至此,代码块的优化已经全部完成。
来源: Luckysec
文章作者: Luckysec
文章链接: http://luckyzmj.cn/posts/1b9a9e28.html
本文章著作权归作者所有,任何形式的转载都请注明出处。
9 一键推送到各个搜索引擎
https://cjh0613.com/20200603HexoSubmitUrlsToSearchEngine.html