长文 - 持续更新 | Gridea Pure主题魔改小记
从入门到车门焊死(确信)[更新于2023.02.05]
本文更新于
2023.02.05
,最初写作于2022.12.29
另附:写作本文的目的只是记录,不是教程。本人人菜瘾大,技术十分之有限,写的代码非常之烂,都是本着能用就行写的,所以请大佬手下留情 QwQ
文章目录
要在Gridea中插入自动生成的目录,只需在合适的地方输入
@[toc]
即可,大小写不敏感
起因
APPID
与APPKEY
直接暴露在网页的源码中,这样做会有安全隐患,何况valine目前作者并不打算重新开源,也遗留有一些安全问题,使得我总是不放心评论系统的安全,再加上waline在官方文档中说明:由于 Waline 在存储上完全复用了 Valine 的数据结构,所以从 Valine 迁移至 Waline 非常简单。
templates
下的includes
文件夹,看到valine.ejs
,点进去直接开干!⚠️ 注意:我的魔改方式多为硬编码,好处是修改起来十分方便,思维量小,代价也很明显,相当于是直接放弃了未来升级主题的可能性,这需要你来做出取舍再决定要不要“抄我的作业”。
折腾之路
推荐文档
事实证明,有看文档的习惯,可以避免像我刚开始改造时一样走一大堆弯路。
valine to waline
waline的后端部署请参考官方文档
head.ejs
或post.ejs
中引入需要的文件哦。<style>
div#waline{
width:<%=site.customConfig['vPercentWidth']%>%;
max-width: <%=site.customConfig['vMaxWidth']%>px;
padding: <%=site.customConfig['vPadding']%>
}
:root {
--waline-font-size: 18px;
}
span.katex { font-size: 18px; }
.wl-emoji-popup { font-size: 16px !important; }
.wl-emoji-popup button { height: 2em; }
</style>
<% if(site.customConfig['valine']) { %>
<div id="waline"></div>
<% } %>
<script type="module">
import { init } from 'https://unpkg.com/@waline/client@v2/dist/waline.mjs';
init({
el: '#waline',
serverURL: 'https://waline.ydlk.cc',
avatar: '<%=site.customConfig['avatar']%>',
recordIp: <%=site.customConfig['recordIp']%>,
reaction: true,
pageview: true,
comment: true,
emoji: [
'//unpkg.com/@waline/emojis@1.1.0/bmoji',
'//unpkg.com/@waline/emojis@1.1.0/bilibili',
'//cdn.jsdelivr.net/npm/sticker-heo@2022.7.5/Sticker-100/',
],
reaction: [
'https://unpkg.com/@waline/emojis@1.1.0/bilibili/bb_sunglasses.png',
'https://unpkg.com/@waline/emojis@1.1.0/bilibili/bb_thumbsup.png',
'https://unpkg.com/@waline/emojis@1.1.0/bilibili/bb_doge.png',
'https://unpkg.com/@waline/emojis@1.1.0/bilibili/bb_confused.png',
'https://unpkg.com/@waline/emojis@1.1.0/bilibili/bb_sweat.png',
'https://unpkg.com/@waline/emojis@1.1.0/bilibili/bb_sleepy.png',
],
dark: false,
recaptchaV3Key: "写成你的,我自己开了的",
});
</script>
post.ejs
中的head
部分。waline的js引入也可以更换为
https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/waline/1.5.4/Waline.min.js
,字节跳动的cdn源,大陆友好
<script>
var versionNo = '1.1.1';
if(!window.localStorage.getItem('update-version') || window.localStorage.getItem('update-version') !=versionNo){
window.localStorage.setItem('update-version',versionNo)
alert('友情提示:我站已强制开启评论验证,请先在评论区点击登录,再进行评论,否则无法使用评论')
}
</script>
引入umami统计
valine.ejs
同目录下的head.ejs
,我注释掉了谷歌统计的的代码,然后直接添加了umami的统计代码,除自己写的页面外,其余直接全局生效,这一步没有什么技术含量。为什么我特别指出要注释掉原来的代码呢?这是为了避免日后出现稀奇古怪的问题时,自己还能人工回滚到原来的版本,虽然我的gridea工作目录也在使用git进行多版本管理,但是谁又能知道“明天与意外哪个先来”呢,对吧?
自定义字体
assets
文件夹中styles
文件夹下的main.less
实现。本站就是修改为了谷歌的Noto Serif SC
(使用loli.net提供的大陆可访问源)。👨💻 注意:Pure主题其实提供了自定义CSS的入口,再次强调,我的这种方案==没有考虑==未来升级时兼容性,纯纯的硬编码,需要你做出取舍再决定要不要“抄作业”
main.less
文件的开头,我引入了字体的css内容:@import url('https://fonts.loli.net/css2?family=Noto+Serif+SC:wght@300;400;500;600;700&display=swap');
font-family
了吗?在最开头加上Noto Serif SC
就生效了。这时这几行会变成这样:body {
font-family: "Noto Serif SC", "PingFang SC", -apple-system, BlinkMacSystemFont, opensans, Optima, 'Microsoft Yahei', sans-serif;
font-size: 16px;
letter-spacing: 0px;
}
crtl+F
搜索全文,将与展示效果有关的letter-spacing
项后的数值调整为0px
,此时的效果就与我的网站相近了下面是一种据说可以提高加载速度的代码,加在
<head>
与</head>
之间,实测似乎有效(?
<!-- 引入 Noto Serif SC -->
<link type="text/css" rel="preload stylesheet" as="style" href="https://fonts.loli.net/css2?family=Noto+Serif+SC:wght@300;400;500;600;700&display=swap" crossorigin >
<!-- Google font预加载&缓存 -->
<link rel="dns-prefetch" href="https://fonts.loli.net/">
<link rel="dns-prefetch" href="https://gstatic.loli.net/">
<link rel="preconnect" href="https://gstatic.loli.net" crossorigin />
<noscript>
<link rel="stylesheet" href="https://fonts.loli.net/css2?family=Noto+Serif+SC:wght@300;400;500;600;700&display=swap" onload="this.media='all'" />
</noscript>
Noto Serif
家族了,其实也就是思源黑体😂XV272U
显示器,27寸2K144Hz)。main.less
上动刀就可以了,此部分按照你的喜好来,==但是==我尝试将正文字体大小修改为了18px
,并没有生效,还在研究中…assets - styles - components
这个路径一路点进去,根据你要修改的部分,选择对应的.less
文件下刀就可以了,对于字体大小而言,你要关注的是font-size
属性。其他两个文件夹下的文件同理,按需修改即可,不过目前似乎对正文文本大小的修改仍是无解状态…waline
评论系统而言,引入支持的css变量即可::root {
--waline-font-size: 18px;
}
span.katex { font-size: 18px; }
.wl-emoji-popup { font-size: 16px !important; }
.wl-emoji-popup button { height: 2em; }
18px
搭建说说页面
⚠️ 注意:我的这种办法虽然省事,但是很蠢,而且除了css外,其他的==不能==随其他页面一起==动态更新==,请自行斟酌 警告 请==不要==让valine与artitalk在同一个页面上出现!出现==离奇的bug==后果自负!
index.html
为例你可以在GitHub组织
YandaoGroup
的daoblog.top
仓库找到我的站点的静态文件
<!DOCTYPE html>
到</script>
之间的全部,然后针对性的删除了一些不需要的引入,例如waline相关的css/js等,然后复制了页脚相关的内容,因为每个人实际生成出来的站点都不尽相同,还请你意会一下/shuoshuo
这里,实际效果等同于https://www.daoblog.top/shuoshuo
这个url。static
文件夹,在这里面存放的内容都会原封不动的输出到最终站点的根目录下,包括新建的文件夹,所以,我们可以在这里先新建一个名为shuoshuo
的文件夹,再在其内部新建index.html
,开始编辑就好了。小Tip:不要忘记修改页面标题哦~
script
之后、</body>
标签之前的部分,就是我们最主要的内容的部分。safemode
模式下的artitalk.js
作为说说页面的框架,我插入的代码如下:<style>
body {background-color:#F9F9F9;}
div#artitalk_main{
width:100%;
max-width: 1050px;
padding: 2.5%;
margin: auto;
}
</style>
<br />
<div class="post-container">
<div class="post-detail gt-bg-theme-color-first">
<article class="gt-post-content">
<div id="artitalk_main"></div>
<script>
new Artitalk({
serverURL: 'https://artitalk.ydlk.cc',
appId: '114514',
appKey: '1919810',
color1: '#F3F3F3',
color2: '#F3F3F3',
color3: '#6C6C6C',
})
</script>
<!--注意:在此模式下,可以在前端随意仿冒appid与appkey-->
<br />
</article>
</div>
</div>
<br />
换行是为了增加与导航栏的距离,使页面更美观,你可以根据个人想法自由调整,额外添加<style>
以及套了几层div
与article
也是为了更改它的一些样式,使其整体更美观👨💻 注意:这些美化内容你也可以自定义成别的,我的方案不可能是最好的,请你自行斟酌
为主页添加说说跳转引导
再次重申:
芝士这是硬编码,上车之前需谨慎!
index.ejs
,在<%- include('./includes/header') %>
与<%- include('./includes/post-list') %>
添加如下内容:<div class="post-list-container">
<div class="post-inner">
<div class="post gt-bg-theme-color-second" onclick="window.open('/shuoshuo/','_self')">
<div class="post-left">
<a href="/shuoshuo/"><span class="sticky-top-flag gt-bg-accent-color-first">说说</span><span class="post-title gt-c-content-color-first" style="font-weight:bold"> 再见2022,你好2023!</span></a>
</div>
</div>
</div>
</div>
/shuoshuo/
为你说说页面的相对路径(相对于根目录而言,例如本例中就实际指向了根目录下的名为shuoshuo
的文件夹)<div class="post-left">
<a href="https://news.ydlk.cc/"><span class="sticky-top-flag gt-bg-accent-color-first">早报</span><span class="post-title gt-c-content-color-first" style="font-weight:bold"> 每早一分钟,带你读懂世界。</span><embed src="/link.svg" type="image/svg+xml" height="14" /></a>
</div>
现在使用的版本中还加入了链接的小图标,实际是嵌入了一个svg文件,在
</a>
之前,内容如下:
<embed src="/link.svg" type="image/svg+xml" height="14" />
svg来自iconfont,放在站点根目录,在文件中修改了fill
属性为#8B959F
,以适配主题颜色。
>返回目录
搭建友链朋友圈
👨💻 In writing…
防止进入“怪异模式”
<!DOCTYPE html>
真的很重要!如果你和我一样正在使用Pure这款主题的话,那么你可能会在浏览器的lighthouse中发现让你添加这一行代码的提示。<!DOCTYPE html>
<html lang="zh">
<head>
......
</head>
......
about.ejs
archives.ejs
friends.ejs
index.ejs
post.ejs
search.ejs
tag.ejs
以及tags.ejs
…index文章块添加超链接
post-list.ejs
,在templates/includes
目录下,看到<div class="post gt-bg-theme-color-second">
了吗?在其后直接加入onclick="window.open('<%= post.link %>','_self')"
即可实现点击灰色背景(整个方块)也能在当前窗口跳转至文章页面的效果。这行代码的意思是:再点击这个div分区内的任意一处时,不开新窗口,直接跳转到
<%= post.link %>
这个链接。<%= post.link %>
在Gridea生成静态站点时,会自动替换为对应的文章链接。
<div class="post gt-bg-theme-color-second" onclick="window.open('<%= post.link %>','_self')">
.pace {
pointer-events: none;
user-select: none;
z-index: 2;
position: fixed;
margin: auto;
top: 4px;
left: 0;
right: 0;
height: 8px;
border-radius: 8px;
width: 6rem;
background: #eaecf2;
overflow: hidden;
}
.pace-inactive .pace-progress {
opacity: 0;
transition: 0.3s ease-in;
}
.pace.pace-inactive {
opacity: 0;
transition: 0.3s;
top: -8px;
}
.pace .pace-progress {
box-sizing: border-box;
transform: translate3d(0, 0, 0);
position: fixed;
z-index: 2;
display: block;
position: absolute;
top: 0;
right: 100%;
height: 100%;
width: 100%;
background: #49b1f5;
background: linear-gradient( //自定义药丸颜色
to right,
#bbbbbb,
#2a3a4a,
);
animation: gradient 2s ease infinite;
background-size: 200%;
}
自定义药丸颜色
的注释了吗?这里后面就可以自定义进度条的颜色了,本例中为从左至右的渐变(靠前项目的为左),可参考linear-gradient
的属性进行设置。head.ejs
中引入下面这段js:<script src="//cdn.bootcss.com/pace/1.0.2/pace.min.js"></script>
<div id="goTopBtn"><span class="glyphicon glyphicon-chevron-up">Δ</span></div>
- 在CSS样式中添加以下的CSS代码,用于控制“返回顶部”按钮的样式。
#goTopBtn {
position: fixed;
line-height: 46px;
text-align: center;
width: 46px;
bottom: 35px;
height: 46px;
cursor: pointer;
background: #fff;
display: none;
border-radius: 6px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.13);
font-size: 22px;
color: #999;
}
- 在网页的底部放上以下的jquery代码,用于控制“返回顶部”按钮什么时候显示,什么时候隐藏。
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
/*返回顶部*/
$(window).scroll(function(){
var sc=$(window).scrollTop();
var rwidth=$(window).width()
if(sc>0){
$("#goTopBtn").css("display","block");
$("#goTopBtn").css("left",(rwidth-36)+"px")
}else{
$("#goTopBtn").css("display","none");
}
})
$("#goTopBtn").click(function(){
var sc=$(window).scrollTop();
$('body,html').animate({scrollTop:0},500);
})
</script>
注:根据原作者的协议,我没办法在上面的文字中补充,只能在这里来提示你一下,css改在
main.less
里面,具体是在最后的一大堆@import
之前,要添加的div
我放在了<div class="site-footer gt-c-content-color-first">
的最后一行,第三步中的jquery
代码放在了</footer>
之前。 记得在<head>
中引入jquery哦!引入如:<script src="https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script>
还是那句话,我的方法仅供参考哦~
为控制台添加字符画
F12
,如果有的话,那么你会发现其实B站在控制台页面打印了一副如下图的字符画:
js
的文件夹,然后在其内部新建了一个名为console-text.js
的文件。if (window.console) {
Function.prototype.makeMulti = function () {
let l = new String(this);
l = l.substring(l.indexOf("/*") + 3, l.lastIndexOf("*/"));
return l;
};
let string = function () {
/*
我是字符画
*/
};
console.log(string.makeMulti());
}
我是字符画
部分替换为你要使用的字符画即可。 */ }
console.log(string.makeMulti());
+ console.log("<Custom>");
console.log("欢迎访问%cYandao's Blog", "color:#1fc7b6;font-weight:bold");
head.ejs
中引入js即可:<script defer type="text/javascript" src="https://www.daoblog.top/js/console-text.js"></script>
<script src="https://cdn.jsdelivr.net/npm/pangu.simple@1.0.5/dist/browser/pangu.js"></script>
pangu.simple.js
,非原版pangu.js
,其优化了大陆用户的排版需求,原版的引入如下:<script src="https://cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.min.js"></script>
你可以将
cdnjs.cloudflare.com
替换为cdnjs.loli.net
来确保中国大陆用户的体验。
footer.ejs
的末尾调用它即可<script>
pangu.spacingPage(); /*全局应用pangu.js*/
</script>
F12
查看你博客对应的元素,下面是一种仅修改post-content
(博客正文)与p
标签的调用方法<script>
pangu.spacingElementByClassName('post-content');
pangu.spacingElementByTagName('p');
/*参考这两句,你可以写出适合你实际情况的语法*/
</script>
<span id="runtime_span"></span>
script
:<script>
function show_runtime() {window.setTimeout("show_runtime()",1000); X=new Date("11/12/2021 11:45:14"); Y=new Date(); T=(Y.getTime()-X.getTime()); M=24*60*60*1000; a=T/M;A=Math.floor(a); b=(a-A)*24;B=Math.floor(b); c=(b-B)*60;C=Math.floor((b-B)*60); D=Math.floor((c-C)*60); runtime_span.innerHTML="本站已运行: "+A+"天"+B+"小时"+C+"分"+D+"秒"}show_runtime(); Date("11/12/2021 11:45:14")
</script>
var CURSOR;
Math.lerp = (a, b, n) => (1 - n) * a + n * b;
const getStyle = (el, attr) => {
try {
return window.getComputedStyle
? window.getComputedStyle(el)[attr]
: el.currentStyle[attr];
} catch (e) {}
return "";
};
class Cursor {
constructor() {
this.pos = {curr: null, prev: null};
this.pt = [];
this.create();
this.init();
this.render();
}
move(left, top) {
this.cursor.style["left"] = `${left}px`;
this.cursor.style["top"] = `${top}px`;
}
create() {
if (!this.cursor) {
this.cursor = document.createElement("div");
this.cursor.id = "cursor";
this.cursor.classList.add("hidden");
document.body.append(this.cursor);
}
var el = document.getElementsByTagName('*');
for (let i = 0; i < el.length; i++)
if (getStyle(el[i], "cursor") == "pointer")
this.pt.push(el[i].outerHTML);
document.body.appendChild((this.scr = document.createElement("style")));
this.scr.innerHTML = `* {cursor: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' width='8px' height='8px'><circle cx='4' cy='4' r='4' opacity='.5'/></svg>") 4 4, auto}`;
}
refresh() {
this.scr.remove();
this.cursor.classList.remove("hover");
this.cursor.classList.remove("active");
this.pos = {curr: null, prev: null};
this.pt = [];
this.create();
this.init();
this.render();
}
init() {
document.onmouseover = e => this.pt.includes(e.target.outerHTML) && this.cursor.classList.add("hover");
document.onmouseout = e => this.pt.includes(e.target.outerHTML) && this.cursor.classList.remove("hover");
document.onmousemove = e => {(this.pos.curr == null) && this.move(e.clientX - 8, e.clientY - 8); this.pos.curr = {x: e.clientX - 8, y: e.clientY - 8}; this.cursor.classList.remove("hidden");};
document.onmouseenter = e => this.cursor.classList.remove("hidden");
document.onmouseleave = e => this.cursor.classList.add("hidden");
document.onmousedown = e => this.cursor.classList.add("active");
document.onmouseup = e => this.cursor.classList.remove("active");
}
render() {
if (this.pos.prev) {
this.pos.prev.x = Math.lerp(this.pos.prev.x, this.pos.curr.x, 0.15);
this.pos.prev.y = Math.lerp(this.pos.prev.y, this.pos.curr.y, 0.15);
this.move(this.pos.prev.x, this.pos.prev.y);
} else {
this.pos.prev = this.pos.curr;
}
requestAnimationFrame(() => this.render());
}
}
(() => {
CURSOR = new Cursor();
// 需要重新获取列表时,使用 CURSOR.refresh()
})();
main.less
中最后的一大堆@import
前插入以下内容:#cursor {
position: fixed;
width: 16px;
height: 16px;
background: #000;
border-radius: 8px;
opacity: 0.25;
z-index: 10086;
pointer-events: none;
transition: 0.2s ease-in-out;
transition-property: background, opacity, transform;
}
#cursor.hidden {
opacity: 0;
}
#cursor.hover {
opacity: 0.1;
transform: scale(2.5);
}
#cursor.active {
opacity: 0.5;
transform: scale(0.5);
}
head.ejs
中插入以下内容:<script defer type="text/javascript" src="/js/mouse.js"></script>
<link rel="stylesheet" href="https://cdnjs.loli.net/ajax/libs/izitoast/1.4.0/css/iziToast.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/izitoast/1.4.0/js/iziToast.min.js" integrity="sha512-Zq9o+E00xhhR/7vJ49mxFNJ0KQw1E1TMWkPTxrWcnpfEFDEXgUiwJHIKit93EW/XxE31HSI5GEOW06G6BF1AtA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
footer.ejs
的末尾添加如下代码即可:<script>
document.body.oncopy = function (){
iziToast.info({
timeout: 2000, //注:弹窗持续时间,单位为毫秒
icon: 'Fontawesome',
closeOnEscape: 'true',
transitionIn: 'bounceInLeft',
transitionOut: 'fadeOutRight',
displayMode: 'replace',
layout: '2',
position: 'topRight',
icon: 'fad fa-copy',
backgroundColor: '#fff',
title: '复制成功',
message: '未经许可,请勿转载
});
}
</script>
<script src="//instant.page/5.1.1" type="module" integrity="sha384-MWfCL6g1OTGsbSwfuMHc8+8J2u71/LA8dzlIN3ycajckxuZZmF+DNjdm7O6H3PSq"></script>
What’s next?
其实还有很多功能想做…
若无特殊说明,请勿转载我站原创文章。
作者: Yandao 发表日期:2022 年 12 月 29 日
理性发言,和谐讨论